implemented periodic IF-MAP RenewSession request
[strongswan.git] / src / libcharon / plugins / tnc_ifmap / tnc_ifmap_soap.c
1 /*
2 * Copyright (C) 2011-2013 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_soap.h"
17 #include "tnc_ifmap_soap_msg.h"
18
19 #include <utils/debug.h>
20 #include <credentials/sets/mem_cred.h>
21 #include <daemon.h>
22
23 #include <tls_socket.h>
24
25 #include <errno.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29
30 #define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
31 #define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2"
32 #define IFMAP_URI "https://localhost:8444/imap"
33 #define IFMAP_NO_FD -1
34
35 typedef struct private_tnc_ifmap_soap_t private_tnc_ifmap_soap_t;
36
37 /**
38 * Private data of an tnc_ifmap_soap_t object.
39 */
40 struct private_tnc_ifmap_soap_t {
41
42 /**
43 * Public tnc_ifmap_soap_t interface.
44 */
45 tnc_ifmap_soap_t public;
46
47 /**
48 * SOAP Session ID
49 */
50 xmlChar *session_id;
51
52 /**
53 * IF-MAP Publisher ID
54 */
55 xmlChar *ifmap_publisher_id;
56
57 /**
58 * IF-MAP namespace
59 */
60 xmlNsPtr ns;
61
62 /**
63 * IF-MAP metadata namespace
64 */
65 xmlNsPtr ns_meta;
66
67 /**
68 * PEP and PDP device name
69 */
70 char *device_name;
71
72 /**
73 * HTTPS Server URI with https:// prefix removed
74 */
75 char *uri;
76
77 /**
78 * Optional base64-encoded username:password for HTTP Basic Authentication
79 */
80 chunk_t user_pass;
81
82 /**
83 * IF-MAP Server (IP address and port)
84 */
85 host_t *host;
86
87 /**
88 * TLS socket
89 */
90 tls_socket_t *tls;
91
92 /**
93 * File descriptor for secure TCP socket
94 */
95 int fd;
96
97 /**
98 * In memory credential set
99 */
100 mem_cred_t *creds;
101
102 };
103
104 METHOD(tnc_ifmap_soap_t, newSession, bool,
105 private_tnc_ifmap_soap_t *this)
106 {
107 tnc_ifmap_soap_msg_t *soap_msg;
108 xmlNodePtr request, result;
109
110 /*build newSession request */
111 request = xmlNewNode(NULL, "newSession");
112 this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
113 xmlSetNs(request, this->ns);
114
115 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
116 if (!soap_msg->post(soap_msg, request, "newSessionResult", &result))
117 {
118 soap_msg->destroy(soap_msg);
119 return FALSE;
120 }
121
122 /* get session-id and ifmap-publisher-id properties */
123 this->session_id = xmlGetProp(result, "session-id");
124 this->ifmap_publisher_id = xmlGetProp(result, "ifmap-publisher-id");
125 soap_msg->destroy(soap_msg);
126
127 DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
128 this->session_id, this->ifmap_publisher_id);
129
130 /* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */
131 this->device_name = lib->settings->get_str(lib->settings,
132 "%s.plugins.tnc-ifmap.device_name",
133 this->ifmap_publisher_id, charon->name);
134 this->device_name = strdup(this->device_name);
135
136 return this->session_id && this->ifmap_publisher_id;
137 }
138
139 METHOD(tnc_ifmap_soap_t, renewSession, bool,
140 private_tnc_ifmap_soap_t *this)
141 {
142 tnc_ifmap_soap_msg_t *soap_msg;
143 xmlNodePtr request;
144 bool success;
145
146 /* build renewSession request */
147 request = xmlNewNode(NULL, "renewSession");
148 this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
149 xmlSetNs(request, this->ns);
150 xmlNewProp(request, "session-id", this->session_id);
151
152 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
153 success = soap_msg->post(soap_msg, request, "renewSessionResult", NULL);
154 soap_msg->destroy(soap_msg);
155
156 return success;
157 }
158
159 METHOD(tnc_ifmap_soap_t, purgePublisher, bool,
160 private_tnc_ifmap_soap_t *this)
161 {
162 tnc_ifmap_soap_msg_t *soap_msg;
163 xmlNodePtr request;
164 bool success;
165
166 /* build purgePublisher request */
167 request = xmlNewNode(NULL, "purgePublisher");
168 this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
169 xmlSetNs(request, this->ns);
170 xmlNewProp(request, "session-id", this->session_id);
171 xmlNewProp(request, "ifmap-publisher-id", this->ifmap_publisher_id);
172
173 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
174 success = soap_msg->post(soap_msg, request, "purgePublisherReceived", NULL);
175 soap_msg->destroy(soap_msg);
176
177 return success;
178 }
179
180 /**
181 * Create an access-request based on device_name and ike_sa_id
182 */
183 static xmlNodePtr create_access_request(private_tnc_ifmap_soap_t *this,
184 u_int32_t id)
185 {
186 xmlNodePtr node;
187 char buf[BUF_LEN];
188
189 node = xmlNewNode(NULL, "access-request");
190
191 snprintf(buf, BUF_LEN, "%s:%d", this->device_name, id);
192 xmlNewProp(node, "name", buf);
193
194 return node;
195 }
196
197 /**
198 * Create an identity
199 */
200 static xmlNodePtr create_identity(private_tnc_ifmap_soap_t *this,
201 identification_t *id, bool is_user)
202 {
203 xmlNodePtr node;
204 char buf[BUF_LEN], *id_type;
205
206 node = xmlNewNode(NULL, "identity");
207
208 snprintf(buf, BUF_LEN, "%Y", id);
209 xmlNewProp(node, "name", buf);
210
211 switch (id->get_type(id))
212 {
213 case ID_IPV4_ADDR:
214 id_type = "other";
215 xmlNewProp(node, "other-type-definition", "36906:ipv4-address");
216 break;
217 case ID_FQDN:
218 id_type = is_user ? "username" : "dns-name";
219 break;
220 case ID_RFC822_ADDR:
221 id_type = "email-address";
222 break;
223 case ID_IPV6_ADDR:
224 id_type = "other";
225 xmlNewProp(node, "other-type-definition", "36906:ipv6-address");
226 break;
227 case ID_DER_ASN1_DN:
228 id_type = "distinguished-name";
229 break;
230 case ID_KEY_ID:
231 id_type = "other";
232 xmlNewProp(node, "other-type-definition", "36906:key-id");
233 break;
234 default:
235 id_type = "other";
236 xmlNewProp(node, "other-type-definition", "36906:other");
237 }
238 xmlNewProp(node, "type", id_type);
239
240 return node;
241 }
242
243 /**
244 * Create enforcement-report metadata
245 */
246 static xmlNodePtr create_enforcement_report(private_tnc_ifmap_soap_t *this,
247 xmlChar *action, xmlChar *reason)
248 {
249 xmlNodePtr node, node2, node3;
250
251 node = xmlNewNode(NULL, "metadata");
252 node2 = xmlNewNode(this->ns_meta, "enforcement-report");
253 xmlAddChild(node, node2);
254 xmlNewProp(node2, "ifmap-cardinality", "multiValue");
255
256 node3 = xmlNewNode(NULL, "enforcement-action");
257 xmlAddChild(node2, node3);
258 xmlNodeAddContent(node3, action);
259
260 node3 = xmlNewNode(NULL, "enforcement-reason");
261 xmlAddChild(node2, node3);
262 xmlNodeAddContent(node3, reason);
263
264 return node;
265 }
266
267 /**
268 * Create delete filter
269 */
270 static xmlNodePtr create_delete_filter(private_tnc_ifmap_soap_t *this,
271 char *metadata)
272 {
273 xmlNodePtr node;
274 char buf[BUF_LEN];
275
276 node = xmlNewNode(NULL, "delete");
277
278 snprintf(buf, BUF_LEN, "meta:%s[@ifmap-publisher-id='%s']",
279 metadata, this->ifmap_publisher_id);
280 xmlNewProp(node, "filter", buf);
281
282 return node;
283 }
284
285 /**
286 * Create a publish request
287 */
288 static xmlNodePtr create_publish_request(private_tnc_ifmap_soap_t *this)
289 {
290 xmlNodePtr request;
291
292 request = xmlNewNode(NULL, "publish");
293 this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
294 xmlSetNs(request, this->ns);
295 this->ns_meta = xmlNewNs(request, IFMAP_META_NS, "meta");
296 xmlNewProp(request, "session-id", this->session_id);
297
298 return request;
299 }
300
301 /**
302 * Create a device
303 */
304 static xmlNodePtr create_device(private_tnc_ifmap_soap_t *this)
305 {
306 xmlNodePtr node, node2;
307
308 node = xmlNewNode(NULL, "device");
309 node2 = xmlNewNode(NULL, "name");
310 xmlAddChild(node, node2);
311 xmlNodeAddContent(node2, this->device_name);
312
313 return node;
314 }
315
316 /**
317 * Create an ip-address
318 */
319 static xmlNodePtr create_ip_address(private_tnc_ifmap_soap_t *this,
320 host_t *host)
321 {
322 xmlNodePtr node;
323 char buf[BUF_LEN];
324
325 node = xmlNewNode(NULL, "ip-address");
326
327 if (host->get_family(host) == AF_INET6)
328 {
329 chunk_t address;
330 int len, written, i;
331 char *pos;
332 bool first = TRUE;
333
334 /* output IPv6 address in canonical IF-MAP 2.0 format */
335 address = host->get_address(host);
336 pos = buf;
337 len = sizeof(buf);
338
339 for (i = 0; i < address.len; i = i + 2)
340 {
341 written = snprintf(pos, len, "%s%x", first ? "" : ":",
342 256*address.ptr[i] + address.ptr[i+1]);
343 if (written < 0 || written >= len)
344 {
345 break;
346 }
347 pos += written;
348 len -= written;
349 first = FALSE;
350 }
351 }
352 else
353 {
354 snprintf(buf, BUF_LEN, "%H", host);
355 }
356
357 xmlNewProp(node, "value", buf);
358 xmlNewProp(node, "type", host->get_family(host) == AF_INET ? "IPv4" : "IPv6");
359
360 return node;
361 }
362
363 /**
364 * Create metadata
365 */
366 static xmlNodePtr create_metadata(private_tnc_ifmap_soap_t *this,
367 xmlChar *metadata)
368 {
369 xmlNodePtr node, node2;
370
371 node = xmlNewNode(NULL, "metadata");
372 node2 = xmlNewNode(this->ns_meta, metadata);
373 xmlAddChild(node, node2);
374 xmlNewProp(node2, "ifmap-cardinality", "singleValue");
375
376 return node;
377 }
378
379 /**
380 * Create capability metadata
381 */
382 static xmlNodePtr create_capability(private_tnc_ifmap_soap_t *this,
383 identification_t *name)
384 {
385 xmlNodePtr node, node2;
386 char buf[BUF_LEN];
387
388 node = xmlNewNode(this->ns_meta, "capability");
389 xmlNewProp(node, "ifmap-cardinality", "multiValue");
390
391 node2 = xmlNewNode(NULL, "name");
392 xmlAddChild(node, node2);
393 snprintf(buf, BUF_LEN, "%Y", name);
394 xmlNodeAddContent(node2, buf);
395
396 node2 = xmlNewNode(NULL, "administrative-domain");
397 xmlAddChild(node, node2);
398 xmlNodeAddContent(node2, "strongswan");
399
400 return node;
401 }
402
403 METHOD(tnc_ifmap_soap_t, publish_ike_sa, bool,
404 private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up)
405 {
406 tnc_ifmap_soap_msg_t *soap_msg;
407 xmlNodePtr request, node, node2 = NULL;
408 enumerator_t *e1, *e2;
409 auth_rule_t type;
410 identification_t *id, *eap_id, *group;
411 host_t *host;
412 auth_cfg_t *auth;
413 u_int32_t ike_sa_id;
414 bool is_user = FALSE, first = TRUE, success;
415
416 /* extract relevant data from IKE_SA*/
417 ike_sa_id = ike_sa->get_unique_id(ike_sa);
418 id = ike_sa->get_other_id(ike_sa);
419 eap_id = ike_sa->get_other_eap_id(ike_sa);
420 host = ike_sa->get_other_host(ike_sa);
421
422 /* in the presence of an EAP Identity, treat it as a username */
423 if (!id->equals(id, eap_id))
424 {
425 is_user = TRUE;
426 id = eap_id;
427 }
428
429 /* build publish request */
430 request = create_publish_request(this);
431
432 /* delete any existing enforcement reports */
433 if (up)
434 {
435 node = create_delete_filter(this, "enforcement-report");
436 xmlAddChild(request, node);
437 xmlAddChild(node, create_ip_address(this, host));
438 xmlAddChild(node, create_device(this));
439 }
440
441 /**
442 * update or delete authenticated-as metadata
443 */
444 if (up)
445 {
446 node = xmlNewNode(NULL, "update");
447 }
448 else
449 {
450 node = create_delete_filter(this, "authenticated-as");
451 }
452 xmlAddChild(request, node);
453
454 /* add access-request, identity and [if up] metadata */
455 xmlAddChild(node, create_access_request(this, ike_sa_id));
456 xmlAddChild(node, create_identity(this, id, is_user));
457 if (up)
458 {
459 xmlAddChild(node, create_metadata(this, "authenticated-as"));
460 }
461
462 /**
463 * update or delete access-request-ip metadata
464 */
465 if (up)
466 {
467 node = xmlNewNode(NULL, "update");
468 }
469 else
470 {
471 node = create_delete_filter(this, "access-request-ip");
472 }
473 xmlAddChild(request, node);
474
475 /* add access-request, ip-address and [if up] metadata */
476 xmlAddChild(node, create_access_request(this, ike_sa_id));
477 xmlAddChild(node, create_ip_address(this, host));
478 if (up)
479 {
480 xmlAddChild(node, create_metadata(this, "access-request-ip"));
481 }
482
483 /**
484 * update or delete authenticated-by metadata
485 */
486 if (up)
487 {
488 node = xmlNewNode(NULL, "update");
489 }
490 else
491 {
492 node = create_delete_filter(this, "authenticated-by");
493 }
494 xmlAddChild(request, node);
495
496 /* add access-request, device and [if up] metadata */
497 xmlAddChild(node, create_access_request(this, ike_sa_id));
498 xmlAddChild(node, create_device(this));
499 if (up)
500 {
501 xmlAddChild(node, create_metadata(this, "authenticated-by"));
502 }
503
504 /**
505 * update or delete capability metadata
506 */
507 e1 = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
508 while (e1->enumerate(e1, &auth) && (first || up))
509 {
510 e2 = auth->create_enumerator(auth);
511 while (e2->enumerate(e2, &type, &group))
512 {
513 /* look for group memberships */
514 if (type == AUTH_RULE_GROUP)
515 {
516 if (first)
517 {
518 first = FALSE;
519
520 if (up)
521 {
522 node = xmlNewNode(NULL, "update");
523 }
524 else
525 {
526 node = create_delete_filter(this, "capability");
527 }
528 xmlAddChild(request, node);
529
530 /* add access-request */
531 xmlAddChild(node, create_access_request(this, ike_sa_id));
532 if (!up)
533 {
534 break;
535 }
536 node2 = xmlNewNode(NULL, "metadata");
537 xmlAddChild(node, node2);
538 }
539 xmlAddChild(node2, create_capability(this, group));
540 }
541 }
542 e2->destroy(e2);
543 }
544 e1->destroy(e1);
545
546 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
547 success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
548 soap_msg->destroy(soap_msg);
549
550 return success;
551 }
552
553 METHOD(tnc_ifmap_soap_t, publish_device_ip, bool,
554 private_tnc_ifmap_soap_t *this, host_t *host)
555 {
556 tnc_ifmap_soap_msg_t *soap_msg;
557 xmlNodePtr request, update;
558 bool success;
559
560 /* build publish update request */
561 request = create_publish_request(this);
562 update = xmlNewNode(NULL, "update");
563 xmlAddChild(request, update);
564
565 /* add device, ip-address and metadata */
566 xmlAddChild(update, create_device(this));
567 xmlAddChild(update, create_ip_address(this, host));
568 xmlAddChild(update, create_metadata(this, "device-ip"));
569
570 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
571 success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
572 soap_msg->destroy(soap_msg);
573
574 return success;
575 }
576
577 METHOD(tnc_ifmap_soap_t, publish_enforcement_report, bool,
578 private_tnc_ifmap_soap_t *this, host_t *host, char *action, char *reason)
579 {
580 tnc_ifmap_soap_msg_t *soap_msg;
581 xmlNodePtr request, update;
582 bool success;
583
584 /* build publish update request */
585 request = create_publish_request(this);
586 update = xmlNewNode(NULL, "update");
587 xmlAddChild(request, update);
588
589 /* add ip-address and metadata */
590 xmlAddChild(update, create_ip_address(this, host));
591 xmlAddChild(update, create_device(this));
592 xmlAddChild(update, create_enforcement_report(this, action, reason));
593
594 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
595 success = soap_msg->post(soap_msg, request, "publishReceived", NULL);
596 soap_msg->destroy(soap_msg);
597
598 return success;
599 }
600
601 METHOD(tnc_ifmap_soap_t, endSession, bool,
602 private_tnc_ifmap_soap_t *this)
603 {
604 tnc_ifmap_soap_msg_t *soap_msg;
605 xmlNodePtr request;
606 bool success;
607
608 /* build endSession request */
609 request = xmlNewNode(NULL, "endSession");
610 this->ns = xmlNewNs(request, IFMAP_NS, "ifmap");
611 xmlSetNs(request, this->ns);
612 xmlNewProp(request, "session-id", this->session_id);
613
614 soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls);
615 success = soap_msg->post(soap_msg, request, "endSessionResult", NULL);
616 soap_msg->destroy(soap_msg);
617
618 return success;
619 }
620
621 METHOD(tnc_ifmap_soap_t, destroy, void,
622 private_tnc_ifmap_soap_t *this)
623 {
624 if (this->session_id)
625 {
626 endSession(this);
627 xmlFree(this->session_id);
628 xmlFree(this->ifmap_publisher_id);
629 free(this->device_name);
630 }
631 DESTROY_IF(this->tls);
632 DESTROY_IF(this->host);
633
634 if (this->fd != IFMAP_NO_FD)
635 {
636 close(this->fd);
637 }
638 lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
639 this->creds->destroy(this->creds);
640 free(this->user_pass.ptr);
641 free(this);
642 }
643
644 static bool soap_init(private_tnc_ifmap_soap_t *this)
645 {
646 char *server_uri, *server_str, *port_str, *uri_str;
647 char *server_cert, *client_cert, *client_key, *user_pass;
648 int port;
649 auth_cfg_t *auth;
650 certificate_t *cert;
651 private_key_t *key;
652 identification_t *server_id, *client_id = NULL;
653
654 /* getting configuration parameters from strongswan.conf */
655 server_uri = lib->settings->get_str(lib->settings,
656 "%s.plugins.tnc-ifmap.server_uri", IFMAP_URI, charon->name);
657 server_cert = lib->settings->get_str(lib->settings,
658 "%s.plugins.tnc-ifmap.server_cert", NULL, charon->name);
659 client_cert = lib->settings->get_str(lib->settings,
660 "%s.plugins.tnc-ifmap.client_cert", NULL, charon->name);
661 client_key = lib->settings->get_str(lib->settings,
662 "%s.plugins.tnc-ifmap.client_key", NULL, charon->name);
663 user_pass = lib->settings->get_str(lib->settings,
664 "%s.plugins.tnc-ifmap.username_password", NULL, charon->name);
665
666 /* load [self-signed] MAP server certificate */
667 if (!server_cert)
668 {
669 DBG1(DBG_TNC, "MAP server certificate not defined");
670 return FALSE;
671 }
672 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
673 BUILD_FROM_FILE, server_cert, BUILD_END);
674 if (!cert)
675 {
676 DBG1(DBG_TNC, "loading MAP server certificate from '%s' failed",
677 server_cert);
678 return FALSE;
679 }
680 DBG1(DBG_TNC, "loaded MAP server certificate from '%s'", server_cert);
681 server_id = cert->get_subject(cert);
682 this->creds->add_cert(this->creds, TRUE, cert);
683
684 /* check availability of client credentials */
685 if (!client_cert && !user_pass)
686 {
687 DBG1(DBG_TNC, "neither MAP client certificate "
688 "nor username:password defined");
689 return FALSE;
690 }
691
692 if (client_cert)
693 {
694 /* load MAP client certificate */
695 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
696 BUILD_FROM_FILE, client_cert, BUILD_END);
697 if (!cert)
698 {
699 DBG1(DBG_TNC, "loading MAP client certificate from '%s' failed",
700 client_cert);
701 return FALSE;
702 }
703 DBG1(DBG_TNC, "loaded MAP client certificate from '%s'", client_cert);
704 this->creds->add_cert(this->creds, TRUE, cert);
705
706 /* load MAP client private key */
707 if (client_key)
708 {
709 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
710 BUILD_FROM_FILE, client_key, BUILD_END);
711 if (!key)
712 {
713 DBG1(DBG_TNC, "loading MAP client private key from '%s' failed",
714 client_key);
715 return FALSE;
716 }
717 DBG1(DBG_TNC, "loaded MAP client RSA private key from '%s'",
718 client_key);
719 this->creds->add_key(this->creds, key);
720 }
721
722 /* set client ID to certificate distinguished name */
723 client_id = cert->get_subject(cert);
724
725 /* check if we have a private key matching the certificate */
726 auth = auth_cfg_create();
727 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
728 key = lib->credmgr->get_private(lib->credmgr, KEY_RSA, client_id, auth);
729 auth->destroy(auth);
730 if (!key)
731 {
732 DBG1(DBG_TNC, "no RSA private key matching MAP client certificate");
733 return FALSE;
734 }
735 }
736 else
737 {
738 /* set base64-encoded username:password for HTTP Basic Authentication */
739 this->user_pass = chunk_to_base64(chunk_from_str(user_pass), NULL);
740 }
741
742 /* remove HTTPS prefix if any */
743 if (strlen(server_uri) >= 8 && strncaseeq(server_uri, "https://", 8))
744 {
745 server_uri += 8;
746 }
747 this->uri = server_uri;
748
749 /* duplicate server string since we are going to manipulate it */
750 server_str = strdup(server_uri);
751
752 /* extract server name and port from server URI */
753 port_str = strchr(server_str, ':');
754 if (port_str)
755 {
756 *port_str++ = '\0';
757 if (sscanf(port_str, "%d", &port) != 1)
758 {
759 DBG1(DBG_TNC, "parsing server port %s failed", port_str);
760 free(server_str);
761 return FALSE;
762 }
763 }
764 else
765 {
766 /* use default https port */
767 port = 443;
768 uri_str = strchr(server_str, '/');
769 if (uri_str)
770 {
771 *uri_str = '\0';
772 }
773 }
774
775 /* open TCP socket and connect to MAP server */
776 this->host = host_create_from_dns(server_str, 0, port);
777 if (!this->host)
778 {
779 DBG1(DBG_TNC, "resolving hostname %s failed", server_str);
780 free(server_str);
781 return FALSE;
782 }
783 free(server_str);
784
785 this->fd = socket(this->host->get_family(this->host), SOCK_STREAM, 0);
786 if (this->fd == IFMAP_NO_FD)
787 {
788 DBG1(DBG_TNC, "opening socket failed: %s", strerror(errno));
789 return FALSE;
790 }
791
792 if (connect(this->fd, this->host->get_sockaddr(this->host),
793 *this->host->get_sockaddr_len(this->host)) == -1)
794 {
795 DBG1(DBG_TNC, "connecting to %#H failed: %s",
796 this->host, strerror(errno));
797 return FALSE;
798 }
799
800 /* open TLS socket */
801 this->tls = tls_socket_create(FALSE, server_id, client_id, this->fd, NULL);
802 if (!this->tls)
803 {
804 DBG1(DBG_TNC, "creating TLS socket failed");
805 return FALSE;
806 }
807
808 return TRUE;
809 }
810
811 /**
812 * See header
813 */
814 tnc_ifmap_soap_t *tnc_ifmap_soap_create()
815 {
816 private_tnc_ifmap_soap_t *this;
817
818 INIT(this,
819 .public = {
820 .newSession = _newSession,
821 .renewSession = _renewSession,
822 .purgePublisher = _purgePublisher,
823 .publish_ike_sa = _publish_ike_sa,
824 .publish_device_ip = _publish_device_ip,
825 .publish_enforcement_report = _publish_enforcement_report,
826 .endSession = _endSession,
827 .destroy = _destroy,
828 },
829 .fd = IFMAP_NO_FD,
830 .creds = mem_cred_create(),
831 );
832
833 lib->credmgr->add_set(lib->credmgr, &this->creds->set);
834
835 if (!soap_init(this))
836 {
837 destroy(this);
838 return NULL;
839 }
840
841 return &this->public;
842 }
843