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