Annotation of embedaddon/strongswan/src/libimcv/plugins/imv_swima/imv_swima_state.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2017 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 "imv_swima_state.h"
! 17:
! 18: #include <imv/imv_lang_string.h>
! 19: #include <imv/imv_reason_string.h>
! 20: #include <imv/imv_remediation_string.h>
! 21:
! 22: #include <tncif_policy.h>
! 23:
! 24: #include <utils/debug.h>
! 25:
! 26: typedef struct private_imv_swima_state_t private_imv_swima_state_t;
! 27:
! 28: /**
! 29: * Private data of an imv_swima_state_t object.
! 30: */
! 31: struct private_imv_swima_state_t {
! 32:
! 33: /**
! 34: * Public members of imv_swima_state_t
! 35: */
! 36: imv_swima_state_t public;
! 37:
! 38: /**
! 39: * TNCCS connection ID
! 40: */
! 41: TNC_ConnectionID connection_id;
! 42:
! 43: /**
! 44: * TNCCS connection state
! 45: */
! 46: TNC_ConnectionState state;
! 47:
! 48: /**
! 49: * Does the TNCCS connection support long message types?
! 50: */
! 51: bool has_long;
! 52:
! 53: /**
! 54: * Does the TNCCS connection support exclusive delivery?
! 55: */
! 56: bool has_excl;
! 57:
! 58: /**
! 59: * Maximum PA-TNC message size for this TNCCS connection
! 60: */
! 61: uint32_t max_msg_len;
! 62:
! 63: /**
! 64: * Flags set for completed actions
! 65: */
! 66: uint32_t action_flags;
! 67:
! 68: /**
! 69: * IMV database session associated with TNCCS connection
! 70: */
! 71: imv_session_t *session;
! 72:
! 73: /**
! 74: * PA-TNC attribute segmentation contracts associated with TNCCS connection
! 75: */
! 76: seg_contract_manager_t *contracts;
! 77:
! 78: /**
! 79: * IMV action recommendation
! 80: */
! 81: TNC_IMV_Action_Recommendation rec;
! 82:
! 83: /**
! 84: * IMV evaluation result
! 85: */
! 86: TNC_IMV_Evaluation_Result eval;
! 87:
! 88: /**
! 89: * IMV Scanner handshake state
! 90: */
! 91: imv_swima_handshake_state_t handshake_state;
! 92:
! 93: /**
! 94: * TNC Reason String
! 95: */
! 96: imv_reason_string_t *reason_string;
! 97:
! 98: /**
! 99: * IETF Remediation Instructions String
! 100: */
! 101: imv_remediation_string_t *remediation_string;
! 102:
! 103: /**
! 104: * Has a subscription been established?
! 105: */
! 106: bool has_subscription;
! 107:
! 108: /**
! 109: * SWID Tag Request ID
! 110: */
! 111: uint32_t request_id;
! 112:
! 113: /**
! 114: * Number of processed Software Identifiers
! 115: */
! 116: int sw_id_count;
! 117:
! 118: /**
! 119: * Number of processed SWID Tags
! 120: */
! 121: int tag_count;
! 122:
! 123: /**
! 124: * Number of missing Software Identifiers or SWID Tags
! 125: */
! 126: uint32_t missing;
! 127:
! 128: /**
! 129: * SWID IMC ID
! 130: */
! 131: TNC_UInt32 imc_id;
! 132:
! 133: /**
! 134: * Top level JSON object
! 135: */
! 136: json_object *jobj;
! 137:
! 138: /**
! 139: * JSON array containing either a SW [ID] inventory or SW ID events
! 140: */
! 141: json_object *jarray;
! 142:
! 143: };
! 144:
! 145: METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
! 146: private_imv_swima_state_t *this)
! 147: {
! 148: return this->connection_id;
! 149: }
! 150:
! 151: METHOD(imv_state_t, has_long, bool,
! 152: private_imv_swima_state_t *this)
! 153: {
! 154: return this->has_long;
! 155: }
! 156:
! 157: METHOD(imv_state_t, has_excl, bool,
! 158: private_imv_swima_state_t *this)
! 159: {
! 160: return this->has_excl;
! 161: }
! 162:
! 163: METHOD(imv_state_t, set_flags, void,
! 164: private_imv_swima_state_t *this, bool has_long, bool has_excl)
! 165: {
! 166: this->has_long = has_long;
! 167: this->has_excl = has_excl;
! 168: }
! 169:
! 170: METHOD(imv_state_t, set_max_msg_len, void,
! 171: private_imv_swima_state_t *this, uint32_t max_msg_len)
! 172: {
! 173: this->max_msg_len = max_msg_len;
! 174: }
! 175:
! 176: METHOD(imv_state_t, get_max_msg_len, uint32_t,
! 177: private_imv_swima_state_t *this)
! 178: {
! 179: return this->max_msg_len;
! 180: }
! 181:
! 182: METHOD(imv_state_t, set_action_flags, void,
! 183: private_imv_swima_state_t *this, uint32_t flags)
! 184: {
! 185: this->action_flags |= flags;
! 186: }
! 187:
! 188: METHOD(imv_state_t, get_action_flags, uint32_t,
! 189: private_imv_swima_state_t *this)
! 190: {
! 191: return this->action_flags;
! 192: }
! 193:
! 194: METHOD(imv_state_t, set_session, void,
! 195: private_imv_swima_state_t *this, imv_session_t *session)
! 196: {
! 197: this->session = session;
! 198: }
! 199:
! 200: METHOD(imv_state_t, get_session, imv_session_t*,
! 201: private_imv_swima_state_t *this)
! 202: {
! 203: return this->session;
! 204: }
! 205:
! 206: METHOD(imv_state_t, get_contracts, seg_contract_manager_t*,
! 207: private_imv_swima_state_t *this)
! 208: {
! 209: return this->contracts;
! 210: }
! 211:
! 212: METHOD(imv_state_t, change_state, TNC_ConnectionState,
! 213: private_imv_swima_state_t *this, TNC_ConnectionState new_state)
! 214: {
! 215: TNC_ConnectionState old_state;
! 216:
! 217: old_state = this->state;
! 218: this->state = new_state;
! 219: return old_state;
! 220: }
! 221:
! 222: METHOD(imv_state_t, get_recommendation, void,
! 223: private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation *rec,
! 224: TNC_IMV_Evaluation_Result *eval)
! 225: {
! 226: *rec = this->rec;
! 227: *eval = this->eval;
! 228: }
! 229:
! 230: METHOD(imv_state_t, set_recommendation, void,
! 231: private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation rec,
! 232: TNC_IMV_Evaluation_Result eval)
! 233: {
! 234: this->rec = rec;
! 235: this->eval = eval;
! 236: }
! 237:
! 238: METHOD(imv_state_t, update_recommendation, void,
! 239: private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation rec,
! 240: TNC_IMV_Evaluation_Result eval)
! 241: {
! 242: this->rec = tncif_policy_update_recommendation(this->rec, rec);
! 243: this->eval = tncif_policy_update_evaluation(this->eval, eval);
! 244: }
! 245:
! 246: METHOD(imv_state_t, get_reason_string, bool,
! 247: private_imv_swima_state_t *this, enumerator_t *language_enumerator,
! 248: chunk_t *reason_string, char **reason_language)
! 249: {
! 250: return FALSE;
! 251: }
! 252:
! 253: METHOD(imv_state_t, get_remediation_instructions, bool,
! 254: private_imv_swima_state_t *this, enumerator_t *language_enumerator,
! 255: chunk_t *string, char **lang_code, char **uri)
! 256: {
! 257: return FALSE;
! 258: }
! 259:
! 260: METHOD(imv_state_t, reset, void,
! 261: private_imv_swima_state_t *this)
! 262: {
! 263: this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
! 264: this->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
! 265:
! 266: this->action_flags = 0;
! 267:
! 268: this->handshake_state = IMV_SWIMA_STATE_INIT;
! 269: this->sw_id_count = 0;
! 270: this->tag_count = 0;
! 271: this->missing = 0;
! 272:
! 273: json_object_put(this->jobj);
! 274: this->jobj = json_object_new_object();
! 275: }
! 276:
! 277: METHOD(imv_state_t, destroy, void,
! 278: private_imv_swima_state_t *this)
! 279: {
! 280: json_object_put(this->jobj);
! 281: DESTROY_IF(this->session);
! 282: this->contracts->destroy(this->contracts);
! 283: free(this);
! 284: }
! 285:
! 286: METHOD(imv_swima_state_t, set_handshake_state, void,
! 287: private_imv_swima_state_t *this, imv_swima_handshake_state_t new_state)
! 288: {
! 289: this->handshake_state = new_state;
! 290: }
! 291:
! 292: METHOD(imv_swima_state_t, get_handshake_state, imv_swima_handshake_state_t,
! 293: private_imv_swima_state_t *this)
! 294: {
! 295: return this->handshake_state;
! 296: }
! 297:
! 298: METHOD(imv_swima_state_t, set_request_id, void,
! 299: private_imv_swima_state_t *this, uint32_t request_id)
! 300: {
! 301: this->request_id = request_id;
! 302: }
! 303:
! 304: METHOD(imv_swima_state_t, get_request_id, uint32_t,
! 305: private_imv_swima_state_t *this)
! 306: {
! 307: return this->request_id;
! 308: }
! 309:
! 310: METHOD(imv_swima_state_t, set_inventory, void,
! 311: private_imv_swima_state_t *this, swima_inventory_t *inventory)
! 312: {
! 313: chunk_t sw_id, sw_locator;
! 314: uint32_t record_id;
! 315: char *sw_id_str;
! 316: json_object *jstring;
! 317: swima_record_t *sw_record;
! 318: enumerator_t *enumerator;
! 319:
! 320: if (this->sw_id_count == 0)
! 321: {
! 322: this->jarray = json_object_new_array();
! 323: json_object_object_add(this->jobj, "data", this->jarray);
! 324: }
! 325:
! 326: enumerator = inventory->create_enumerator(inventory);
! 327: while (enumerator->enumerate(enumerator, &sw_record))
! 328: {
! 329: record_id = sw_record->get_record_id(sw_record);
! 330: sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
! 331: sw_id_str = strndup(sw_id.ptr, sw_id.len);
! 332: if (sw_locator.len)
! 333: {
! 334: DBG3(DBG_IMV, "%6u: %s @ %.*s", record_id, sw_id_str,
! 335: sw_locator.len, sw_locator.ptr);
! 336: }
! 337: else
! 338: {
! 339: DBG3(DBG_IMV, "%6u: %s", record_id, sw_id_str);
! 340: }
! 341:
! 342: /* Add software identity to JSON array */
! 343: jstring = json_object_new_string(sw_id_str);
! 344: json_object_array_add(this->jarray, jstring);
! 345: free(sw_id_str);
! 346: }
! 347: enumerator->destroy(enumerator);
! 348: }
! 349:
! 350: METHOD(imv_swima_state_t, set_events, void,
! 351: private_imv_swima_state_t *this, swima_events_t *events)
! 352: {
! 353: chunk_t sw_id, timestamp;
! 354: uint32_t record_id, eid, last_eid, epoch, source_id, action;
! 355: char *sw_id_str, *timestamp_str;
! 356: json_object *jevent, *jvalue, *jstring;
! 357: swima_event_t *sw_event;
! 358: swima_record_t *sw_record;
! 359: enumerator_t *enumerator;
! 360:
! 361: if (this->sw_id_count == 0)
! 362: {
! 363: last_eid = events->get_eid(events, &epoch, NULL);
! 364: jvalue = json_object_new_int(epoch);
! 365: json_object_object_add(this->jobj, "epoch", jvalue);
! 366: jvalue = json_object_new_int(last_eid);
! 367: json_object_object_add(this->jobj, "lastEid", jvalue);
! 368: this->jarray = json_object_new_array();
! 369: json_object_object_add(this->jobj, "events", this->jarray);
! 370: }
! 371:
! 372: enumerator = events->create_enumerator(events);
! 373: while (enumerator->enumerate(enumerator, &sw_event))
! 374: {
! 375: eid = sw_event->get_eid(sw_event, ×tamp);
! 376: timestamp_str = strndup(timestamp.ptr, timestamp.len);
! 377: action = sw_event->get_action(sw_event);
! 378: sw_record = sw_event->get_sw_record(sw_event);
! 379: record_id = sw_record->get_record_id(sw_record);
! 380: source_id = sw_record->get_source_id(sw_record);
! 381: sw_id = sw_record->get_sw_id(sw_record, NULL);
! 382: sw_id_str = strndup(sw_id.ptr, sw_id.len);
! 383: DBG3(DBG_IMV, "%3u %.*s %u %5u: %s", eid, timestamp.len, timestamp.ptr,
! 384: action, record_id, sw_id_str);
! 385:
! 386: /* Add software event to JSON array */
! 387: jevent = json_object_new_object();
! 388: jvalue = json_object_new_int(eid);
! 389: json_object_object_add(jevent, "eid", jvalue);
! 390: jstring = json_object_new_string(timestamp_str);
! 391: json_object_object_add(jevent, "timestamp", jstring);
! 392: jvalue = json_object_new_int(record_id);
! 393: json_object_object_add(jevent, "recordId", jvalue);
! 394: jvalue = json_object_new_int(source_id);
! 395: json_object_object_add(jevent, "sourceId", jvalue);
! 396: jvalue = json_object_new_int(action);
! 397: json_object_object_add(jevent, "action", jvalue);
! 398: jstring = json_object_new_string(sw_id_str);
! 399: json_object_object_add(jevent, "softwareId", jstring);
! 400: json_object_array_add(this->jarray, jevent);
! 401: free(timestamp_str);
! 402: free(sw_id_str);
! 403: }
! 404: enumerator->destroy(enumerator);
! 405: }
! 406:
! 407: METHOD(imv_swima_state_t, get_jrequest, json_object*,
! 408: private_imv_swima_state_t *this)
! 409: {
! 410: return this->jobj;
! 411: }
! 412:
! 413: METHOD(imv_swima_state_t, set_missing, void,
! 414: private_imv_swima_state_t *this, uint32_t count)
! 415: {
! 416: this->missing = count;
! 417: }
! 418:
! 419: METHOD(imv_swima_state_t, get_missing, uint32_t,
! 420: private_imv_swima_state_t *this)
! 421: {
! 422: return this->missing;
! 423: }
! 424:
! 425: METHOD(imv_swima_state_t, set_count, void,
! 426: private_imv_swima_state_t *this, int sw_id_count, int tag_count,
! 427: TNC_UInt32 imc_id)
! 428: {
! 429: this->sw_id_count += sw_id_count;
! 430: this->tag_count += tag_count;
! 431: this->imc_id = imc_id;
! 432: }
! 433:
! 434: METHOD(imv_swima_state_t, get_count, void,
! 435: private_imv_swima_state_t *this, int *sw_id_count, int *tag_count)
! 436: {
! 437: if (sw_id_count)
! 438: {
! 439: *sw_id_count = this->sw_id_count;
! 440: }
! 441: if (tag_count)
! 442: {
! 443: *tag_count = this->tag_count;
! 444: }
! 445: }
! 446:
! 447: METHOD(imv_swima_state_t, get_imc_id, TNC_UInt32,
! 448: private_imv_swima_state_t *this)
! 449: {
! 450: return this->imc_id;
! 451: }
! 452:
! 453: METHOD(imv_swima_state_t, set_subscription, void,
! 454: private_imv_swima_state_t *this, bool set)
! 455: {
! 456: this->has_subscription = set;
! 457: }
! 458:
! 459: METHOD(imv_swima_state_t, get_subscription, bool,
! 460: private_imv_swima_state_t *this)
! 461: {
! 462: return this->has_subscription;
! 463: }
! 464:
! 465: /**
! 466: * Described in header.
! 467: */
! 468: imv_state_t *imv_swima_state_create(TNC_ConnectionID connection_id)
! 469: {
! 470: private_imv_swima_state_t *this;
! 471:
! 472: INIT(this,
! 473: .public = {
! 474: .interface = {
! 475: .get_connection_id = _get_connection_id,
! 476: .has_long = _has_long,
! 477: .has_excl = _has_excl,
! 478: .set_flags = _set_flags,
! 479: .set_max_msg_len = _set_max_msg_len,
! 480: .get_max_msg_len = _get_max_msg_len,
! 481: .set_action_flags = _set_action_flags,
! 482: .get_action_flags = _get_action_flags,
! 483: .set_session = _set_session,
! 484: .get_session= _get_session,
! 485: .get_contracts = _get_contracts,
! 486: .change_state = _change_state,
! 487: .get_recommendation = _get_recommendation,
! 488: .set_recommendation = _set_recommendation,
! 489: .update_recommendation = _update_recommendation,
! 490: .get_reason_string = _get_reason_string,
! 491: .get_remediation_instructions = _get_remediation_instructions,
! 492: .reset = _reset,
! 493: .destroy = _destroy,
! 494: },
! 495: .set_handshake_state = _set_handshake_state,
! 496: .get_handshake_state = _get_handshake_state,
! 497: .set_request_id = _set_request_id,
! 498: .get_request_id = _get_request_id,
! 499: .set_inventory = _set_inventory,
! 500: .set_events = _set_events,
! 501: .get_jrequest = _get_jrequest,
! 502: .set_missing = _set_missing,
! 503: .get_missing = _get_missing,
! 504: .set_count = _set_count,
! 505: .get_count = _get_count,
! 506: .get_imc_id = _get_imc_id,
! 507: .set_subscription = _set_subscription,
! 508: .get_subscription = _get_subscription,
! 509: },
! 510: .state = TNC_CONNECTION_STATE_CREATE,
! 511: .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
! 512: .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
! 513: .connection_id = connection_id,
! 514: .contracts = seg_contract_manager_create(),
! 515: .imc_id = TNC_IMCID_ANY,
! 516: .jobj = json_object_new_object(),
! 517: );
! 518:
! 519: return &this->public.interface;
! 520: }
! 521:
! 522:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>