Annotation of embedaddon/strongswan/src/libimcv/plugins/imc_os/imc_os.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2011-2015 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 "imc_os_state.h"
! 17:
! 18: #include <imc/imc_agent.h>
! 19: #include <imc/imc_msg.h>
! 20: #include <imc/imc_os_info.h>
! 21: #include <generic/generic_attr_bool.h>
! 22: #include <generic/generic_attr_string.h>
! 23: #include <ietf/ietf_attr.h>
! 24: #include <ietf/ietf_attr_attr_request.h>
! 25: #include "ietf/ietf_attr_fwd_enabled.h"
! 26: #include <ietf/ietf_attr_installed_packages.h>
! 27: #include <ietf/ietf_attr_numeric_version.h>
! 28: #include <ietf/ietf_attr_op_status.h>
! 29: #include <ietf/ietf_attr_product_info.h>
! 30: #include <ietf/ietf_attr_string_version.h>
! 31: #include <ita/ita_attr.h>
! 32: #include <ita/ita_attr_get_settings.h>
! 33: #include <ita/ita_attr_settings.h>
! 34:
! 35: #include <tncif_pa_subtypes.h>
! 36:
! 37: #include <pen/pen.h>
! 38: #include <utils/debug.h>
! 39:
! 40: /* IMC definitions */
! 41:
! 42: static const char imc_name[] = "OS";
! 43:
! 44: static pen_type_t msg_types[] = {
! 45: { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM }
! 46: };
! 47:
! 48: static imc_agent_t *imc_os;
! 49: static imc_os_info_t *os;
! 50:
! 51: /**
! 52: * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
! 53: */
! 54: TNC_Result TNC_IMC_API TNC_IMC_Initialize(TNC_IMCID imc_id,
! 55: TNC_Version min_version,
! 56: TNC_Version max_version,
! 57: TNC_Version *actual_version)
! 58: {
! 59: if (imc_os)
! 60: {
! 61: DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
! 62: return TNC_RESULT_ALREADY_INITIALIZED;
! 63: }
! 64: imc_os = imc_agent_create(imc_name, msg_types, countof(msg_types),
! 65: imc_id, actual_version);
! 66: if (!imc_os)
! 67: {
! 68: return TNC_RESULT_FATAL;
! 69: }
! 70:
! 71: os = imc_os_info_create();
! 72: if (!os)
! 73: {
! 74: imc_os->destroy(imc_os);
! 75: imc_os = NULL;
! 76:
! 77: return TNC_RESULT_FATAL;
! 78: }
! 79:
! 80: if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
! 81: {
! 82: DBG1(DBG_IMC, "no common IF-IMC version");
! 83: return TNC_RESULT_NO_COMMON_VERSION;
! 84: }
! 85: return TNC_RESULT_SUCCESS;
! 86: }
! 87:
! 88: /**
! 89: * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
! 90: */
! 91: TNC_Result TNC_IMC_API TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
! 92: TNC_ConnectionID connection_id, TNC_ConnectionState new_state)
! 93: {
! 94: imc_state_t *state;
! 95:
! 96: if (!imc_os)
! 97: {
! 98: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 99: return TNC_RESULT_NOT_INITIALIZED;
! 100: }
! 101: switch (new_state)
! 102: {
! 103: case TNC_CONNECTION_STATE_CREATE:
! 104: state = imc_os_state_create(connection_id);
! 105: return imc_os->create_state(imc_os, state);
! 106: case TNC_CONNECTION_STATE_DELETE:
! 107: return imc_os->delete_state(imc_os, connection_id);
! 108: default:
! 109: return imc_os->change_state(imc_os, connection_id,
! 110: new_state, NULL);
! 111: }
! 112: }
! 113:
! 114: /**
! 115: * Add IETF Product Information attribute to the send queue
! 116: */
! 117: static void add_product_info(imc_msg_t *msg)
! 118: {
! 119: pa_tnc_attr_t *attr;
! 120: os_type_t os_type;
! 121: pen_t vendor_id = PEN_IETF;
! 122: int i;
! 123:
! 124: typedef struct vendor_pen_t {
! 125: os_type_t os_type;
! 126: pen_t pen;
! 127: } vendor_pen_t;
! 128:
! 129: vendor_pen_t vendor_pens[] = {
! 130: { OS_TYPE_DEBIAN, PEN_DEBIAN },
! 131: { OS_TYPE_UBUNTU, PEN_CANONICAL },
! 132: { OS_TYPE_FEDORA, PEN_FEDORA },
! 133: { OS_TYPE_REDHAT, PEN_REDHAT },
! 134: { OS_TYPE_ANDROID, PEN_GOOGLE }
! 135: };
! 136:
! 137: os_type = os->get_type(os);
! 138: for (i = 0; i < countof(vendor_pens); i++)
! 139: {
! 140: if (os_type == vendor_pens[i].os_type)
! 141: {
! 142: vendor_id = vendor_pens[i].pen;
! 143: break;
! 144: }
! 145: }
! 146: attr = ietf_attr_product_info_create(vendor_id, 0, os->get_name(os));
! 147: msg->add_attribute(msg, attr);
! 148: }
! 149:
! 150: /**
! 151: * Add IETF Numeric Version attribute to the send queue
! 152: */
! 153: static void add_numeric_version(imc_msg_t *msg)
! 154: {
! 155: pa_tnc_attr_t *attr;
! 156: uint32_t major, minor;
! 157:
! 158: os->get_numeric_version(os, &major, &minor);
! 159: DBG1(DBG_IMC, "operating system numeric version is %d.%d",
! 160: major, minor);
! 161:
! 162: attr = ietf_attr_numeric_version_create(major, minor, 0, 0, 0);
! 163: msg->add_attribute(msg, attr);
! 164: }
! 165:
! 166: /**
! 167: * Add IETF String Version attribute to the send queue
! 168: */
! 169: static void add_string_version(imc_msg_t *msg)
! 170: {
! 171: pa_tnc_attr_t *attr;
! 172:
! 173: attr = ietf_attr_string_version_create(os->get_version(os),
! 174: chunk_empty, chunk_empty);
! 175: msg->add_attribute(msg, attr);
! 176: }
! 177:
! 178: /**
! 179: * Add IETF Operational Status attribute to the send queue
! 180: */
! 181: static void add_op_status(imc_msg_t *msg)
! 182: {
! 183: pa_tnc_attr_t *attr;
! 184: time_t uptime, last_boot;
! 185:
! 186: uptime = os->get_uptime(os);
! 187: last_boot = uptime ? time(NULL) - uptime : UNDEFINED_TIME;
! 188: if (last_boot != UNDEFINED_TIME)
! 189: {
! 190: DBG1(DBG_IMC, "last boot: %T, %u s ago", &last_boot, TRUE, uptime);
! 191: }
! 192: attr = ietf_attr_op_status_create(OP_STATUS_OPERATIONAL,
! 193: OP_RESULT_SUCCESSFUL, last_boot);
! 194: msg->add_attribute(msg, attr);
! 195: }
! 196:
! 197: /**
! 198: * Add IETF Forwarding Enabled attribute to the send queue
! 199: */
! 200: static void add_fwd_enabled(imc_msg_t *msg)
! 201: {
! 202: pa_tnc_attr_t *attr;
! 203: os_fwd_status_t fwd_status;
! 204:
! 205: fwd_status = os->get_fwd_status(os);
! 206: DBG1(DBG_IMC, "IPv4 forwarding is %N", os_fwd_status_names, fwd_status);
! 207: attr = ietf_attr_fwd_enabled_create(fwd_status,
! 208: pen_type_create(PEN_IETF, IETF_ATTR_FORWARDING_ENABLED));
! 209: msg->add_attribute(msg, attr);
! 210: }
! 211:
! 212: /**
! 213: * Add IETF Factory Default Password Enabled attribute to the send queue
! 214: */
! 215: static void add_default_pwd_enabled(imc_msg_t *msg)
! 216: {
! 217: pa_tnc_attr_t *attr;
! 218: bool status;
! 219:
! 220: status = os->get_default_pwd_status(os);
! 221: DBG1(DBG_IMC, "factory default password is %sabled", status ? "en" : "dis");
! 222: attr = generic_attr_bool_create(status,
! 223: pen_type_create(PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED));
! 224: msg->add_attribute(msg, attr);
! 225: }
! 226:
! 227: /**
! 228: * Add ITA Device ID attribute to the send queue
! 229: */
! 230: static void add_device_id(imc_msg_t *msg)
! 231: {
! 232: pa_tnc_attr_t *attr;
! 233: chunk_t chunk, value = chunk_empty, keyid;
! 234: char *name, *device_id, *device_handle, *cert_path;
! 235: certificate_t *cert = NULL;
! 236: private_key_t *privkey = NULL;
! 237: public_key_t *pubkey;
! 238:
! 239: /* Get the device ID as a character string */
! 240: device_id = lib->settings->get_str(lib->settings,
! 241: "%s.plugins.imc-os.device_id", NULL, lib->ns);
! 242: if (device_id)
! 243: {
! 244: value = chunk_clone(chunk_from_str(device_id));
! 245: }
! 246:
! 247: if (value.len == 0)
! 248: {
! 249: /* Derive the device ID from a private key bound to a smartcard or TPM */
! 250: device_handle = lib->settings->get_str(lib->settings,
! 251: "%s.plugins.imc-os.device_handle", NULL, lib->ns);
! 252: if (device_handle)
! 253: {
! 254: chunk = chunk_from_hex(
! 255: chunk_create(device_handle, strlen(device_handle)), NULL);
! 256: privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
! 257: BUILD_PKCS11_KEYID, chunk, BUILD_END);
! 258: free(chunk.ptr);
! 259:
! 260: if (privkey)
! 261: {
! 262: if (privkey->get_fingerprint(privkey, KEYID_PUBKEY_INFO_SHA1,
! 263: &keyid))
! 264: {
! 265: value = chunk_to_hex(keyid, NULL, FALSE);
! 266: }
! 267: privkey->destroy(privkey);
! 268:
! 269: }
! 270: }
! 271: }
! 272:
! 273: if (value.len == 0)
! 274: {
! 275: /* Derive the device ID from a raw public key */
! 276: cert_path = lib->settings->get_str(lib->settings,
! 277: "%s.plugins.imc-os.device_pubkey", NULL, lib->ns);
! 278: if (cert_path)
! 279: {
! 280: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
! 281: CERT_TRUSTED_PUBKEY, BUILD_FROM_FILE,
! 282: cert_path, BUILD_END);
! 283: if (cert)
! 284: {
! 285: DBG2(DBG_IMC, "loaded device public key from '%s'", cert_path);
! 286: }
! 287: else
! 288: {
! 289: DBG1(DBG_IMC, "loading device public key from '%s' failed",
! 290: cert_path);
! 291: }
! 292: }
! 293:
! 294: if (!cert)
! 295: {
! 296: /* Derive the device ID from the public key contained in a certificate */
! 297: cert_path = lib->settings->get_str(lib->settings,
! 298: "%s.plugins.imc-os.device_cert", NULL, lib->ns);
! 299: if (cert_path)
! 300: {
! 301: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
! 302: CERT_X509, BUILD_FROM_FILE,
! 303: cert_path, BUILD_END);
! 304: if (cert)
! 305: {
! 306: DBG2(DBG_IMC, "loaded device certificate from '%s'", cert_path);
! 307: }
! 308: else
! 309: {
! 310: DBG1(DBG_IMC, "loading device certificate from '%s' failed",
! 311: cert_path);
! 312: }
! 313: }
! 314: }
! 315:
! 316: /* Compute the SHA-1 keyid of the retrieved device public key */
! 317: if (cert)
! 318: {
! 319: pubkey = cert->get_public_key(cert);
! 320: if (pubkey)
! 321: {
! 322: if (pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1,
! 323: &keyid))
! 324: {
! 325: value = chunk_to_hex(keyid, NULL, FALSE);
! 326: }
! 327: pubkey->destroy(pubkey);
! 328: }
! 329: cert->destroy(cert);
! 330: }
! 331: }
! 332:
! 333: if (value.len == 0)
! 334: {
! 335: /* Derive the device ID from some unique OS settings */
! 336: name = os->get_type(os) == OS_TYPE_ANDROID ?
! 337: "android_id" : "/var/lib/dbus/machine-id";
! 338: value = os->get_setting(os, name);
! 339:
! 340: /* Trim trailing newline character */
! 341: if (value.len > 0 && value.ptr[value.len - 1] == '\n')
! 342: {
! 343: value.len--;
! 344: }
! 345: }
! 346:
! 347: if (value.len == 0)
! 348: {
! 349: DBG1(DBG_IMC, "no device ID available");
! 350: return;
! 351: }
! 352:
! 353: DBG1(DBG_IMC, "device ID is %.*s", value.len, value.ptr);
! 354: attr = generic_attr_string_create(value, pen_type_create(PEN_ITA,
! 355: ITA_ATTR_DEVICE_ID));
! 356: msg->add_attribute(msg, attr);
! 357: free(value.ptr);
! 358: }
! 359:
! 360: /**
! 361: * Add an IETF Installed Packages attribute to the send queue
! 362: */
! 363: static void add_installed_packages(imc_state_t *state, imc_msg_t *msg)
! 364: {
! 365: pa_tnc_attr_t *attr;
! 366: ietf_attr_installed_packages_t *attr_cast;
! 367: enumerator_t *enumerator;
! 368: chunk_t name, version;
! 369:
! 370: enumerator = os->create_package_enumerator(os);
! 371: if (!enumerator)
! 372: {
! 373: return;
! 374: }
! 375: attr = ietf_attr_installed_packages_create();
! 376:
! 377: while (enumerator->enumerate(enumerator, &name, &version))
! 378: {
! 379: DBG2(DBG_IMC, "package '%.*s' (%.*s)",
! 380: name.len, name.ptr, version.len, version.ptr);
! 381: attr_cast = (ietf_attr_installed_packages_t*)attr;
! 382: attr_cast->add(attr_cast, name, version);
! 383: }
! 384: enumerator->destroy(enumerator);
! 385:
! 386: msg->add_attribute(msg, attr);
! 387: }
! 388:
! 389: /**
! 390: * Add ITA Settings attribute to the send queue
! 391: */
! 392: static void add_settings(enumerator_t *enumerator, imc_msg_t *msg)
! 393: {
! 394: pa_tnc_attr_t *attr = NULL;
! 395: ita_attr_settings_t *attr_cast;
! 396: chunk_t value;
! 397: char *name;
! 398: bool first = TRUE;
! 399:
! 400: while (enumerator->enumerate(enumerator, &name))
! 401: {
! 402: DBG1(DBG_IMC, "setting '%s'", name);
! 403:
! 404: value = os->get_setting(os, name);
! 405: if (!value.ptr)
! 406: {
! 407: continue;
! 408: }
! 409: if (first)
! 410: {
! 411: attr = ita_attr_settings_create();
! 412: first = FALSE;
! 413: }
! 414: attr_cast = (ita_attr_settings_t*)attr;
! 415: attr_cast->add(attr_cast, name, value);
! 416: chunk_free(&value);
! 417: }
! 418:
! 419: if (attr)
! 420: {
! 421: msg->add_attribute(msg, attr);
! 422: }
! 423: }
! 424:
! 425: /**
! 426: * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
! 427: */
! 428: TNC_Result TNC_IMC_API TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
! 429: TNC_ConnectionID connection_id)
! 430: {
! 431: imc_state_t *state;
! 432: imc_msg_t *out_msg;
! 433: TNC_Result result = TNC_RESULT_SUCCESS;
! 434:
! 435: if (!imc_os)
! 436: {
! 437: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 438: return TNC_RESULT_NOT_INITIALIZED;
! 439: }
! 440: if (!imc_os->get_state(imc_os, connection_id, &state))
! 441: {
! 442: return TNC_RESULT_FATAL;
! 443: }
! 444: if (lib->settings->get_bool(lib->settings,
! 445: "%s.plugins.imc-os.push_info", TRUE, lib->ns))
! 446: {
! 447: out_msg = imc_msg_create(imc_os, state, connection_id, imc_id,
! 448: TNC_IMVID_ANY, msg_types[0]);
! 449: add_product_info(out_msg);
! 450: add_string_version(out_msg);
! 451: add_numeric_version(out_msg);
! 452: add_op_status(out_msg);
! 453: add_fwd_enabled(out_msg);
! 454: add_default_pwd_enabled(out_msg);
! 455: add_device_id(out_msg);
! 456:
! 457: /* send PA-TNC message with the excl flag not set */
! 458: result = out_msg->send(out_msg, FALSE);
! 459: out_msg->destroy(out_msg);
! 460: }
! 461:
! 462: return result;
! 463: }
! 464:
! 465: static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
! 466: {
! 467: imc_msg_t *out_msg;
! 468: enumerator_t *enumerator;
! 469: pa_tnc_attr_t *attr;
! 470: pen_type_t type;
! 471: TNC_Result result;
! 472: bool fatal_error = FALSE;
! 473:
! 474: /* generate an outgoing PA-TNC message - we might need it */
! 475: out_msg = imc_msg_create_as_reply(in_msg);
! 476:
! 477: /* parse received PA-TNC message and handle local and remote errors */
! 478: result = in_msg->receive(in_msg, out_msg, &fatal_error);
! 479: if (result != TNC_RESULT_SUCCESS)
! 480: {
! 481: out_msg->destroy(out_msg);
! 482: return result;
! 483: }
! 484:
! 485: /* analyze PA-TNC attributes */
! 486: enumerator = in_msg->create_attribute_enumerator(in_msg);
! 487: while (enumerator->enumerate(enumerator, &attr))
! 488: {
! 489: type = attr->get_type(attr);
! 490:
! 491: if (type.vendor_id == PEN_IETF)
! 492: {
! 493: if (type.type == IETF_ATTR_ATTRIBUTE_REQUEST)
! 494: {
! 495: ietf_attr_attr_request_t *attr_cast;
! 496: pen_type_t *entry;
! 497: enumerator_t *e;
! 498:
! 499: attr_cast = (ietf_attr_attr_request_t*)attr;
! 500:
! 501: e = attr_cast->create_enumerator(attr_cast);
! 502: while (e->enumerate(e, &entry))
! 503: {
! 504: if (entry->vendor_id == PEN_IETF)
! 505: {
! 506: switch (entry->type)
! 507: {
! 508: case IETF_ATTR_PRODUCT_INFORMATION:
! 509: add_product_info(out_msg);
! 510: break;
! 511: case IETF_ATTR_STRING_VERSION:
! 512: add_string_version(out_msg);
! 513: break;
! 514: case IETF_ATTR_NUMERIC_VERSION:
! 515: add_numeric_version(out_msg);
! 516: break;
! 517: case IETF_ATTR_OPERATIONAL_STATUS:
! 518: add_op_status(out_msg);
! 519: break;
! 520: case IETF_ATTR_FORWARDING_ENABLED:
! 521: add_fwd_enabled(out_msg);
! 522: break;
! 523: case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
! 524: add_default_pwd_enabled(out_msg);
! 525: break;
! 526: case IETF_ATTR_INSTALLED_PACKAGES:
! 527: add_installed_packages(state, out_msg);
! 528: break;
! 529: default:
! 530: break;
! 531: }
! 532: }
! 533: else if (entry->vendor_id == PEN_ITA)
! 534: {
! 535: switch (entry->type)
! 536: {
! 537: case ITA_ATTR_DEVICE_ID:
! 538: add_device_id(out_msg);
! 539: break;
! 540: default:
! 541: break;
! 542: }
! 543: }
! 544: }
! 545: e->destroy(e);
! 546: }
! 547: }
! 548: else if (type.vendor_id == PEN_ITA && type.type == ITA_ATTR_GET_SETTINGS)
! 549: {
! 550: ita_attr_get_settings_t *attr_cast;
! 551: enumerator_t *e;
! 552:
! 553: attr_cast = (ita_attr_get_settings_t*)attr;
! 554:
! 555: e = attr_cast->create_enumerator(attr_cast);
! 556: add_settings(e, out_msg);
! 557: e->destroy(e);
! 558: }
! 559: }
! 560: enumerator->destroy(enumerator);
! 561:
! 562: if (fatal_error)
! 563: {
! 564: result = TNC_RESULT_FATAL;
! 565: }
! 566: else
! 567: {
! 568: /* send PA-TNC message with the EXCL flag set */
! 569: result = out_msg->send(out_msg, TRUE);
! 570: }
! 571: out_msg->destroy(out_msg);
! 572:
! 573: return result;
! 574: }
! 575:
! 576: /**
! 577: * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
! 578:
! 579: */
! 580: TNC_Result TNC_IMC_API TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
! 581: TNC_ConnectionID connection_id,
! 582: TNC_BufferReference msg,
! 583: TNC_UInt32 msg_len,
! 584: TNC_MessageType msg_type)
! 585: {
! 586: imc_state_t *state;
! 587: imc_msg_t *in_msg;
! 588: TNC_Result result;
! 589:
! 590: if (!imc_os)
! 591: {
! 592: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 593: return TNC_RESULT_NOT_INITIALIZED;
! 594: }
! 595: if (!imc_os->get_state(imc_os, connection_id, &state))
! 596: {
! 597: return TNC_RESULT_FATAL;
! 598: }
! 599: in_msg = imc_msg_create_from_data(imc_os, state, connection_id, msg_type,
! 600: chunk_create(msg, msg_len));
! 601: result = receive_message(state, in_msg);
! 602: in_msg->destroy(in_msg);
! 603:
! 604: return result;
! 605: }
! 606:
! 607: /**
! 608: * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
! 609: */
! 610: TNC_Result TNC_IMC_API TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
! 611: TNC_ConnectionID connection_id,
! 612: TNC_UInt32 msg_flags,
! 613: TNC_BufferReference msg,
! 614: TNC_UInt32 msg_len,
! 615: TNC_VendorID msg_vid,
! 616: TNC_MessageSubtype msg_subtype,
! 617: TNC_UInt32 src_imv_id,
! 618: TNC_UInt32 dst_imc_id)
! 619: {
! 620: imc_state_t *state;
! 621: imc_msg_t *in_msg;
! 622: TNC_Result result;
! 623:
! 624: if (!imc_os)
! 625: {
! 626: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 627: return TNC_RESULT_NOT_INITIALIZED;
! 628: }
! 629: if (!imc_os->get_state(imc_os, connection_id, &state))
! 630: {
! 631: return TNC_RESULT_FATAL;
! 632: }
! 633: in_msg = imc_msg_create_from_long_data(imc_os, state, connection_id,
! 634: src_imv_id, dst_imc_id,msg_vid, msg_subtype,
! 635: chunk_create(msg, msg_len));
! 636: result =receive_message(state, in_msg);
! 637: in_msg->destroy(in_msg);
! 638:
! 639: return result;
! 640: }
! 641:
! 642: /**
! 643: * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
! 644: */
! 645: TNC_Result TNC_IMC_API TNC_IMC_BatchEnding(TNC_IMCID imc_id,
! 646: TNC_ConnectionID connection_id)
! 647: {
! 648: if (!imc_os)
! 649: {
! 650: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 651: return TNC_RESULT_NOT_INITIALIZED;
! 652: }
! 653: return TNC_RESULT_SUCCESS;
! 654: }
! 655:
! 656: /**
! 657: * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
! 658: */
! 659: TNC_Result TNC_IMC_API TNC_IMC_Terminate(TNC_IMCID imc_id)
! 660: {
! 661: if (!imc_os)
! 662: {
! 663: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 664: return TNC_RESULT_NOT_INITIALIZED;
! 665: }
! 666: imc_os->destroy(imc_os);
! 667: imc_os = NULL;
! 668:
! 669: os->destroy(os);
! 670: os = NULL;
! 671:
! 672: return TNC_RESULT_SUCCESS;
! 673: }
! 674:
! 675: /**
! 676: * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
! 677: */
! 678: TNC_Result TNC_IMC_API TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
! 679: TNC_TNCC_BindFunctionPointer bind_function)
! 680: {
! 681: if (!imc_os)
! 682: {
! 683: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 684: return TNC_RESULT_NOT_INITIALIZED;
! 685: }
! 686: return imc_os->bind_functions(imc_os, bind_function);
! 687: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>