Annotation of embedaddon/strongswan/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.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 "ietf_swima_attr_sw_inv.h"
! 17: #include "swima/swima_record.h"
! 18:
! 19: #include <pa_tnc/pa_tnc_msg.h>
! 20: #include <bio/bio_writer.h>
! 21: #include <bio/bio_reader.h>
! 22: #include <utils/debug.h>
! 23:
! 24:
! 25: typedef struct private_ietf_swima_attr_sw_inv_t private_ietf_swima_attr_sw_inv_t;
! 26:
! 27: /**
! 28: * Software [Identifier] Inventory
! 29: * see sections 5.8/5.10 of RFC 8412 SWIMA
! 30: *
! 31: * 1 2 3
! 32: * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
! 33: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 34: * | Flags | Software Identifier Count |
! 35: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 36: * | Request ID Copy / Subscription ID |
! 37: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 38: * | EID Epoch |
! 39: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 40: * | Last EID |
! 41: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 42: * | Record Identifier |
! 43: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 44: * | Data Model Type PEN |Data Model Type|
! 45: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 46: * | Source ID Num | Reserved | Software Identifier Length |
! 47: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 48: * | Software Identifier (Variable Length) |
! 49: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 50: * | Software Locator Length | Software Locator (Var. Len) |
! 51: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 52: *
! 53: * Software Inventory only
! 54: * see section 5.10 of IETF SW Inventory Message and Attributes for PA-TNC
! 55: *
! 56: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 57: * | Record Length |
! 58: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 59: * | Record (Variable length) |
! 60: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! 61: */
! 62:
! 63: /**
! 64: * Private data of an ietf_swima_attr_sw_inv_t object.
! 65: */
! 66: struct private_ietf_swima_attr_sw_inv_t {
! 67:
! 68: /**
! 69: * Public members of ietf_swima_attr_sw_inv_t
! 70: */
! 71: ietf_swima_attr_sw_inv_t public;
! 72:
! 73: /**
! 74: * Vendor-specific attribute type
! 75: */
! 76: pen_type_t type;
! 77:
! 78: /**
! 79: * Length of attribute value
! 80: */
! 81: size_t length;
! 82:
! 83: /**
! 84: * Offset up to which attribute value has been processed
! 85: */
! 86: size_t offset;
! 87:
! 88: /**
! 89: * Current position of attribute value pointer
! 90: */
! 91: chunk_t value;
! 92:
! 93: /**
! 94: * Contains complete attribute or current segment
! 95: */
! 96: chunk_t segment;
! 97:
! 98: /**
! 99: * Noskip flag
! 100: */
! 101: bool noskip_flag;
! 102:
! 103: /**
! 104: * Request ID
! 105: */
! 106: uint32_t request_id;
! 107:
! 108: /**
! 109: * Attribute flags
! 110: */
! 111: uint8_t flags;
! 112:
! 113: /**
! 114: * Number of unprocessed software inventory evidence records in attribute
! 115: */
! 116: uint32_t record_count;
! 117:
! 118: /**
! 119: * SWID Tag ID Inventory
! 120: */
! 121: swima_inventory_t *inventory;
! 122:
! 123: /**
! 124: * Reference count
! 125: */
! 126: refcount_t ref;
! 127: };
! 128:
! 129: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
! 130: private_ietf_swima_attr_sw_inv_t *this)
! 131: {
! 132: return this->type;
! 133: }
! 134:
! 135: METHOD(pa_tnc_attr_t, get_value, chunk_t,
! 136: private_ietf_swima_attr_sw_inv_t *this)
! 137: {
! 138: return this->value;
! 139: }
! 140:
! 141: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
! 142: private_ietf_swima_attr_sw_inv_t *this)
! 143: {
! 144: return this->noskip_flag;
! 145: }
! 146:
! 147: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
! 148: private_ietf_swima_attr_sw_inv_t *this, bool noskip)
! 149: {
! 150: this->noskip_flag = noskip;
! 151: }
! 152:
! 153: /**
! 154: * This function is shared with ietf_swima_attr_sw_ev.c
! 155: **/
! 156: extern void ietf_swima_attr_sw_ev_build_sw_record(bio_writer_t *writer,
! 157: uint8_t action, swima_record_t *sw_record, bool has_record);
! 158:
! 159: METHOD(pa_tnc_attr_t, build, void,
! 160: private_ietf_swima_attr_sw_inv_t *this)
! 161: {
! 162: bio_writer_t *writer;
! 163: swima_record_t *sw_record;
! 164: uint32_t last_eid, eid_epoch;
! 165: enumerator_t *enumerator;
! 166:
! 167: if (this->value.ptr)
! 168: {
! 169: return;
! 170: }
! 171: last_eid = this->inventory->get_eid(this->inventory, &eid_epoch);
! 172:
! 173: writer = bio_writer_create(IETF_SWIMA_SW_INV_MIN_SIZE);
! 174: writer->write_uint8 (writer, this->flags);
! 175: writer->write_uint24(writer, this->inventory->get_count(this->inventory));
! 176: writer->write_uint32(writer, this->request_id);
! 177: writer->write_uint32(writer, eid_epoch);
! 178: writer->write_uint32(writer, last_eid);
! 179:
! 180: enumerator = this->inventory->create_enumerator(this->inventory);
! 181: while (enumerator->enumerate(enumerator, &sw_record))
! 182: {
! 183: ietf_swima_attr_sw_ev_build_sw_record(writer, 0x00, sw_record,
! 184: this->type.type == IETF_ATTR_SW_INVENTORY);
! 185: }
! 186: enumerator->destroy(enumerator);
! 187:
! 188: this->value = writer->extract_buf(writer);
! 189: this->segment = this->value;
! 190: this->length = this->value.len;
! 191: writer->destroy(writer);
! 192: }
! 193:
! 194: /**
! 195: * This function is shared with ietf_swima_attr_sw_ev.c
! 196: **/
! 197: extern bool ietf_swima_attr_sw_ev_process_sw_record(bio_reader_t *reader,
! 198: uint8_t *action, swima_record_t **sw_record, bool has_record);
! 199:
! 200: METHOD(pa_tnc_attr_t, process, status_t,
! 201: private_ietf_swima_attr_sw_inv_t *this, uint32_t *offset)
! 202: {
! 203: bio_reader_t *reader;
! 204: uint32_t last_eid, eid_epoch;
! 205: swima_record_t *sw_record;
! 206: status_t status = NEED_MORE;
! 207:
! 208: if (this->offset == 0)
! 209: {
! 210: if (this->length < IETF_SWIMA_SW_INV_MIN_SIZE)
! 211: {
! 212: DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
! 213: ietf_attr_names, this->type.type);
! 214: *offset = this->offset;
! 215: return FAILED;
! 216: }
! 217: if (this->value.len < IETF_SWIMA_SW_INV_MIN_SIZE)
! 218: {
! 219: return NEED_MORE;
! 220: }
! 221: reader = bio_reader_create(this->value);
! 222: reader->read_uint8 (reader, &this->flags);
! 223: reader->read_uint24(reader, &this->record_count);
! 224: reader->read_uint32(reader, &this->request_id);
! 225: reader->read_uint32(reader, &eid_epoch);
! 226: reader->read_uint32(reader, &last_eid);
! 227: this->offset = IETF_SWIMA_SW_INV_MIN_SIZE;
! 228: this->value = reader->peek(reader);
! 229: this->inventory->set_eid(this->inventory, last_eid, eid_epoch);
! 230: reader->destroy(reader);
! 231: }
! 232:
! 233: reader = bio_reader_create(this->value);
! 234:
! 235: while (this->record_count)
! 236: {
! 237: if (!ietf_swima_attr_sw_ev_process_sw_record(reader, NULL, &sw_record,
! 238: this->type.type == IETF_ATTR_SW_INVENTORY))
! 239: {
! 240: goto end;
! 241: }
! 242:
! 243: this->inventory->add(this->inventory, sw_record);
! 244: this->offset += this->value.len - reader->remaining(reader);
! 245: this->value = reader->peek(reader);
! 246:
! 247: /* at least one software inventory evidence record was processed */
! 248: status = SUCCESS;
! 249: this->record_count--;
! 250: }
! 251:
! 252: if (this->length == this->offset)
! 253: {
! 254: status = SUCCESS;
! 255: }
! 256: else
! 257: {
! 258: DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF,
! 259: ietf_attr_names, this->type.type);
! 260: *offset = this->offset;
! 261: status = FAILED;
! 262: }
! 263:
! 264: end:
! 265: reader->destroy(reader);
! 266: return status;
! 267: }
! 268:
! 269: METHOD(pa_tnc_attr_t, add_segment, void,
! 270: private_ietf_swima_attr_sw_inv_t *this, chunk_t segment)
! 271: {
! 272: this->value = chunk_cat("cc", this->value, segment);
! 273: chunk_free(&this->segment);
! 274: this->segment = this->value;
! 275: }
! 276:
! 277: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
! 278: private_ietf_swima_attr_sw_inv_t *this)
! 279: {
! 280: ref_get(&this->ref);
! 281: return &this->public.pa_tnc_attribute;
! 282: }
! 283:
! 284: METHOD(pa_tnc_attr_t, destroy, void,
! 285: private_ietf_swima_attr_sw_inv_t *this)
! 286: {
! 287: if (ref_put(&this->ref))
! 288: {
! 289: this->inventory->destroy(this->inventory);
! 290: free(this->segment.ptr);
! 291: free(this);
! 292: }
! 293: }
! 294:
! 295: METHOD(ietf_swima_attr_sw_inv_t, get_flags, uint8_t,
! 296: private_ietf_swima_attr_sw_inv_t *this)
! 297: {
! 298: return this->flags;
! 299: }
! 300:
! 301: METHOD(ietf_swima_attr_sw_inv_t, get_request_id, uint32_t,
! 302: private_ietf_swima_attr_sw_inv_t *this)
! 303: {
! 304: return this->request_id;
! 305: }
! 306:
! 307: METHOD(ietf_swima_attr_sw_inv_t, get_record_count, uint32_t,
! 308: private_ietf_swima_attr_sw_inv_t *this)
! 309: {
! 310: return this->record_count;
! 311: }
! 312:
! 313: METHOD(ietf_swima_attr_sw_inv_t, set_inventory, void,
! 314: private_ietf_swima_attr_sw_inv_t *this, swima_inventory_t *inventory)
! 315: {
! 316: this->inventory->destroy(this->inventory);
! 317: this->inventory = inventory->get_ref(inventory);
! 318: }
! 319:
! 320: METHOD(ietf_swima_attr_sw_inv_t, get_inventory, swima_inventory_t*,
! 321: private_ietf_swima_attr_sw_inv_t *this)
! 322: {
! 323: return this->inventory;
! 324: }
! 325:
! 326: METHOD(ietf_swima_attr_sw_inv_t, clear_inventory, void,
! 327: private_ietf_swima_attr_sw_inv_t *this)
! 328: {
! 329: this->inventory->clear(this->inventory);
! 330: }
! 331:
! 332: /**
! 333: * Described in header.
! 334: */
! 335: pa_tnc_attr_t *ietf_swima_attr_sw_inv_create(uint8_t flags, uint32_t request_id,
! 336: bool sw_id_only)
! 337: {
! 338: private_ietf_swima_attr_sw_inv_t *this;
! 339: ietf_attr_t type;
! 340:
! 341: type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
! 342:
! 343: INIT(this,
! 344: .public = {
! 345: .pa_tnc_attribute = {
! 346: .get_type = _get_type,
! 347: .get_value = _get_value,
! 348: .get_noskip_flag = _get_noskip_flag,
! 349: .set_noskip_flag = _set_noskip_flag,
! 350: .build = _build,
! 351: .process = _process,
! 352: .add_segment = _add_segment,
! 353: .get_ref = _get_ref,
! 354: .destroy = _destroy,
! 355: },
! 356: .get_flags = _get_flags,
! 357: .get_request_id = _get_request_id,
! 358: .get_record_count = _get_record_count,
! 359: .set_inventory = _set_inventory,
! 360: .get_inventory = _get_inventory,
! 361: .clear_inventory = _clear_inventory,
! 362: },
! 363: .type = { PEN_IETF, type },
! 364: .flags = flags,
! 365: .request_id = request_id,
! 366: .inventory = swima_inventory_create(),
! 367: .ref = 1,
! 368: );
! 369:
! 370: return &this->public.pa_tnc_attribute;
! 371: }
! 372:
! 373:
! 374: /**
! 375: * Described in header.
! 376: */
! 377: pa_tnc_attr_t *ietf_swima_attr_sw_inv_create_from_data(size_t length,
! 378: chunk_t data, bool sw_id_only)
! 379: {
! 380: private_ietf_swima_attr_sw_inv_t *this;
! 381: ietf_attr_t type;
! 382:
! 383: type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
! 384:
! 385: INIT(this,
! 386: .public = {
! 387: .pa_tnc_attribute = {
! 388: .get_type = _get_type,
! 389: .get_value = _get_value,
! 390: .get_noskip_flag = _get_noskip_flag,
! 391: .set_noskip_flag = _set_noskip_flag,
! 392: .build = _build,
! 393: .process = _process,
! 394: .add_segment = _add_segment,
! 395: .get_ref = _get_ref,
! 396: .destroy = _destroy,
! 397: },
! 398: .get_flags = _get_flags,
! 399: .get_request_id = _get_request_id,
! 400: .get_record_count = _get_record_count,
! 401: .set_inventory = _set_inventory,
! 402: .get_inventory = _get_inventory,
! 403: .clear_inventory = _clear_inventory,
! 404: },
! 405: .type = { PEN_IETF, type },
! 406: .length = length,
! 407: .segment = chunk_clone(data),
! 408: .inventory = swima_inventory_create(),
! 409: .ref = 1,
! 410: );
! 411:
! 412: /* received either complete attribute value or first segment */
! 413: this->value = this->segment;
! 414:
! 415: return &this->public.pa_tnc_attribute;
! 416: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>