Annotation of embedaddon/strongswan/src/libimcv/plugins/imc_test/imc_test.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2011-2012 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_test_state.h"
! 17:
! 18: #include <imc/imc_agent.h>
! 19: #include <imc/imc_msg.h>
! 20: #include <ietf/ietf_attr.h>
! 21: #include <ita/ita_attr.h>
! 22: #include <ita/ita_attr_command.h>
! 23: #include <ita/ita_attr_dummy.h>
! 24:
! 25: #include <tncif_pa_subtypes.h>
! 26:
! 27: #include <pen/pen.h>
! 28: #include <utils/debug.h>
! 29:
! 30: /* IMC definitions */
! 31:
! 32: static const char imc_name[] = "Test";
! 33:
! 34: static pen_type_t msg_types[] = {
! 35: { PEN_ITA, PA_SUBTYPE_ITA_TEST }
! 36: };
! 37:
! 38: static imc_agent_t *imc_test;
! 39:
! 40: /**
! 41: * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
! 42: */
! 43: TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
! 44: TNC_Version min_version,
! 45: TNC_Version max_version,
! 46: TNC_Version *actual_version)
! 47: {
! 48: if (imc_test)
! 49: {
! 50: DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
! 51: return TNC_RESULT_ALREADY_INITIALIZED;
! 52: }
! 53: imc_test = imc_agent_create(imc_name, msg_types, countof(msg_types),
! 54: imc_id, actual_version);
! 55: if (!imc_test)
! 56: {
! 57: return TNC_RESULT_FATAL;
! 58: }
! 59: if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
! 60: {
! 61: DBG1(DBG_IMC, "no common IF-IMC version");
! 62: return TNC_RESULT_NO_COMMON_VERSION;
! 63: }
! 64: return TNC_RESULT_SUCCESS;
! 65: }
! 66:
! 67: /**
! 68: * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
! 69: */
! 70: TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
! 71: TNC_ConnectionID connection_id,
! 72: TNC_ConnectionState new_state)
! 73: {
! 74: imc_state_t *state;
! 75: imc_test_state_t *test_state;
! 76: TNC_Result result;
! 77: TNC_UInt32 additional_id;
! 78: char *command;
! 79: bool retry;
! 80: void *pointer;
! 81: enumerator_t *enumerator;
! 82: int dummy_size, additional_ids;
! 83:
! 84: if (!imc_test)
! 85: {
! 86: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 87: return TNC_RESULT_NOT_INITIALIZED;
! 88: }
! 89:
! 90: switch (new_state)
! 91: {
! 92: case TNC_CONNECTION_STATE_CREATE:
! 93: command = lib->settings->get_str(lib->settings,
! 94: "%s.plugins.imc-test.command", "none", lib->ns);
! 95: dummy_size = lib->settings->get_int(lib->settings,
! 96: "%s.plugins.imc-test.dummy_size", 0, lib->ns);
! 97: retry = lib->settings->get_bool(lib->settings,
! 98: "%s.plugins.imc-test.retry", FALSE, lib->ns);
! 99: state = imc_test_state_create(connection_id, command, dummy_size,
! 100: retry);
! 101:
! 102: result = imc_test->create_state(imc_test, state);
! 103: if (result != TNC_RESULT_SUCCESS)
! 104: {
! 105: return result;
! 106: }
! 107:
! 108: /* Optionally reserve additional IMC IDs */
! 109: additional_ids = lib->settings->get_int(lib->settings,
! 110: "%s.plugins.imc-test.additional_ids", 0, lib->ns);
! 111: imc_test->reserve_additional_ids(imc_test, additional_ids -
! 112: imc_test->count_additional_ids(imc_test));
! 113:
! 114: return TNC_RESULT_SUCCESS;
! 115:
! 116: case TNC_CONNECTION_STATE_HANDSHAKE:
! 117: /* get updated IMC state */
! 118: result = imc_test->change_state(imc_test, connection_id,
! 119: new_state, &state);
! 120: if (result != TNC_RESULT_SUCCESS)
! 121: {
! 122: return TNC_RESULT_FATAL;
! 123: }
! 124: test_state = (imc_test_state_t*)state;
! 125:
! 126: /* is it the first handshake or a retry ? */
! 127: if (!test_state->is_first_handshake(test_state))
! 128: {
! 129: command = lib->settings->get_str(lib->settings,
! 130: "%s.plugins.imc-test.retry_command",
! 131: test_state->get_command(test_state), lib->ns);
! 132: test_state->set_command(test_state, command);
! 133: }
! 134:
! 135: state->set_result(state, imc_id, TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
! 136:
! 137: /* Exit if there are no additional IMC IDs */
! 138: if (!imc_test->count_additional_ids(imc_test))
! 139: {
! 140: return result;
! 141: }
! 142:
! 143: enumerator = imc_test->create_id_enumerator(imc_test);
! 144: while (enumerator->enumerate(enumerator, &pointer))
! 145: {
! 146: /* interpret pointer as scalar value */
! 147: additional_id = (TNC_UInt32)pointer;
! 148:
! 149: state->set_result(state, additional_id,
! 150: TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
! 151: }
! 152: enumerator->destroy(enumerator);
! 153:
! 154: return TNC_RESULT_SUCCESS;
! 155:
! 156: case TNC_CONNECTION_STATE_DELETE:
! 157: return imc_test->delete_state(imc_test, connection_id);
! 158:
! 159: case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
! 160: case TNC_CONNECTION_STATE_ACCESS_NONE:
! 161: /* get updated IMC state */
! 162: result = imc_test->change_state(imc_test, connection_id,
! 163: new_state, &state);
! 164: if (result != TNC_RESULT_SUCCESS)
! 165: {
! 166: return TNC_RESULT_FATAL;
! 167: }
! 168: test_state = (imc_test_state_t*)state;
! 169:
! 170: /* do a handshake retry? */
! 171: if (test_state->do_handshake_retry(test_state))
! 172: {
! 173: return imc_test->request_handshake_retry(imc_id, connection_id,
! 174: TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE);
! 175: }
! 176: return TNC_RESULT_SUCCESS;
! 177:
! 178: default:
! 179: return imc_test->change_state(imc_test, connection_id,
! 180: new_state, NULL);
! 181: }
! 182: }
! 183:
! 184: static void create_message(imc_state_t *state, imc_msg_t *out_msg)
! 185: {
! 186: imc_test_state_t *test_state;
! 187: pa_tnc_attr_t *attr;
! 188:
! 189: test_state = (imc_test_state_t*)state;
! 190: if (test_state->get_dummy_size(test_state))
! 191: {
! 192: attr = ita_attr_dummy_create(test_state->get_dummy_size(test_state));
! 193: attr->set_noskip_flag(attr, TRUE);
! 194: out_msg->add_attribute(out_msg, attr);
! 195: }
! 196: attr = ita_attr_command_create(test_state->get_command(test_state));
! 197: attr->set_noskip_flag(attr, TRUE);
! 198: out_msg->add_attribute(out_msg, attr);
! 199: }
! 200:
! 201: /**
! 202: * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
! 203: */
! 204: TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
! 205: TNC_ConnectionID connection_id)
! 206: {
! 207: imc_state_t *state;
! 208: imc_msg_t *out_msg;
! 209: enumerator_t *enumerator;
! 210: void *pointer;
! 211: TNC_UInt32 additional_id;
! 212: TNC_Result result;
! 213:
! 214: if (!imc_test)
! 215: {
! 216: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 217: return TNC_RESULT_NOT_INITIALIZED;
! 218: }
! 219: if (!imc_test->get_state(imc_test, connection_id, &state))
! 220: {
! 221: return TNC_RESULT_FATAL;
! 222: }
! 223:
! 224: /* send PA message for primary IMC ID with the EXCL flag set */
! 225: out_msg = imc_msg_create(imc_test, state, connection_id, imc_id,
! 226: TNC_IMVID_ANY, msg_types[0]);
! 227: create_message(state, out_msg);
! 228: result = out_msg->send(out_msg, TRUE);
! 229: out_msg->destroy(out_msg);
! 230:
! 231: /* Exit if there are no additional IMC IDs */
! 232: if (!imc_test->count_additional_ids(imc_test))
! 233: {
! 234: return result;
! 235: }
! 236:
! 237: /* Do we have support for transporting multiple IMC IDs? */
! 238: if (!state->has_long(state))
! 239: {
! 240: DBG1(DBG_IMC, "IMC %u \"%s\" did not detect support for transporting "
! 241: "multiple IMC IDs", imc_id, imc_name);
! 242: return result;
! 243: }
! 244:
! 245: /* send PA messages for additional IMC IDs */
! 246: enumerator = imc_test->create_id_enumerator(imc_test);
! 247: while (result == TNC_RESULT_SUCCESS &&
! 248: enumerator->enumerate(enumerator, &pointer))
! 249: {
! 250: /* interpret pointer as scalar value */
! 251: additional_id = (TNC_UInt32)pointer;
! 252: out_msg = imc_msg_create(imc_test, state, connection_id, additional_id,
! 253: TNC_IMVID_ANY, msg_types[0]);
! 254: create_message(state, out_msg);
! 255: result = out_msg->send(out_msg, TRUE);
! 256: out_msg->destroy(out_msg);
! 257: }
! 258: enumerator->destroy(enumerator);
! 259:
! 260: return result;
! 261: }
! 262:
! 263: static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
! 264: {
! 265: imc_msg_t *out_msg;
! 266: enumerator_t *enumerator;
! 267: pa_tnc_attr_t *attr;
! 268: pen_type_t attr_type;
! 269: TNC_Result result = TNC_RESULT_SUCCESS;
! 270: bool fatal_error = FALSE;
! 271:
! 272: /* generate an outgoing PA-TNC message - we might need it */
! 273: out_msg = imc_msg_create_as_reply(in_msg);
! 274:
! 275: /* parse received PA-TNC message and handle local and remote errors */
! 276: result = in_msg->receive(in_msg, out_msg, &fatal_error);
! 277: if (result != TNC_RESULT_SUCCESS)
! 278: {
! 279: out_msg->destroy(out_msg);
! 280: return result;
! 281: }
! 282:
! 283: /* analyze PA-TNC attributes */
! 284: enumerator = in_msg->create_attribute_enumerator(in_msg);
! 285: while (enumerator->enumerate(enumerator, &attr))
! 286: {
! 287: attr_type = attr->get_type(attr);
! 288:
! 289: if (attr_type.vendor_id != PEN_ITA)
! 290: {
! 291: continue;
! 292: }
! 293: if (attr_type.type == ITA_ATTR_COMMAND)
! 294: {
! 295: ita_attr_command_t *ita_attr;
! 296:
! 297: ita_attr = (ita_attr_command_t*)attr;
! 298: DBG1(DBG_IMC, "received command '%s'",
! 299: ita_attr->get_command(ita_attr));
! 300: }
! 301: else if (attr_type.type == ITA_ATTR_DUMMY)
! 302: {
! 303: ita_attr_dummy_t *ita_attr;
! 304:
! 305: ita_attr = (ita_attr_dummy_t*)attr;
! 306: DBG1(DBG_IMC, "received dummy attribute value (%d bytes)",
! 307: ita_attr->get_size(ita_attr));
! 308: }
! 309: }
! 310: enumerator->destroy(enumerator);
! 311:
! 312: if (fatal_error)
! 313: {
! 314: result = TNC_RESULT_FATAL;
! 315: }
! 316: else
! 317: {
! 318: /* if no assessment result is known then repeat the measurement */
! 319: if (!state->get_result(state, in_msg->get_dst_id(in_msg), NULL))
! 320: {
! 321: create_message(state, out_msg);
! 322: }
! 323: result = out_msg->send(out_msg, TRUE);
! 324: }
! 325: out_msg->destroy(out_msg);
! 326:
! 327: return result;
! 328: }
! 329:
! 330: /**
! 331: * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
! 332: */
! 333: TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
! 334: TNC_ConnectionID connection_id,
! 335: TNC_BufferReference msg,
! 336: TNC_UInt32 msg_len,
! 337: TNC_MessageType msg_type)
! 338: {
! 339: imc_state_t *state;
! 340: imc_msg_t *in_msg;
! 341: TNC_Result result;
! 342:
! 343: if (!imc_test)
! 344: {
! 345: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 346: return TNC_RESULT_NOT_INITIALIZED;
! 347: }
! 348: if (!imc_test->get_state(imc_test, connection_id, &state))
! 349: {
! 350: return TNC_RESULT_FATAL;
! 351: }
! 352:
! 353: in_msg = imc_msg_create_from_data(imc_test, state, connection_id, msg_type,
! 354: chunk_create(msg, msg_len));
! 355: result = receive_message(state, in_msg);
! 356: in_msg->destroy(in_msg);
! 357:
! 358: return result;
! 359: }
! 360:
! 361: /**
! 362: * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
! 363: */
! 364: TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
! 365: TNC_ConnectionID connection_id,
! 366: TNC_UInt32 msg_flags,
! 367: TNC_BufferReference msg,
! 368: TNC_UInt32 msg_len,
! 369: TNC_VendorID msg_vid,
! 370: TNC_MessageSubtype msg_subtype,
! 371: TNC_UInt32 src_imv_id,
! 372: TNC_UInt32 dst_imc_id)
! 373: {
! 374: imc_state_t *state;
! 375: imc_msg_t *in_msg;
! 376: TNC_Result result;
! 377:
! 378: if (!imc_test)
! 379: {
! 380: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 381: return TNC_RESULT_NOT_INITIALIZED;
! 382: }
! 383: if (!imc_test->get_state(imc_test, connection_id, &state))
! 384: {
! 385: return TNC_RESULT_FATAL;
! 386: }
! 387: in_msg = imc_msg_create_from_long_data(imc_test, state, connection_id,
! 388: src_imv_id, dst_imc_id, msg_vid, msg_subtype,
! 389: chunk_create(msg, msg_len));
! 390: result =receive_message(state, in_msg);
! 391: in_msg->destroy(in_msg);
! 392:
! 393: return result;
! 394: }
! 395:
! 396: /**
! 397: * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
! 398: */
! 399: TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
! 400: TNC_ConnectionID connection_id)
! 401: {
! 402: if (!imc_test)
! 403: {
! 404: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 405: return TNC_RESULT_NOT_INITIALIZED;
! 406: }
! 407: return TNC_RESULT_SUCCESS;
! 408: }
! 409:
! 410: /**
! 411: * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
! 412: */
! 413: TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
! 414: {
! 415: if (!imc_test)
! 416: {
! 417: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 418: return TNC_RESULT_NOT_INITIALIZED;
! 419: }
! 420: imc_test->destroy(imc_test);
! 421: imc_test = NULL;
! 422:
! 423: return TNC_RESULT_SUCCESS;
! 424: }
! 425:
! 426: /**
! 427: * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
! 428: */
! 429: TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
! 430: TNC_TNCC_BindFunctionPointer bind_function)
! 431: {
! 432: if (!imc_test)
! 433: {
! 434: DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
! 435: return TNC_RESULT_NOT_INITIALIZED;
! 436: }
! 437: return imc_test->bind_functions(imc_test, bind_function);
! 438: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>