mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
libimcv: Implemented IETF SW PA-TNC attributes
This commit is contained in:
parent
bb87af2a73
commit
84c0366bd3
@ -2,7 +2,8 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtpmtss \
|
||||
-DIPSEC_SCRIPT=\"${ipsec_script}\"
|
||||
-DIPSEC_SCRIPT=\"${ipsec_script}\" \
|
||||
-DSWID_DIRECTORY=\"${prefix}/share\"
|
||||
|
||||
ipseclib_LTLIBRARIES = libimcv.la
|
||||
|
||||
@ -49,6 +50,9 @@ libimcv_la_SOURCES = \
|
||||
ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
|
||||
ietf/ietf_attr_remediation_instr.h ietf/ietf_attr_remediation_instr.c \
|
||||
ietf/ietf_attr_string_version.h ietf/ietf_attr_string_version.c \
|
||||
ietf/swima/ietf_swima_attr_req.h ietf/swima/ietf_swima_attr_req.c \
|
||||
ietf/swima/ietf_swima_attr_sw_inv.h ietf/swima/ietf_swima_attr_sw_inv.c \
|
||||
ietf/swima/ietf_swima_attr_sw_ev.h ietf/swima/ietf_swima_attr_sw_ev.c \
|
||||
ita/ita_attr.h ita/ita_attr.c \
|
||||
ita/ita_attr_command.h ita/ita_attr_command.c \
|
||||
ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
|
||||
@ -91,6 +95,13 @@ libimcv_la_SOURCES = \
|
||||
swid/swid_inventory.h swid/swid_inventory.c \
|
||||
swid/swid_tag.h swid/swid_tag.c \
|
||||
swid/swid_tag_id.h swid/swid_tag_id.c \
|
||||
swima/swima_data_model.h swima/swima_data_model.c \
|
||||
swima/swima_record.h swima/swima_record.c \
|
||||
swima/swima_event.h swima/swima_event.c \
|
||||
swima/swima_events.h swima/swima_events.c \
|
||||
swima/swima_inventory.h swima/swima_inventory.c \
|
||||
swima/swima_collector.h swima/swima_collector.c \
|
||||
swima/swima_error.h swima/swima_error.c \
|
||||
tcg/tcg_attr.h tcg/tcg_attr.c \
|
||||
tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \
|
||||
tcg/pts/tcg_pts_attr_dh_nonce_params_req.h tcg/pts/tcg_pts_attr_dh_nonce_params_req.c \
|
||||
@ -192,6 +203,8 @@ imcv_tests_SOURCES = \
|
||||
seg/seg_contract_manager.c \
|
||||
suites/test_imcv_seg.c \
|
||||
ietf/ietf_attr_pa_tnc_error.c \
|
||||
ietf/swima/ietf_swima_attr_req.c \
|
||||
ietf/swima/ietf_swima_attr_sw_inv.c \
|
||||
tcg/seg/tcg_seg_attr_seg_env.c \
|
||||
imcv.c imcv_tests.h imcv_tests.c
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "ietf/ietf_attr_product_info.h"
|
||||
#include "ietf/ietf_attr_remediation_instr.h"
|
||||
#include "ietf/ietf_attr_string_version.h"
|
||||
#include "ietf/swima/ietf_swima_attr_req.h"
|
||||
#include "ietf/swima/ietf_swima_attr_sw_inv.h"
|
||||
#include "ietf/swima/ietf_swima_attr_sw_ev.h"
|
||||
#include "generic/generic_attr_bool.h"
|
||||
|
||||
|
||||
@ -94,14 +97,19 @@ pa_tnc_attr_t* ietf_attr_create_from_data(uint32_t type, size_t length,
|
||||
case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
|
||||
return generic_attr_bool_create_from_data(length, value,
|
||||
pen_type_create(PEN_IETF, type));
|
||||
case IETF_ATTR_SW_REQUEST:
|
||||
return ietf_swima_attr_req_create_from_data(length, value);
|
||||
case IETF_ATTR_SW_ID_INVENTORY:
|
||||
return ietf_swima_attr_sw_inv_create_from_data(length, value, TRUE);
|
||||
case IETF_ATTR_SW_INVENTORY:
|
||||
return ietf_swima_attr_sw_inv_create_from_data(length, value, FALSE);
|
||||
case IETF_ATTR_SW_ID_EVENTS:
|
||||
return ietf_swima_attr_sw_ev_create_from_data(length, value, TRUE);
|
||||
case IETF_ATTR_SW_EVENTS:
|
||||
return ietf_swima_attr_sw_ev_create_from_data(length, value, FALSE);
|
||||
case IETF_ATTR_TESTING:
|
||||
case IETF_ATTR_RESERVED:
|
||||
/* unsupported IETF/SWIMA attributes */
|
||||
case IETF_ATTR_SW_REQUEST:
|
||||
case IETF_ATTR_SW_ID_INVENTORY:
|
||||
case IETF_ATTR_SW_ID_EVENTS:
|
||||
case IETF_ATTR_SW_INVENTORY:
|
||||
case IETF_ATTR_SW_EVENTS:
|
||||
case IETF_ATTR_SUBSCRIPTION_STATUS_REQ:
|
||||
case IETF_ATTR_SUBSCRIPTION_STATUS_RESP:
|
||||
case IETF_ATTR_SRC_METADATA_REQ:
|
||||
|
@ -256,7 +256,8 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
||||
reader->read_uint24(reader, &this->error_code.vendor_id);
|
||||
reader->read_uint32(reader, &this->error_code.type);
|
||||
|
||||
if (this->error_code.vendor_id == PEN_IETF)
|
||||
if (this->error_code.vendor_id == PEN_IETF &&
|
||||
this->error_code.type <= PA_ERROR_PA_TNC_MSG_ROOF)
|
||||
{
|
||||
if (!reader->read_data(reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info))
|
||||
{
|
||||
@ -406,7 +407,8 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code,
|
||||
{
|
||||
private_ietf_attr_pa_tnc_error_t *this;
|
||||
|
||||
if (error_code.vendor_id == PEN_IETF)
|
||||
if (error_code.vendor_id == PEN_IETF &&
|
||||
error_code.type <= PA_ERROR_PA_TNC_MSG_ROOF)
|
||||
{
|
||||
msg_info.len = PA_ERROR_MSG_INFO_SIZE;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ enum pa_tnc_error_code_t {
|
||||
PA_ERROR_INVALID_PARAMETER = 1,
|
||||
PA_ERROR_VERSION_NOT_SUPPORTED = 2,
|
||||
PA_ERROR_ATTR_TYPE_NOT_SUPPORTED = 3,
|
||||
PA_ERROR_PA_TNC_MSG_ROOF = 3,
|
||||
|
||||
/* draft-ietf-sacm-nea-swid-patnc (SWIMA) */
|
||||
PA_ERROR_SW = 32,
|
||||
|
320
src/libimcv/ietf/swima/ietf_swima_attr_req.c
Normal file
320
src/libimcv/ietf/swima/ietf_swima_attr_req.c
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "ietf_swima_attr_req.h"
|
||||
#include "swima/swima_record.h"
|
||||
|
||||
#include <pa_tnc/pa_tnc_msg.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
typedef struct private_ietf_swima_attr_req_t private_ietf_swima_attr_req_t;
|
||||
|
||||
/**
|
||||
* SW Request
|
||||
* see section 5.7 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |C|S|R| Reserved| Software Identifier Count |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Request ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Earliest EID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Software Identifier Length | Software Identifier (Var Len) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define SW_REQ_RESERVED_MASK 0xE0
|
||||
|
||||
/**
|
||||
* Private data of an ietf_swima_attr_req_t object.
|
||||
*/
|
||||
struct private_ietf_swima_attr_req_t {
|
||||
|
||||
/**
|
||||
* Public members of ietf_swima_attr_req_t
|
||||
*/
|
||||
ietf_swima_attr_req_t public;
|
||||
|
||||
/**
|
||||
* Vendor-specific attribute type
|
||||
*/
|
||||
pen_type_t type;
|
||||
|
||||
/**
|
||||
* Length of attribute value
|
||||
*/
|
||||
size_t length;
|
||||
|
||||
/**
|
||||
* Attribute value or segment
|
||||
*/
|
||||
chunk_t value;
|
||||
|
||||
/**
|
||||
* Noskip flag
|
||||
*/
|
||||
bool noskip_flag;
|
||||
|
||||
/**
|
||||
* SWID request flags
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* Request ID
|
||||
*/
|
||||
uint32_t request_id;
|
||||
|
||||
/**
|
||||
* Inventory of Target Software Identifiers
|
||||
*/
|
||||
swima_inventory_t *targets;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->noskip_flag;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||
private_ietf_swima_attr_req_t *this, bool noskip)
|
||||
{
|
||||
this->noskip_flag = noskip;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, build, void,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
swima_record_t *sw_record;
|
||||
uint32_t earliest_eid;
|
||||
chunk_t sw_id;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
if (this->value.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
earliest_eid = this->targets->get_eid(this->targets, NULL);
|
||||
|
||||
writer = bio_writer_create(IETF_SWIMA_REQ_MIN_SIZE);
|
||||
writer->write_uint8 (writer, this->flags);
|
||||
writer->write_uint24(writer, this->targets->get_count(this->targets));
|
||||
writer->write_uint32(writer, this->request_id);
|
||||
writer->write_uint32(writer, earliest_eid);
|
||||
|
||||
enumerator = this->targets->create_enumerator(this->targets);
|
||||
while (enumerator->enumerate(enumerator, &sw_record))
|
||||
{
|
||||
sw_id = sw_record->get_sw_id(sw_record, NULL);
|
||||
writer->write_data16(writer, sw_id);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->value = writer->extract_buf(writer);
|
||||
this->length = this->value.len;
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, process, status_t,
|
||||
private_ietf_swima_attr_req_t *this, uint32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
swima_record_t *sw_record;
|
||||
uint32_t sw_id_count, earliest_eid;
|
||||
chunk_t sw_id;
|
||||
|
||||
*offset = 0;
|
||||
|
||||
if (this->value.len < this->length)
|
||||
{
|
||||
return NEED_MORE;
|
||||
}
|
||||
if (this->value.len < IETF_SWIMA_REQ_MIN_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for SW Request");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
reader = bio_reader_create(this->value);
|
||||
reader->read_uint8 (reader, &this->flags);
|
||||
reader->read_uint24(reader, &sw_id_count);
|
||||
reader->read_uint32(reader, &this->request_id);
|
||||
reader->read_uint32(reader, &earliest_eid);
|
||||
|
||||
*offset = IETF_SWIMA_REQ_MIN_SIZE;
|
||||
this->flags &= SW_REQ_RESERVED_MASK;
|
||||
this->targets->set_eid(this->targets, earliest_eid, 0);
|
||||
|
||||
while (sw_id_count--)
|
||||
{
|
||||
if (!reader->read_data16(reader, &sw_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for Software ID");
|
||||
reader->destroy(reader);
|
||||
return FAILED;
|
||||
}
|
||||
*offset += 2 + sw_id.len;
|
||||
|
||||
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
||||
this->targets->add(this->targets, sw_record);
|
||||
}
|
||||
reader->destroy(reader);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||
private_ietf_swima_attr_req_t *this, chunk_t segment)
|
||||
{
|
||||
this->value = chunk_cat("mc", this->value, segment);
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, destroy, void,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->targets->destroy(this->targets);
|
||||
free(this->value.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_req_t, get_flags, uint8_t,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->flags;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_req_t, get_request_id, uint32_t,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->request_id;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_req_t, set_targets, void,
|
||||
private_ietf_swima_attr_req_t *this, swima_inventory_t *targets)
|
||||
{
|
||||
this->targets->destroy(this->targets);
|
||||
this->targets = targets->get_ref(targets);
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_req_t, get_targets, swima_inventory_t*,
|
||||
private_ietf_swima_attr_req_t *this)
|
||||
{
|
||||
return this->targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_req_create(uint8_t flags, uint32_t request_id)
|
||||
{
|
||||
private_ietf_swima_attr_req_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.set_targets = _set_targets,
|
||||
.get_targets = _get_targets,
|
||||
},
|
||||
.type = { PEN_IETF, IETF_ATTR_SW_REQUEST },
|
||||
.flags = flags & SW_REQ_RESERVED_MASK,
|
||||
.request_id = request_id,
|
||||
.targets = swima_inventory_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_req_create_from_data(size_t length, chunk_t data)
|
||||
{
|
||||
private_ietf_swima_attr_req_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.set_targets = _set_targets,
|
||||
.get_targets = _get_targets,
|
||||
},
|
||||
.type = { PEN_IETF, IETF_ATTR_SW_REQUEST },
|
||||
.length = length,
|
||||
.value = chunk_clone(data),
|
||||
.targets = swima_inventory_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
96
src/libimcv/ietf/swima/ietf_swima_attr_req.h
Normal file
96
src/libimcv/ietf/swima/ietf_swima_attr_req.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ietf_swima_attr_req ietf_swima_attr_req
|
||||
* @{ @ingroup ietf_attr
|
||||
*/
|
||||
|
||||
#ifndef IETF_SWIMA_ATTR_REQ_H_
|
||||
#define IETF_SWIMA_ATTR_REQ_H_
|
||||
|
||||
#define IETF_SWIMA_REQ_MIN_SIZE 12
|
||||
|
||||
typedef struct ietf_swima_attr_req_t ietf_swima_attr_req_t;
|
||||
typedef enum ietf_swima_attr_req_flag_t ietf_swima_attr_req_flag_t;
|
||||
|
||||
enum ietf_swima_attr_req_flag_t {
|
||||
IETF_SWIMA_ATTR_REQ_FLAG_NONE = 0,
|
||||
IETF_SWIMA_ATTR_REQ_FLAG_C = (1 << 7),
|
||||
IETF_SWIMA_ATTR_REQ_FLAG_S = (1 << 6),
|
||||
IETF_SWIMA_ATTR_REQ_FLAG_R = (1 << 5)
|
||||
};
|
||||
|
||||
#include "swima/swima_inventory.h"
|
||||
#include "ietf/ietf_attr.h"
|
||||
#include "pa_tnc/pa_tnc_attr.h"
|
||||
|
||||
/**
|
||||
* Class implementing the IETF SW Request attribute
|
||||
*/
|
||||
struct ietf_swima_attr_req_t {
|
||||
|
||||
/**
|
||||
* Public PA-TNC attribute interface
|
||||
*/
|
||||
pa_tnc_attr_t pa_tnc_attribute;
|
||||
|
||||
/**
|
||||
* Get SW request flags
|
||||
*
|
||||
* @return Flags
|
||||
*/
|
||||
uint8_t (*get_flags)(ietf_swima_attr_req_t *this);
|
||||
|
||||
/**
|
||||
* Get Request ID
|
||||
*
|
||||
* @return Request ID
|
||||
*/
|
||||
uint32_t (*get_request_id)(ietf_swima_attr_req_t *this);
|
||||
|
||||
/**
|
||||
* Set Software Identity targets
|
||||
*
|
||||
* @param targets SW ID inventory containing targets (not cloned)
|
||||
*/
|
||||
void (*set_targets)(ietf_swima_attr_req_t *this, swima_inventory_t *targets);
|
||||
|
||||
/**
|
||||
* Get Software Identity targets
|
||||
*
|
||||
* @return SW ID inventory containing targets
|
||||
*/
|
||||
swima_inventory_t* (*get_targets)(ietf_swima_attr_req_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_req_t object
|
||||
*
|
||||
* @param flags Sets the C|S|R flags
|
||||
* @param request_id Request ID
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_req_create(uint8_t flags, uint32_t request_id);
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_req_t object from received data
|
||||
*
|
||||
* @param length Total length of attribute value
|
||||
* @param value Unparsed attribute value (might be a segment)
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_req_create_from_data(size_t length, chunk_t value);
|
||||
|
||||
#endif /** IETF_SWIMA_ATTR_REQ_H_ @}*/
|
482
src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
Normal file
482
src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
Normal file
@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "ietf_swima_attr_sw_ev.h"
|
||||
#include "swima/swima_event.h"
|
||||
|
||||
#include <pa_tnc/pa_tnc_msg.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#define SW_EV_TIMESTAMP_SIZE 20
|
||||
|
||||
typedef struct private_ietf_swima_attr_sw_ev_t private_ietf_swima_attr_sw_ev_t;
|
||||
|
||||
/**
|
||||
* Software [Identifier] Events
|
||||
* see sections 5.9/5.11 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Flags | Software Identifier Count |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Request ID Copy / Subscription ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | EID Epoch |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Last EID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Last Consulted EID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | EID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Timestamp |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Timestamp |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Timestamp |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Timestamp |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Timestamp |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record Identifier |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Data Model Type PEN |Data Model Type|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Source ID Num | Action | Software Identifier Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Software Identifier (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Software Locator Length | Software Locator (Var. Len) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* Software Event only
|
||||
* see section 5.11 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record (Variable length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private data of an ietf_swima_attr_sw_ev_t object.
|
||||
*/
|
||||
struct private_ietf_swima_attr_sw_ev_t {
|
||||
|
||||
/**
|
||||
* Public members of ietf_swima_attr_sw_ev_t
|
||||
*/
|
||||
ietf_swima_attr_sw_ev_t public;
|
||||
|
||||
/**
|
||||
* Vendor-specific attribute type
|
||||
*/
|
||||
pen_type_t type;
|
||||
|
||||
/**
|
||||
* Length of attribute value
|
||||
*/
|
||||
size_t length;
|
||||
|
||||
/**
|
||||
* Offset up to which attribute value has been processed
|
||||
*/
|
||||
size_t offset;
|
||||
|
||||
/**
|
||||
* Current position of attribute value pointer
|
||||
*/
|
||||
chunk_t value;
|
||||
|
||||
/**
|
||||
* Contains complete attribute or current segment
|
||||
*/
|
||||
chunk_t segment;
|
||||
|
||||
/**
|
||||
* Noskip flag
|
||||
*/
|
||||
bool noskip_flag;
|
||||
|
||||
/**
|
||||
* Request ID
|
||||
*/
|
||||
uint32_t request_id;
|
||||
|
||||
/**
|
||||
* Attribute flags
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* Number of unprocessed software events in attribute
|
||||
*/
|
||||
uint32_t event_count;
|
||||
|
||||
/**
|
||||
* Event list
|
||||
*/
|
||||
swima_events_t *events;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->noskip_flag;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||
private_ietf_swima_attr_sw_ev_t *this, bool noskip)
|
||||
{
|
||||
this->noskip_flag = noskip;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, build, void,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
swima_event_t *sw_event;
|
||||
swima_record_t *sw_record;
|
||||
chunk_t timestamp, sw_id, sw_locator, record;
|
||||
pen_type_t data_model;
|
||||
uint32_t eid, record_id, last_eid, last_consulted_eid, eid_epoch;
|
||||
uint8_t action, source_id;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
if (this->value.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
last_consulted_eid = this->events->get_eid(this->events, &eid_epoch,
|
||||
&last_eid);
|
||||
|
||||
writer = bio_writer_create(IETF_SWIMA_SW_EV_MIN_SIZE);
|
||||
writer->write_uint8 (writer, this->flags);
|
||||
writer->write_uint24(writer, this->events->get_count(this->events));
|
||||
writer->write_uint32(writer, this->request_id);
|
||||
writer->write_uint32(writer, eid_epoch);
|
||||
writer->write_uint32(writer, last_eid);
|
||||
writer->write_uint32(writer, last_consulted_eid);
|
||||
|
||||
enumerator = this->events->create_enumerator(this->events);
|
||||
while (enumerator->enumerate(enumerator, &sw_event))
|
||||
{
|
||||
eid = sw_event->get_eid(sw_event, ×tamp);
|
||||
action = sw_event->get_action(sw_event);
|
||||
sw_record = sw_event->get_sw_record(sw_event);
|
||||
record_id = sw_record->get_record_id(sw_record);
|
||||
data_model = sw_record->get_data_model(sw_record);
|
||||
source_id = sw_record->get_source_id(sw_record);
|
||||
sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
|
||||
|
||||
writer->write_uint32(writer, eid);
|
||||
writer->write_data (writer, timestamp);
|
||||
writer->write_uint32(writer, record_id);
|
||||
writer->write_uint24(writer, data_model.vendor_id);
|
||||
writer->write_uint8 (writer, data_model.type);
|
||||
writer->write_uint8 (writer, source_id);
|
||||
writer->write_uint8 (writer, action);
|
||||
writer->write_data16(writer, sw_id);
|
||||
writer->write_data16(writer, sw_locator);
|
||||
|
||||
if (this->type.type == IETF_ATTR_SW_EVENTS)
|
||||
{
|
||||
record = sw_record->get_record(sw_record);
|
||||
writer->write_data32(writer, record);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->value = writer->extract_buf(writer);
|
||||
this->segment = this->value;
|
||||
this->length = this->value.len;
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, process, status_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this, uint32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
uint32_t data_model_pen, record_id;
|
||||
uint32_t eid, eid_epoch, last_eid, last_consulted_eid;
|
||||
uint8_t data_model_type, source_id, action;
|
||||
pen_type_t data_model;
|
||||
chunk_t sw_id, sw_locator, record, timestamp;
|
||||
swima_event_t *sw_event;
|
||||
swima_record_t *sw_record;
|
||||
status_t status = NEED_MORE;
|
||||
|
||||
if (this->offset == 0)
|
||||
{
|
||||
if (this->length < IETF_SWIMA_SW_EV_MIN_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
|
||||
ietf_attr_names, this->type.type);
|
||||
*offset = this->offset;
|
||||
return FAILED;
|
||||
}
|
||||
if (this->value.len < IETF_SWIMA_SW_EV_MIN_SIZE)
|
||||
{
|
||||
return NEED_MORE;
|
||||
}
|
||||
reader = bio_reader_create(this->value);
|
||||
reader->read_uint8 (reader, &this->flags);
|
||||
reader->read_uint24(reader, &this->event_count);
|
||||
reader->read_uint32(reader, &this->request_id);
|
||||
reader->read_uint32(reader, &eid_epoch);
|
||||
reader->read_uint32(reader, &last_eid);
|
||||
reader->read_uint32(reader, &last_consulted_eid);
|
||||
this->offset = IETF_SWIMA_SW_EV_MIN_SIZE;
|
||||
this->events->set_eid(this->events, last_consulted_eid, eid_epoch);
|
||||
this->events->set_last_eid(this->events, last_eid);
|
||||
this->value = reader->peek(reader);
|
||||
reader->destroy(reader);
|
||||
}
|
||||
|
||||
reader = bio_reader_create(this->value);
|
||||
|
||||
while (this->event_count)
|
||||
{
|
||||
if (!reader->read_uint32(reader, &eid) ||
|
||||
!reader->read_data (reader, SW_EV_TIMESTAMP_SIZE, ×tamp) ||
|
||||
!reader->read_uint32(reader, &record_id) ||
|
||||
!reader->read_uint24(reader, &data_model_pen) ||
|
||||
!reader->read_uint8 (reader, &data_model_type) ||
|
||||
!reader->read_uint8 (reader, &source_id) ||
|
||||
!reader->read_uint8 (reader, &action) ||
|
||||
!reader->read_data16(reader, &sw_id) ||
|
||||
!reader->read_data16(reader, &sw_locator))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
record = chunk_empty;
|
||||
|
||||
if (action == 0 || action > SWIMA_EVENT_ACTION_LAST)
|
||||
{
|
||||
DBG1(DBG_TNC, "invalid event action value for %N/%N", pen_names,
|
||||
PEN_IETF, ietf_attr_names, this->type.type);
|
||||
*offset = this->offset;
|
||||
reader->destroy(reader);
|
||||
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->type.type == IETF_ATTR_SW_EVENTS &&
|
||||
!reader->read_data32(reader, &record))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
data_model = pen_type_create(data_model_pen, data_model_type);
|
||||
sw_record = swima_record_create(record_id, sw_id, sw_locator);
|
||||
sw_record->set_data_model(sw_record, data_model);
|
||||
sw_record->set_source_id(sw_record, source_id);
|
||||
sw_record->set_record(sw_record, record);
|
||||
sw_event = swima_event_create(eid, timestamp, action, sw_record);
|
||||
this->events->add(this->events, sw_event);
|
||||
this->offset += this->value.len - reader->remaining(reader);
|
||||
this->value = reader->peek(reader);
|
||||
|
||||
/* at least one software event was processed */
|
||||
status = SUCCESS;
|
||||
this->event_count--;
|
||||
}
|
||||
|
||||
if (this->length == this->offset)
|
||||
{
|
||||
status = SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF,
|
||||
ietf_attr_names, this->type.type);
|
||||
*offset = this->offset;
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
end:
|
||||
reader->destroy(reader);
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||
private_ietf_swima_attr_sw_ev_t *this, chunk_t segment)
|
||||
{
|
||||
this->value = chunk_cat("cc", this->value, segment);
|
||||
chunk_free(&this->segment);
|
||||
this->segment = this->value;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, destroy, void,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->events->destroy(this->events);
|
||||
free(this->segment.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, get_flags, uint8_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->flags;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, get_request_id, uint32_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->request_id;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, get_event_count, uint32_t,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->event_count;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, set_events, void,
|
||||
private_ietf_swima_attr_sw_ev_t *this, swima_events_t *events)
|
||||
{
|
||||
this->events->destroy(this->events);
|
||||
this->events = events->get_ref(events);
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, get_events, swima_events_t*,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
return this->events;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_ev_t, clear_events, void,
|
||||
private_ietf_swima_attr_sw_ev_t *this)
|
||||
{
|
||||
this->events->clear(this->events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_sw_ev_create(uint8_t flags, uint32_t request_id,
|
||||
bool sw_id_only)
|
||||
{
|
||||
private_ietf_swima_attr_sw_ev_t *this;
|
||||
ietf_attr_t type;
|
||||
|
||||
type = sw_id_only ? IETF_ATTR_SW_ID_EVENTS : IETF_ATTR_SW_EVENTS;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.get_event_count = _get_event_count,
|
||||
.set_events = _set_events,
|
||||
.get_events = _get_events,
|
||||
.clear_events = _clear_events,
|
||||
},
|
||||
.type = { PEN_IETF, type },
|
||||
.flags = flags,
|
||||
.request_id = request_id,
|
||||
.events = swima_events_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_sw_ev_create_from_data(size_t length,
|
||||
chunk_t data, bool sw_id_only)
|
||||
{
|
||||
private_ietf_swima_attr_sw_ev_t *this;
|
||||
ietf_attr_t type;
|
||||
|
||||
type = sw_id_only ? IETF_ATTR_SW_ID_EVENTS : IETF_ATTR_SW_EVENTS;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.get_event_count = _get_event_count,
|
||||
.set_events = _set_events,
|
||||
.get_events = _get_events,
|
||||
.clear_events = _clear_events,
|
||||
},
|
||||
.type = { PEN_IETF, type },
|
||||
.length = length,
|
||||
.segment = chunk_clone(data),
|
||||
.events = swima_events_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
/* received either complete attribute value or first segment */
|
||||
this->value = this->segment;
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
111
src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h
Normal file
111
src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ietf_swima_attr_sw_ev ietf_swima_attr_sw_ev
|
||||
* @{ @ingroup ietf_attr
|
||||
*/
|
||||
|
||||
#ifndef IETF_SWIMA_ATTR_SW_EV_H_
|
||||
#define IETF_SWIMA_ATTR_SW_EV_H_
|
||||
|
||||
#define IETF_SWIMA_SW_EV_MIN_SIZE 20
|
||||
|
||||
typedef struct ietf_swima_attr_sw_ev_t ietf_swima_attr_sw_ev_t;
|
||||
typedef enum ietf_swima_attr_sw_ev_flag_t ietf_swima_attr_sw_ev_flag_t;
|
||||
|
||||
enum ietf_swima_attr_sw_ev_flag_t {
|
||||
IETF_SWIMA_ATTR_SW_EV_FLAG_NONE = 0,
|
||||
IETF_SWIMA_ATTR_SW_EV_FLAG_S_F = (1 << 7)
|
||||
};
|
||||
|
||||
#include "ietf/ietf_attr.h"
|
||||
#include "swima/swima_events.h"
|
||||
#include "pa_tnc/pa_tnc_attr.h"
|
||||
|
||||
/**
|
||||
* Class implementing the IETF SW Identifier Inventory attribute
|
||||
*
|
||||
*/
|
||||
struct ietf_swima_attr_sw_ev_t {
|
||||
|
||||
/**
|
||||
* Public PA-TNC attribute interface
|
||||
*/
|
||||
pa_tnc_attr_t pa_tnc_attribute;
|
||||
|
||||
/**
|
||||
* Get Software Inventory flags
|
||||
*
|
||||
* @return Flags
|
||||
*/
|
||||
uint8_t (*get_flags)(ietf_swima_attr_sw_ev_t *this);
|
||||
|
||||
/**
|
||||
* Get Request ID
|
||||
*
|
||||
* @return Request ID
|
||||
*/
|
||||
uint32_t (*get_request_id)(ietf_swima_attr_sw_ev_t *this);
|
||||
|
||||
/**
|
||||
* Get number of Software [Identifier] Events
|
||||
*
|
||||
* @return Software [Identifier] event count
|
||||
*/
|
||||
uint32_t (*get_event_count)(ietf_swima_attr_sw_ev_t *this);
|
||||
|
||||
/**
|
||||
* Add Software [Identifier] Events
|
||||
*
|
||||
* @param sw_events List of Software [Identifier] events to be added
|
||||
*/
|
||||
void (*set_events)(ietf_swima_attr_sw_ev_t *this,
|
||||
swima_events_t *sw_events);
|
||||
/**
|
||||
* Get Software [Identifier] Events
|
||||
*
|
||||
* @result Software [Identifier] events
|
||||
*/
|
||||
swima_events_t* (*get_events)(ietf_swima_attr_sw_ev_t *this);
|
||||
|
||||
/**
|
||||
* Remove all Software [Identifier] events
|
||||
*/
|
||||
void (*clear_events)(ietf_swima_attr_sw_ev_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_sw_ev_t object
|
||||
*
|
||||
* @param flags Sets the flags
|
||||
* @param request_id Copy of the Request ID
|
||||
* @param sw_id_only TRUE if the Software ID, only is transmitted
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_sw_ev_create(uint8_t flags, uint32_t request_id,
|
||||
bool sw_id_only);
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_sw_ev_t object from received data
|
||||
*
|
||||
* @param length Total length of attribute value
|
||||
* @param value Unparsed attribute value (might be a segment)
|
||||
* @param sw_id_only TRUE if the Software ID, only is transmitted
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_sw_ev_create_from_data(size_t length,
|
||||
chunk_t value, bool sw_id_only);
|
||||
|
||||
#endif /** IETF_SWIMA_ATTR_SW_EV_H_ @}*/
|
438
src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
Normal file
438
src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "ietf_swima_attr_sw_inv.h"
|
||||
#include "swima/swima_record.h"
|
||||
|
||||
#include <pa_tnc/pa_tnc_msg.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
|
||||
typedef struct private_ietf_swima_attr_sw_inv_t private_ietf_swima_attr_sw_inv_t;
|
||||
|
||||
/**
|
||||
* Software [Identifier] Inventory
|
||||
* see sections 5.8/5.10 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Flags | Software Identifier Count |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Request ID Copy / Subscription ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | EID Epoch |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Last EID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record Identifier |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Data Model Type PEN |Data Model Type|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Source ID Num | Software Identifier Length |Software Id (v)|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Software Locator Length | Software Locator (Var. Len) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* Software Inventory only
|
||||
* see section 5.10 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Record (Variable length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private data of an ietf_swima_attr_sw_inv_t object.
|
||||
*/
|
||||
struct private_ietf_swima_attr_sw_inv_t {
|
||||
|
||||
/**
|
||||
* Public members of ietf_swima_attr_sw_inv_t
|
||||
*/
|
||||
ietf_swima_attr_sw_inv_t public;
|
||||
|
||||
/**
|
||||
* Vendor-specific attribute type
|
||||
*/
|
||||
pen_type_t type;
|
||||
|
||||
/**
|
||||
* Length of attribute value
|
||||
*/
|
||||
size_t length;
|
||||
|
||||
/**
|
||||
* Offset up to which attribute value has been processed
|
||||
*/
|
||||
size_t offset;
|
||||
|
||||
/**
|
||||
* Current position of attribute value pointer
|
||||
*/
|
||||
chunk_t value;
|
||||
|
||||
/**
|
||||
* Contains complete attribute or current segment
|
||||
*/
|
||||
chunk_t segment;
|
||||
|
||||
/**
|
||||
* Noskip flag
|
||||
*/
|
||||
bool noskip_flag;
|
||||
|
||||
/**
|
||||
* Request ID
|
||||
*/
|
||||
uint32_t request_id;
|
||||
|
||||
/**
|
||||
* Attribute flags
|
||||
*/
|
||||
uint8_t flags;
|
||||
|
||||
/**
|
||||
* Number of unprocessed software inventory evidence records in attribute
|
||||
*/
|
||||
uint32_t record_count;
|
||||
|
||||
/**
|
||||
* SWID Tag ID Inventory
|
||||
*/
|
||||
swima_inventory_t *inventory;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->noskip_flag;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||
private_ietf_swima_attr_sw_inv_t *this, bool noskip)
|
||||
{
|
||||
this->noskip_flag = noskip;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, build, void,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
swima_record_t *sw_record;
|
||||
chunk_t sw_id, sw_locator, record;
|
||||
pen_type_t data_model;
|
||||
uint32_t record_id, last_eid, eid_epoch;
|
||||
uint8_t source_id;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
if (this->value.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
last_eid = this->inventory->get_eid(this->inventory, &eid_epoch);
|
||||
|
||||
writer = bio_writer_create(IETF_SWIMA_SW_INV_MIN_SIZE);
|
||||
writer->write_uint8 (writer, this->flags);
|
||||
writer->write_uint24(writer, this->inventory->get_count(this->inventory));
|
||||
writer->write_uint32(writer, this->request_id);
|
||||
writer->write_uint32(writer, eid_epoch);
|
||||
writer->write_uint32(writer, last_eid);
|
||||
|
||||
enumerator = this->inventory->create_enumerator(this->inventory);
|
||||
while (enumerator->enumerate(enumerator, &sw_record))
|
||||
{
|
||||
record_id = sw_record->get_record_id(sw_record);
|
||||
data_model = sw_record->get_data_model(sw_record);
|
||||
source_id = sw_record->get_source_id(sw_record);
|
||||
sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
|
||||
|
||||
writer->write_uint32(writer, record_id);
|
||||
writer->write_uint24(writer, data_model.vendor_id);
|
||||
writer->write_uint8 (writer, data_model.type);
|
||||
writer->write_uint8 (writer, source_id);
|
||||
writer->write_data16(writer, sw_id);
|
||||
writer->write_data16(writer, sw_locator);
|
||||
|
||||
if (this->type.type == IETF_ATTR_SW_INVENTORY)
|
||||
{
|
||||
record = sw_record->get_record(sw_record);
|
||||
writer->write_data32(writer, record);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->value = writer->extract_buf(writer);
|
||||
this->segment = this->value;
|
||||
this->length = this->value.len;
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, process, status_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this, uint32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
uint32_t data_model_pen, record_id, last_eid, eid_epoch;
|
||||
uint8_t data_model_type, source_id;
|
||||
pen_type_t data_model;
|
||||
chunk_t sw_id, sw_locator, record;
|
||||
swima_record_t *sw_record;
|
||||
status_t status = NEED_MORE;
|
||||
|
||||
if (this->offset == 0)
|
||||
{
|
||||
if (this->length < IETF_SWIMA_SW_INV_MIN_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
|
||||
ietf_attr_names, this->type.type);
|
||||
*offset = this->offset;
|
||||
return FAILED;
|
||||
}
|
||||
if (this->value.len < IETF_SWIMA_SW_INV_MIN_SIZE)
|
||||
{
|
||||
return NEED_MORE;
|
||||
}
|
||||
reader = bio_reader_create(this->value);
|
||||
reader->read_uint8 (reader, &this->flags);
|
||||
reader->read_uint24(reader, &this->record_count);
|
||||
reader->read_uint32(reader, &this->request_id);
|
||||
reader->read_uint32(reader, &eid_epoch);
|
||||
reader->read_uint32(reader, &last_eid);
|
||||
this->offset = IETF_SWIMA_SW_INV_MIN_SIZE;
|
||||
this->value = reader->peek(reader);
|
||||
this->inventory->set_eid(this->inventory, last_eid, eid_epoch);
|
||||
reader->destroy(reader);
|
||||
}
|
||||
|
||||
reader = bio_reader_create(this->value);
|
||||
|
||||
while (this->record_count)
|
||||
{
|
||||
if (!reader->read_uint32(reader, &record_id) ||
|
||||
!reader->read_uint24(reader, &data_model_pen) ||
|
||||
!reader->read_uint8 (reader, &data_model_type) ||
|
||||
!reader->read_uint8 (reader, &source_id) ||
|
||||
!reader->read_data16(reader, &sw_id) ||
|
||||
!reader->read_data16(reader, &sw_locator))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
record = chunk_empty;
|
||||
|
||||
if (this->type.type == IETF_ATTR_SW_INVENTORY &&
|
||||
!reader->read_data32(reader, &record))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
data_model = pen_type_create(data_model_pen, data_model_type);
|
||||
sw_record = swima_record_create(record_id, sw_id, sw_locator);
|
||||
sw_record->set_data_model(sw_record, data_model);
|
||||
sw_record->set_source_id(sw_record, source_id);
|
||||
sw_record->set_record(sw_record, record);
|
||||
this->inventory->add(this->inventory, sw_record);
|
||||
this->offset += this->value.len - reader->remaining(reader);
|
||||
this->value = reader->peek(reader);
|
||||
|
||||
/* at least one software inventory evidence record was processed */
|
||||
status = SUCCESS;
|
||||
this->record_count--;
|
||||
}
|
||||
|
||||
if (this->length == this->offset)
|
||||
{
|
||||
status = SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF,
|
||||
ietf_attr_names, this->type.type);
|
||||
*offset = this->offset;
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
end:
|
||||
reader->destroy(reader);
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||
private_ietf_swima_attr_sw_inv_t *this, chunk_t segment)
|
||||
{
|
||||
this->value = chunk_cat("cc", this->value, segment);
|
||||
chunk_free(&this->segment);
|
||||
this->segment = this->value;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
METHOD(pa_tnc_attr_t, destroy, void,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->inventory->destroy(this->inventory);
|
||||
free(this->segment.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, get_flags, uint8_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->flags;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, get_request_id, uint32_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->request_id;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, get_record_count, uint32_t,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->record_count;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, set_inventory, void,
|
||||
private_ietf_swima_attr_sw_inv_t *this, swima_inventory_t *inventory)
|
||||
{
|
||||
this->inventory->destroy(this->inventory);
|
||||
this->inventory = inventory->get_ref(inventory);
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, get_inventory, swima_inventory_t*,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
return this->inventory;
|
||||
}
|
||||
|
||||
METHOD(ietf_swima_attr_sw_inv_t, clear_inventory, void,
|
||||
private_ietf_swima_attr_sw_inv_t *this)
|
||||
{
|
||||
this->inventory->clear(this->inventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_sw_inv_create(uint8_t flags, uint32_t request_id,
|
||||
bool sw_id_only)
|
||||
{
|
||||
private_ietf_swima_attr_sw_inv_t *this;
|
||||
ietf_attr_t type;
|
||||
|
||||
type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.get_record_count = _get_record_count,
|
||||
.set_inventory = _set_inventory,
|
||||
.get_inventory = _get_inventory,
|
||||
.clear_inventory = _clear_inventory,
|
||||
},
|
||||
.type = { PEN_IETF, type },
|
||||
.flags = flags,
|
||||
.request_id = request_id,
|
||||
.inventory = swima_inventory_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_swima_attr_sw_inv_create_from_data(size_t length,
|
||||
chunk_t data, bool sw_id_only)
|
||||
{
|
||||
private_ietf_swima_attr_sw_inv_t *this;
|
||||
ietf_attr_t type;
|
||||
|
||||
type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pa_tnc_attribute = {
|
||||
.get_type = _get_type,
|
||||
.get_value = _get_value,
|
||||
.get_noskip_flag = _get_noskip_flag,
|
||||
.set_noskip_flag = _set_noskip_flag,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.add_segment = _add_segment,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_flags = _get_flags,
|
||||
.get_request_id = _get_request_id,
|
||||
.get_record_count = _get_record_count,
|
||||
.set_inventory = _set_inventory,
|
||||
.get_inventory = _get_inventory,
|
||||
.clear_inventory = _clear_inventory,
|
||||
},
|
||||
.type = { PEN_IETF, type },
|
||||
.length = length,
|
||||
.segment = chunk_clone(data),
|
||||
.inventory = swima_inventory_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
/* received either complete attribute value or first segment */
|
||||
this->value = this->segment;
|
||||
|
||||
return &this->public.pa_tnc_attribute;
|
||||
}
|
112
src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h
Normal file
112
src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ietf_swima_attr_sw_inv ietf_swima_attr_sw_inv
|
||||
* @{ @ingroup ietf_attr
|
||||
*/
|
||||
|
||||
#ifndef IETF_SWIMA_ATTR_SW_INV_H_
|
||||
#define IETF_SWIMA_ATTR_SW_INV_H_
|
||||
|
||||
#define IETF_SWIMA_SW_INV_MIN_SIZE 16
|
||||
|
||||
typedef struct ietf_swima_attr_sw_inv_t ietf_swima_attr_sw_inv_t;
|
||||
typedef enum ietf_swima_attr_sw_inv_flag_t ietf_swima_attr_sw_inv_flag_t;
|
||||
|
||||
enum ietf_swima_attr_sw_inv_flag_t {
|
||||
IETF_SWIMA_ATTR_SW_INV_FLAG_NONE = 0,
|
||||
IETF_SWIMA_ATTR_SW_INV_FLAG_S_F = (1 << 7)
|
||||
};
|
||||
|
||||
#include "ietf/ietf_attr.h"
|
||||
#include "swima/swima_inventory.h"
|
||||
#include "pa_tnc/pa_tnc_attr.h"
|
||||
|
||||
/**
|
||||
* Class implementing the IETF SW Identifier Inventory attribute
|
||||
*
|
||||
*/
|
||||
struct ietf_swima_attr_sw_inv_t {
|
||||
|
||||
/**
|
||||
* Public PA-TNC attribute interface
|
||||
*/
|
||||
pa_tnc_attr_t pa_tnc_attribute;
|
||||
|
||||
/**
|
||||
* Get Software Inventory flags
|
||||
*
|
||||
* @return Flags
|
||||
*/
|
||||
uint8_t (*get_flags)(ietf_swima_attr_sw_inv_t *this);
|
||||
|
||||
/**
|
||||
* Get Request ID
|
||||
*
|
||||
* @return Request ID
|
||||
*/
|
||||
uint32_t (*get_request_id)(ietf_swima_attr_sw_inv_t *this);
|
||||
|
||||
/**
|
||||
* Get number of Software [Identifier] Inventory records
|
||||
*
|
||||
* @return Software ID count
|
||||
*/
|
||||
uint32_t (*get_record_count)(ietf_swima_attr_sw_inv_t *this);
|
||||
|
||||
/**
|
||||
* Add a Software [Identifier] Inventory
|
||||
*
|
||||
* @param sw_inventory Software [Identifier] record to be added
|
||||
*/
|
||||
void (*set_inventory)(ietf_swima_attr_sw_inv_t *this,
|
||||
swima_inventory_t *sw_inventory);
|
||||
/**
|
||||
* Get Software [Identifier] Inventory
|
||||
*
|
||||
* @result Software [Identifier] Inventory
|
||||
*/
|
||||
swima_inventory_t* (*get_inventory)(ietf_swima_attr_sw_inv_t *this);
|
||||
|
||||
/**
|
||||
* Remove all Software [Identifier] records from the inventory
|
||||
*/
|
||||
void (*clear_inventory)(ietf_swima_attr_sw_inv_t *this);
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_sw_inv_t object
|
||||
*
|
||||
* @param flags Sets the flags
|
||||
* @param request_id Copy of the Request ID
|
||||
* @param sw_id_only TRUE if the Software ID, only is transmitted
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_sw_inv_create(uint8_t flags, uint32_t request_id,
|
||||
bool sw_id_only);
|
||||
|
||||
/**
|
||||
* Creates an ietf_swima_attr_sw_inv_t object from received data
|
||||
*
|
||||
* @param length Total length of attribute value
|
||||
* @param value Unparsed attribute value (might be a segment)
|
||||
* @param sw_id_only TRUE if the Software ID, only is transmitted
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_swima_attr_sw_inv_create_from_data(size_t length,
|
||||
chunk_t value, bool sw_id_only);
|
||||
|
||||
#endif /** IETF_SWIMA_ATTR_SW_INV_H_ @}*/
|
@ -304,14 +304,47 @@ CREATE INDEX "swid_tags_sessions_session_id" ON "swid_tags_sessions" (
|
||||
|
||||
DROP TABLE IF EXISTS "swid_tagstats";
|
||||
CREATE TABLE "swid_tagstats" (
|
||||
"id" integer NOT NULL PRIMARY KEY,
|
||||
"tag_id" integer NOT NULL REFERENCES "swid_tags" ("id"),
|
||||
"device_id" integer NOT NULL REFERENCES "devices" ("id"),
|
||||
"first_seen_id" integer NOT NULL REFERENCES "sessions" ("id"),
|
||||
"last_seen_id" integer NOT NULL REFERENCES "sessions" ("id"),
|
||||
"id" INTEGER NOT NULL PRIMARY KEY,
|
||||
"tag_id" INTEGER NOT NULL REFERENCES "swid_tags" ("id"),
|
||||
"device_id" INTEGER NOT NULL REFERENCES "devices" ("id"),
|
||||
"first_seen_id" INTEGER NOT NULL REFERENCES "sessions" ("id"),
|
||||
"last_seen_id" INTEGER NOT NULL REFERENCES "sessions" ("id"),
|
||||
"first_installed_id" INTEGER REFERENCES "swid_events" ("id"),
|
||||
"last_deleted_id" INTEGER REFERENCES "swid_events" ("id"),
|
||||
UNIQUE ("tag_id", "device_id")
|
||||
);
|
||||
CREATE INDEX "swid_tagstats_tag_id" ON "swid_tagstats" ("tag_id");
|
||||
CREATE INDEX "swid_tagstats_device_id" ON "swid_tagstats" ("device_id");
|
||||
CREATE INDEX "swid_tagstats_first_seen_id" ON "swid_tagstats" ("first_seen_id");
|
||||
CREATE INDEX "swid_tagstats_last_seen_id" ON "swid_tagstats" ("last_seen_id");
|
||||
|
||||
DROP TABLE IF EXISTS "swid_events";
|
||||
CREATE TABLE "swid_events" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"device" INTEGER REFERENCES "devices" ("id"),
|
||||
"epoch" INTEGER NOT NULL,
|
||||
"eid" INTEGER NOT NULL,
|
||||
"timestamp" CHAR(20) NOT NULL
|
||||
);
|
||||
DROP INDEX IF EXISTS "swid_events_device";
|
||||
CREATE INDEX "swid_events_device" ON "swid_events" (
|
||||
"device"
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS "swid_tags_events";
|
||||
CREATE TABLE "swid_tags_events" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"tag_id" INTEGER NOT NULL REFERENCES "swid_tags" ("id"),
|
||||
"event_id" INTEGER NOT NULL REFERENCES "swid_events" ("id"),
|
||||
"action" INTEGER NOT NULL,
|
||||
"record_id" INTEGER DEFAULT 0,
|
||||
"source_id" INTEGER DEFAULT 0
|
||||
);
|
||||
DROP INDEX IF EXISTS "swid_tags_events_event_id";
|
||||
DROP INDEX IF EXISTS "swid_tags_events_tag_id";
|
||||
CREATE INDEX "swid_tags_events_event_id" ON "swid_tags_events" (
|
||||
"event_id"
|
||||
);
|
||||
CREATE INDEX "swid_tags_events_tag_id" ON "swid_tags_events" (
|
||||
"tag_id"
|
||||
);
|
||||
|
@ -299,8 +299,9 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
|
||||
error_code = error_attr->get_error_code(error_attr);
|
||||
msg_info = error_attr->get_msg_info(error_attr);
|
||||
|
||||
/* skip errors from non-IETF namespaces */
|
||||
if (error_code.vendor_id != PEN_IETF)
|
||||
/* skip errors from non-IETF namespaces and non PA-TNC msg errors */
|
||||
if (error_code.vendor_id != PEN_IETF ||
|
||||
error_code.type > PA_ERROR_PA_TNC_MSG_ROOF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
647
src/libimcv/swima/swima_collector.c
Normal file
647
src/libimcv/swima/swima_collector.c
Normal file
@ -0,0 +1,647 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_collector.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define SOURCE_ID_GENERATOR 1
|
||||
#define SOURCE_ID_COLLECTOR 2
|
||||
|
||||
#define SWID_GENERATOR "/usr/local/bin/swid_generator"
|
||||
|
||||
/**
|
||||
* Directories to be skipped by collector
|
||||
*/
|
||||
static const char* skip_directories[] = {
|
||||
"/usr/share/doc",
|
||||
"/usr/share/help",
|
||||
"/usr/share/icons",
|
||||
"/usr/share/gnome/help"
|
||||
};
|
||||
|
||||
typedef struct private_swima_collector_t private_swima_collector_t;
|
||||
|
||||
/**
|
||||
* Private data of a swima_collector_t object.
|
||||
*
|
||||
*/
|
||||
struct private_swima_collector_t {
|
||||
|
||||
/**
|
||||
* Public swima_collector_t interface.
|
||||
*/
|
||||
swima_collector_t public;
|
||||
|
||||
/**
|
||||
* Collect Software Identifiers only
|
||||
*/
|
||||
bool sw_id_only;
|
||||
|
||||
/**
|
||||
* Software Collector Database [if it exists]
|
||||
*/
|
||||
database_t *db;
|
||||
|
||||
/**
|
||||
* List of Software [Identifier] records
|
||||
*/
|
||||
swima_inventory_t *inventory;
|
||||
|
||||
/**
|
||||
* List of Software [Identifier] events
|
||||
*/
|
||||
swima_events_t *events;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract Software Identifier from SWID tag
|
||||
*/
|
||||
static status_t extract_sw_id(chunk_t swid_tag, chunk_t *sw_id)
|
||||
{
|
||||
char *pos, *tag, *tagid, *regid;
|
||||
size_t len, tagid_len, regid_len;
|
||||
status_t status = NOT_FOUND;
|
||||
|
||||
/* Copy at most 1023 bytes of the SWID tag and null-terminate it */
|
||||
len = min(1023, swid_tag.len);
|
||||
pos = tag = strndup(swid_tag.ptr, len);
|
||||
|
||||
tagid= strstr(pos, "tagId=\"");
|
||||
if (tagid == NULL)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
tagid += 7;
|
||||
len -= tagid - pos - 7;
|
||||
|
||||
pos = strchr(tagid, '"');
|
||||
if (pos == NULL)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
tagid_len = pos - tagid;
|
||||
|
||||
regid= strstr(pos, "regid=\"");
|
||||
if (regid == NULL)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
regid += 7;
|
||||
len -= regid - pos - 7;
|
||||
|
||||
pos = strchr(regid, '"');
|
||||
if (pos == NULL)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
regid_len = pos - regid;
|
||||
|
||||
*sw_id = chunk_cat("ccc", chunk_create(regid, regid_len),
|
||||
chunk_from_chars('_','_'),
|
||||
chunk_create(tagid, tagid_len));
|
||||
status = SUCCESS;
|
||||
end:
|
||||
free(tag);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read SWID tags issued by the swid_generator tool
|
||||
*/
|
||||
static status_t read_swid_tags(private_swima_collector_t *this, FILE *file)
|
||||
{
|
||||
swima_record_t *sw_record;
|
||||
bio_writer_t *writer;
|
||||
chunk_t sw_id, swid_tag;
|
||||
bool more_tags = TRUE, last_newline;
|
||||
char line[8192];
|
||||
size_t len;
|
||||
status_t status;
|
||||
|
||||
while (more_tags)
|
||||
{
|
||||
last_newline = TRUE;
|
||||
writer = bio_writer_create(512);
|
||||
while (TRUE)
|
||||
{
|
||||
if (!fgets(line, sizeof(line), file))
|
||||
{
|
||||
more_tags = FALSE;
|
||||
break;
|
||||
}
|
||||
len = strlen(line);
|
||||
|
||||
if (last_newline && line[0] == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_newline = (line[len-1] == '\n');
|
||||
writer->write_data(writer, chunk_create(line, len));
|
||||
}
|
||||
}
|
||||
swid_tag = writer->get_buf(writer);
|
||||
|
||||
if (swid_tag.len > 1)
|
||||
{
|
||||
/* remove trailing newline if present */
|
||||
if (swid_tag.ptr[swid_tag.len - 1] == '\n')
|
||||
{
|
||||
swid_tag.len--;
|
||||
}
|
||||
DBG3(DBG_IMC, " %.*s", swid_tag.len, swid_tag.ptr);
|
||||
|
||||
status = extract_sw_id(swid_tag, &sw_id);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IMC, "software id could not be extracted from tag");
|
||||
writer->destroy(writer);
|
||||
return status;
|
||||
}
|
||||
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
||||
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
||||
sw_record->set_record(sw_record, swid_tag);
|
||||
this->inventory->add(this->inventory, sw_record);
|
||||
chunk_free(&sw_id);
|
||||
}
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Software Identifiers issued by the swid_generator tool
|
||||
*/
|
||||
static status_t read_swid_tag_ids(private_swima_collector_t *this, FILE *file)
|
||||
{
|
||||
swima_record_t *sw_record;
|
||||
chunk_t sw_id;
|
||||
char line[BUF_LEN];
|
||||
size_t len;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!fgets(line, sizeof(line), file))
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
len = strlen(line);
|
||||
|
||||
/* remove trailing newline if present */
|
||||
if (len > 0 && line[len - 1] == '\n')
|
||||
{
|
||||
len--;
|
||||
}
|
||||
DBG3(DBG_IMC, " %.*s", len, line);
|
||||
|
||||
sw_id = chunk_create(line, len);
|
||||
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
||||
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
||||
this->inventory->add(this->inventory, sw_record);
|
||||
}
|
||||
}
|
||||
|
||||
static status_t retrieve_inventory(private_swima_collector_t *this,
|
||||
swima_inventory_t *targets)
|
||||
{
|
||||
char *name;
|
||||
uint32_t record_id, source;
|
||||
swima_record_t *sw_record;
|
||||
chunk_t sw_id;
|
||||
enumerator_t *e;
|
||||
|
||||
/* Retrieve complete software identifier inventory */
|
||||
e = this->db->query(this->db,
|
||||
"SELECT id, name, source FROM sw_identifiers WHERE installed = 1 "
|
||||
"ORDER BY name ASC", DB_UINT, DB_TEXT, DB_UINT);
|
||||
if (!e)
|
||||
{
|
||||
DBG1(DBG_IMC, "database query for installed sw_identifiers failed");
|
||||
return FAILED;
|
||||
}
|
||||
while (e->enumerate(e, &record_id, &name, &source))
|
||||
{
|
||||
sw_id = chunk_from_str(name);
|
||||
sw_record = swima_record_create(record_id, sw_id, chunk_empty);
|
||||
sw_record->set_source_id(sw_record, source);
|
||||
this->inventory->add(this->inventory, sw_record);
|
||||
}
|
||||
e->destroy(e);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static status_t retrieve_events(private_swima_collector_t *this,
|
||||
swima_inventory_t *targets)
|
||||
{
|
||||
enumerator_t *e;
|
||||
char *name, *timestamp;
|
||||
uint32_t record_id, source, action, eid, earliest_eid;
|
||||
chunk_t sw_id, ev_ts;
|
||||
swima_record_t *sw_record;
|
||||
swima_event_t *sw_event;
|
||||
|
||||
earliest_eid = targets->get_eid(targets, NULL);
|
||||
|
||||
/* Retrieve complete software identifier inventory */
|
||||
e = this->db->query(this->db,
|
||||
"SELECT e.id, e.timestamp, i.id, i.name, i.source, s.action "
|
||||
"FROM sw_events as s JOIN events AS e ON s.eid = e.id "
|
||||
"JOIN sw_identifiers as i ON s.sw_id = i.id WHERE s.eid >= ?"
|
||||
"ORDER BY s.eid, i.name, s.action ASC", DB_UINT, earliest_eid,
|
||||
DB_UINT, DB_TEXT, DB_UINT, DB_TEXT, DB_UINT, DB_UINT);
|
||||
if (!e)
|
||||
{
|
||||
DBG1(DBG_IMC, "database query for sw_events failed");
|
||||
return FAILED;
|
||||
}
|
||||
while (e->enumerate(e, &eid, ×tamp, &record_id, &name, &source, &action))
|
||||
{
|
||||
sw_id = chunk_from_str(name);
|
||||
ev_ts = chunk_from_str(timestamp);
|
||||
sw_record = swima_record_create(record_id, sw_id, chunk_empty);
|
||||
sw_record->set_source_id(sw_record, source);
|
||||
sw_event = swima_event_create(eid, ev_ts, action, sw_record);
|
||||
this->events->add(this->events, sw_event);
|
||||
}
|
||||
e->destroy(e);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static status_t generate_tags(private_swima_collector_t *this, char *generator,
|
||||
swima_inventory_t *targets, bool pretty, bool full)
|
||||
{
|
||||
FILE *file;
|
||||
char command[BUF_LEN];
|
||||
char doc_separator[] = "'\n\n'";
|
||||
|
||||
status_t status = SUCCESS;
|
||||
|
||||
if (targets->get_count(targets) == 0)
|
||||
{
|
||||
/* Assemble the SWID generator command */
|
||||
if (this->sw_id_only)
|
||||
{
|
||||
snprintf(command, BUF_LEN, "%s software-id", generator);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
|
||||
generator, doc_separator, pretty ? " --pretty" : "",
|
||||
full ? " --full" : "");
|
||||
}
|
||||
|
||||
/* Open a pipe stream for reading the SWID generator output */
|
||||
file = popen(command, "r");
|
||||
if (!file)
|
||||
{
|
||||
DBG1(DBG_IMC, "failed to run swid_generator command");
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (this->sw_id_only)
|
||||
{
|
||||
DBG2(DBG_IMC, "SWID tag ID generation by package manager");
|
||||
status = read_swid_tag_ids(this, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_IMC, "SWID tag generation by package manager");
|
||||
status = read_swid_tags(this, file);
|
||||
}
|
||||
pclose(file);
|
||||
}
|
||||
else if (!this->sw_id_only)
|
||||
{
|
||||
swima_record_t *target;
|
||||
enumerator_t *enumerator;
|
||||
chunk_t sw_id;
|
||||
|
||||
enumerator = targets->create_enumerator(targets);
|
||||
while (enumerator->enumerate(enumerator, &target))
|
||||
{
|
||||
sw_id = target->get_sw_id(target, NULL);
|
||||
|
||||
/* Assemble the SWID generator command */
|
||||
snprintf(command, BUF_LEN, "%s swid --software-id %.*s%s%s",
|
||||
generator, sw_id.len, sw_id.ptr,
|
||||
pretty ? " --pretty" : "", full ? " --full" : "");
|
||||
|
||||
/* Open a pipe stream for reading the SWID generator output */
|
||||
file = popen(command, "r");
|
||||
if (!file)
|
||||
{
|
||||
DBG1(DBG_IMC, "failed to run swid_generator command");
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
status = read_swid_tags(this, file);
|
||||
pclose(file);
|
||||
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool collect_tags(private_swima_collector_t *this, char *pathname,
|
||||
swima_inventory_t *targets, bool is_swidtag_dir)
|
||||
{
|
||||
char *rel_name, *abs_name, *suffix, *pos;
|
||||
chunk_t *swid_tag, sw_id, sw_locator;
|
||||
swima_record_t *sw_record;
|
||||
struct stat st;
|
||||
bool success = FALSE, skip, is_new_swidtag_dir;
|
||||
enumerator_t *enumerator;
|
||||
int i;
|
||||
|
||||
enumerator = enumerator_create_directory(pathname);
|
||||
if (!enumerator)
|
||||
{
|
||||
DBG1(DBG_IMC, "directory '%s' can not be opened, %s",
|
||||
pathname, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
|
||||
{
|
||||
if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
skip = FALSE;
|
||||
|
||||
for (i = 0; i < countof(skip_directories); i++)
|
||||
{
|
||||
if (streq(abs_name, skip_directories[i]))
|
||||
{
|
||||
skip = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
is_new_swidtag_dir = streq(rel_name, "swidtag");
|
||||
if (is_new_swidtag_dir)
|
||||
{
|
||||
DBG2(DBG_IMC, "entering %s", pathname);
|
||||
}
|
||||
if (!collect_tags(this, abs_name, targets, is_swidtag_dir ||
|
||||
is_new_swidtag_dir))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
if (is_new_swidtag_dir)
|
||||
{
|
||||
DBG2(DBG_IMC, "leaving %s", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_swidtag_dir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* found a swidtag file? */
|
||||
suffix = strstr(rel_name, ".swidtag");
|
||||
if (!suffix)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* load the swidtag file */
|
||||
swid_tag = chunk_map(abs_name, FALSE);
|
||||
if (!swid_tag)
|
||||
{
|
||||
DBG1(DBG_IMC, " opening '%s' failed: %s", abs_name,
|
||||
strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* extract software identity from SWID tag */
|
||||
if (extract_sw_id(*swid_tag, &sw_id) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IMC, "software id could not be extracted from SWID tag");
|
||||
chunk_unmap(swid_tag);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* In case of a targeted request */
|
||||
if (targets->get_count(targets))
|
||||
{
|
||||
enumerator_t *target_enumerator;
|
||||
swima_record_t *target;
|
||||
bool match = FALSE;
|
||||
|
||||
target_enumerator = targets->create_enumerator(targets);
|
||||
while (target_enumerator->enumerate(target_enumerator, &target))
|
||||
{
|
||||
if (chunk_equals(target->get_sw_id(target, NULL), sw_id))
|
||||
{
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
target_enumerator->destroy(target_enumerator);
|
||||
|
||||
if (!match)
|
||||
{
|
||||
chunk_unmap(swid_tag);
|
||||
chunk_free(&sw_id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
DBG2(DBG_IMC, " %s", rel_name);
|
||||
|
||||
pos = strstr(pathname, "/swidtag");
|
||||
sw_locator = pos ? chunk_create(pathname, pos - pathname) : chunk_empty;
|
||||
sw_record = swima_record_create(0, sw_id, sw_locator);
|
||||
sw_record->set_source_id(sw_record, SOURCE_ID_COLLECTOR);
|
||||
if (!this->sw_id_only)
|
||||
{
|
||||
sw_record->set_record(sw_record, *swid_tag);
|
||||
}
|
||||
this->inventory->add(this->inventory, sw_record);
|
||||
chunk_unmap(swid_tag);
|
||||
chunk_free(&sw_id);
|
||||
}
|
||||
success = TRUE;
|
||||
|
||||
end:
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
|
||||
private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
|
||||
{
|
||||
char *directory, *generator;
|
||||
bool pretty, full;
|
||||
status_t status;
|
||||
|
||||
directory = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.imc-swima.swid_directory",
|
||||
SWID_DIRECTORY, lib->ns);
|
||||
generator = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.imc-swima.swid_generator",
|
||||
SWID_GENERATOR, lib->ns);
|
||||
pretty = lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.imc-swima.swid_pretty",
|
||||
FALSE, lib->ns);
|
||||
full = lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.imc-swima.swid_full",
|
||||
FALSE, lib->ns);
|
||||
|
||||
/**
|
||||
* Re-initialize collector
|
||||
*/
|
||||
this->sw_id_only = sw_id_only;
|
||||
this->inventory->clear(this->inventory);
|
||||
|
||||
/**
|
||||
* Source 1: Tags are generated by a package manager
|
||||
*/
|
||||
if (sw_id_only && this->db)
|
||||
{
|
||||
status = retrieve_inventory(this, targets);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = generate_tags(this, generator, targets, pretty, full);
|
||||
}
|
||||
|
||||
/**
|
||||
* Source 2: Collect swidtag files by iteratively entering all
|
||||
* directories in the tree under the "directory" path.
|
||||
*/
|
||||
collect_tags(this, directory, targets, FALSE);
|
||||
|
||||
return status == SUCCESS ? this->inventory : NULL;
|
||||
}
|
||||
|
||||
METHOD(swima_collector_t, collect_events, swima_events_t*,
|
||||
private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
|
||||
{
|
||||
if (!sw_id_only || !this->db)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-initialize collector
|
||||
*/
|
||||
this->sw_id_only = sw_id_only;
|
||||
this->events->clear(this->events);
|
||||
|
||||
return retrieve_events(this, targets) == SUCCESS ? this->events : NULL;
|
||||
}
|
||||
|
||||
METHOD(swima_collector_t, destroy, void,
|
||||
private_swima_collector_t *this)
|
||||
{
|
||||
DESTROY_IF(this->db);
|
||||
this->inventory->destroy(this->inventory);
|
||||
this->events->destroy(this->events);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
swima_collector_t *swima_collector_create(void)
|
||||
{
|
||||
private_swima_collector_t *this;
|
||||
char *database;
|
||||
uint32_t last_eid = 1, eid_epoch = 0x11223344;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.collect_inventory = _collect_inventory,
|
||||
.collect_events = _collect_events,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.inventory = swima_inventory_create(),
|
||||
.events = swima_events_create(),
|
||||
);
|
||||
|
||||
database = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.imc-swima.swid_database", NULL, lib->ns);
|
||||
|
||||
/* If we have an URI, try to connect to sw_collector database */
|
||||
if (database)
|
||||
{
|
||||
database_t *db = lib->db->create(lib->db, database);
|
||||
|
||||
if (db)
|
||||
{
|
||||
enumerator_t *e;
|
||||
|
||||
/* Get last event ID and corresponding epoch */
|
||||
e = db->query(db,
|
||||
"SELECT id, epoch FROM events ORDER BY timestamp DESC",
|
||||
DB_UINT, DB_UINT);
|
||||
if (!e || !e->enumerate(e, &last_eid, &eid_epoch))
|
||||
{
|
||||
DBG1(DBG_IMC, "database query for last event failed");
|
||||
DESTROY_IF(e);
|
||||
db->destroy(db);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The query worked, attach collector database permanently */
|
||||
e->destroy(e);
|
||||
this->db = db;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IMC, "opening sw-collector database URI '%s' failed",
|
||||
database);
|
||||
}
|
||||
}
|
||||
if (!this->db)
|
||||
{
|
||||
/* Set the event ID epoch and last event ID smanually */
|
||||
eid_epoch = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.imc-swima.eid_epoch",
|
||||
eid_epoch, lib->ns);
|
||||
}
|
||||
this->inventory->set_eid(this->inventory, last_eid, eid_epoch);
|
||||
this->events->set_eid(this->events, last_eid, eid_epoch);
|
||||
|
||||
return &this->public;
|
||||
}
|
68
src/libimcv/swima/swima_collector.h
Normal file
68
src/libimcv/swima/swima_collector.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_collector swima_collector
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_COLLECTOR_H_
|
||||
#define SWIMA_COLLECTOR_H_
|
||||
|
||||
#include "swima/swima_inventory.h"
|
||||
#include "swima/swima_events.h"
|
||||
|
||||
typedef struct swima_collector_t swima_collector_t;
|
||||
|
||||
/**
|
||||
* Class collecting Software [Identity] Inventory
|
||||
*/
|
||||
struct swima_collector_t {
|
||||
|
||||
/**
|
||||
* Collect the Software [Identity] Inventory
|
||||
*
|
||||
* @param sw_id_only TRUE to request Software Identity Inventory only
|
||||
* @param targets Software Identity targets
|
||||
* @return Software [Identity] Inventory
|
||||
*/
|
||||
swima_inventory_t* (*collect_inventory)(swima_collector_t *this,
|
||||
bool sw_id_only,
|
||||
swima_inventory_t *targets);
|
||||
|
||||
/**
|
||||
* Collect Software [Identity] Events
|
||||
*
|
||||
* @param sw_id_only TRUE to request Software Identity Inventory only
|
||||
* @param targets Software Identity targets
|
||||
* @return Software [Identity] Events
|
||||
*/
|
||||
swima_events_t* (*collect_events)(swima_collector_t *this,
|
||||
bool sw_id_only,
|
||||
swima_inventory_t *targets);
|
||||
|
||||
/**
|
||||
* Destroys a swima_collector_t object.
|
||||
*/
|
||||
void (*destroy)(swima_collector_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a swima_collector_t object
|
||||
*/
|
||||
swima_collector_t* swima_collector_create(void);
|
||||
|
||||
#endif /** SWIMA_COLLECTOR_H_ @}*/
|
28
src/libimcv/swima/swima_data_model.c
Normal file
28
src/libimcv/swima/swima_data_model.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima/swima_data_model.h"
|
||||
|
||||
/**
|
||||
* ISO/IEC 19770-2-2015: Information Technology - Software Asset Management -
|
||||
* Part 2: Software Identification Tag
|
||||
*/
|
||||
pen_type_t swima_data_model_iso_2015_swid_xml = { PEN_IETF, 1 };
|
||||
|
||||
/**
|
||||
* ISO/IEC 19770-2-2009: Information Technology - Software Asset Management -
|
||||
* Part 2: Software Identification Tag
|
||||
*/
|
||||
pen_type_t swima_data_model_iso_2009_swid_xml = { PEN_IETF, 2 };
|
38
src/libimcv/swima/swima_data_model.h
Normal file
38
src/libimcv/swima/swima_data_model.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_data_model swima_data_model
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_DATA_MODEL_H_
|
||||
#define SWIMA_DATA_MODEL_H_
|
||||
|
||||
#include <pen/pen.h>
|
||||
|
||||
/**
|
||||
* ISO/IEC 19770-2-2015: Information Technology - Software Asset Management -
|
||||
* Part 2: Software Identification Tag
|
||||
*/
|
||||
extern pen_type_t swima_data_model_iso_2015_swid_xml;
|
||||
|
||||
/**
|
||||
* ISO/IEC 19770-2-2009: Information Technology - Software Asset Management -
|
||||
* Part 2: Software Identification Tag
|
||||
*/
|
||||
extern pen_type_t swima_data_model_iso_2009_swid_xml;
|
||||
|
||||
#endif /** SWIMA_DATA_MODEL_H_ @}*/
|
77
src/libimcv/swima/swima_error.c
Normal file
77
src/libimcv/swima/swima_error.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_error.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
|
||||
/**
|
||||
* SW_ERROR, SW_SUBSCRIPTION_DENIED_ERROR and SW_SUBSCRIPTION_ID_REUSE_ERROR
|
||||
*
|
||||
* 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Copy of Request ID / Subscription ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Description (variable length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* SW_RESPONSE_TOO_LARGE_ERROR
|
||||
*
|
||||
* 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Copy of Request ID / Subscription ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Maximum Allowed Size |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Description (variable length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t* swima_error_create(pa_tnc_error_code_t code, uint32_t request_id,
|
||||
uint32_t max_attr_size, char *description)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
chunk_t msg_info;
|
||||
pa_tnc_attr_t *attr;
|
||||
pen_type_t error_code;
|
||||
|
||||
error_code = pen_type_create( PEN_IETF, code);
|
||||
writer = bio_writer_create(4);
|
||||
writer->write_uint32(writer, request_id);
|
||||
|
||||
if (code == PA_ERROR_SW_RESPONSE_TOO_LARGE)
|
||||
{
|
||||
writer->write_uint32(writer, max_attr_size);
|
||||
}
|
||||
|
||||
if (description)
|
||||
{
|
||||
writer->write_data(writer, chunk_from_str(description));
|
||||
}
|
||||
msg_info = writer->get_buf(writer);
|
||||
attr = ietf_attr_pa_tnc_error_create(error_code, msg_info);
|
||||
writer->destroy(writer);
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
43
src/libimcv/swima/swima_error.h
Normal file
43
src/libimcv/swima/swima_error.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_error swima_error
|
||||
* @{ @ingroup libimcv_swid
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_ERROR_H_
|
||||
#define SWIMA_ERROR_H_
|
||||
|
||||
typedef enum swima_error_code_t swima_error_code_t;
|
||||
|
||||
#include "pa_tnc/pa_tnc_attr.h"
|
||||
#include "ietf/ietf_attr_pa_tnc_error.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Creates a SWIMA Error Attribute
|
||||
* see section 5.16 of IETF SW Inventory Message and Attributes for PA-TNC
|
||||
*
|
||||
* @param code PA-TNC error code
|
||||
* @param request SWID request ID
|
||||
* @param max_attr_size Maximum PA-TNC attribute size (if applicable)
|
||||
* @param description Optional description string or NULL
|
||||
*/
|
||||
pa_tnc_attr_t* swima_error_create(pa_tnc_error_code_t code, uint32_t request,
|
||||
uint32_t max_attr_size, char *description);
|
||||
|
||||
#endif /** SWIMA_ERROR_H_ @}*/
|
124
src/libimcv/swima/swima_event.c
Normal file
124
src/libimcv/swima/swima_event.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_event.h"
|
||||
#include "swima_data_model.h"
|
||||
|
||||
typedef struct private_swima_event_t private_swima_event_t;
|
||||
|
||||
/**
|
||||
* Private data of a swima_event_t object.
|
||||
*
|
||||
*/
|
||||
struct private_swima_event_t {
|
||||
|
||||
/**
|
||||
* Public swima_event_t interface.
|
||||
*/
|
||||
swima_event_t public;
|
||||
|
||||
/**
|
||||
* Event ID
|
||||
*/
|
||||
uint32_t eid;
|
||||
|
||||
/**
|
||||
* Timestamp
|
||||
*/
|
||||
chunk_t timestamp;
|
||||
|
||||
/**
|
||||
* Action
|
||||
*/
|
||||
uint8_t action;
|
||||
|
||||
/**
|
||||
* Software [Identifier] record
|
||||
*/
|
||||
swima_record_t *sw_record;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(swima_event_t, get_eid, uint32_t,
|
||||
private_swima_event_t *this, chunk_t *timestamp)
|
||||
{
|
||||
if (timestamp)
|
||||
{
|
||||
*timestamp = this->timestamp;
|
||||
}
|
||||
return this->eid;
|
||||
}
|
||||
|
||||
METHOD(swima_event_t, get_action, uint8_t,
|
||||
private_swima_event_t *this)
|
||||
{
|
||||
return this->action;
|
||||
}
|
||||
|
||||
METHOD(swima_event_t, get_sw_record, swima_record_t*,
|
||||
private_swima_event_t *this)
|
||||
{
|
||||
return this->sw_record;
|
||||
}
|
||||
|
||||
|
||||
METHOD(swima_event_t, get_ref, swima_event_t*,
|
||||
private_swima_event_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
METHOD(swima_event_t, destroy, void,
|
||||
private_swima_event_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->sw_record->destroy(this->sw_record);
|
||||
free(this->timestamp.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
swima_event_t *swima_event_create(uint32_t eid, chunk_t timestamp,
|
||||
uint8_t action, swima_record_t *sw_record)
|
||||
{
|
||||
private_swima_event_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_eid = _get_eid,
|
||||
.get_action = _get_action,
|
||||
.get_sw_record = _get_sw_record,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.eid = eid,
|
||||
.timestamp = chunk_clone(timestamp),
|
||||
.action = action,
|
||||
.sw_record = sw_record,
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
87
src/libimcv/swima/swima_event.h
Normal file
87
src/libimcv/swima/swima_event.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_event swima_event
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_EVENT_H_
|
||||
#define SWIMA_EVENT_H_
|
||||
|
||||
#include "swima_record.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#define SWIMA_EVENT_ACTION_CREATION 1
|
||||
#define SWIMA_EVENT_ACTION_DELETION 2
|
||||
#define SWIMA_EVENT_ACTION_ALTERATION 3
|
||||
#define SWIMA_EVENT_ACTION_LAST 3
|
||||
|
||||
typedef struct swima_event_t swima_event_t;
|
||||
|
||||
/**
|
||||
* Class storing a Software [Identifier] event
|
||||
*/
|
||||
struct swima_event_t {
|
||||
|
||||
/**
|
||||
* Get Event ID and optionally the associated timestamp
|
||||
*
|
||||
* @param timestamp Timestamp associated with Event
|
||||
* @return Event ID
|
||||
*/
|
||||
uint32_t (*get_eid)(swima_event_t *this, chunk_t *timestamp);
|
||||
|
||||
/**
|
||||
* Get Action associated with Event
|
||||
*
|
||||
* @return Action associated with event
|
||||
*/
|
||||
uint8_t (*get_action)(swima_event_t *this);
|
||||
|
||||
/**
|
||||
* Get Software [Identifier] record
|
||||
*
|
||||
* @return Software [Identifier] record
|
||||
*/
|
||||
swima_record_t* (*get_sw_record)(swima_event_t *this);
|
||||
|
||||
/**
|
||||
* Get a new reference to a swima_event object
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
swima_event_t* (*get_ref)(swima_event_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a swima_event_t object.
|
||||
*/
|
||||
void (*destroy)(swima_event_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a swima_event_t object
|
||||
*
|
||||
* @param eid Event ID
|
||||
* @param timestamp Time of Event
|
||||
* @param action Action (CREATION, DELETION, ALTERATION)
|
||||
* @param sw_record Software [Identifier] record
|
||||
*/
|
||||
swima_event_t* swima_event_create(uint32_t eid, chunk_t timestamp,
|
||||
uint8_t action, swima_record_t *sw_record);
|
||||
|
||||
#endif /** SWIMA_EVENT_H_ @}*/
|
155
src/libimcv/swima/swima_events.c
Normal file
155
src/libimcv/swima/swima_events.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_events.h"
|
||||
#include "swima_record.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_swima_events_t private_swima_events_t;
|
||||
|
||||
/**
|
||||
* Private data of a swima_events_t object.
|
||||
*
|
||||
*/
|
||||
struct private_swima_events_t {
|
||||
|
||||
/**
|
||||
* Public swima_events_t interface.
|
||||
*/
|
||||
swima_events_t public;
|
||||
|
||||
/**
|
||||
* Epoch of Event IDs
|
||||
*/
|
||||
uint32_t epoch;
|
||||
|
||||
/**
|
||||
* Last Event ID
|
||||
*/
|
||||
uint32_t last_eid;
|
||||
|
||||
/**
|
||||
* Last Consulted Event ID
|
||||
*/
|
||||
uint32_t last_consulted_eid;
|
||||
|
||||
/**
|
||||
* List of SW records
|
||||
*/
|
||||
linked_list_t *list;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
|
||||
};
|
||||
|
||||
METHOD(swima_events_t, add, void,
|
||||
private_swima_events_t *this, swima_event_t *event)
|
||||
{
|
||||
this->list->insert_last(this->list, event);
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, get_count, int,
|
||||
private_swima_events_t *this)
|
||||
{
|
||||
return this->list->get_count(this->list);
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, set_eid, void,
|
||||
private_swima_events_t *this, uint32_t eid, uint32_t epoch)
|
||||
{
|
||||
this->last_eid = this->last_consulted_eid = eid;
|
||||
this->epoch = epoch;
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, set_last_eid, void,
|
||||
private_swima_events_t *this, uint32_t last_eid)
|
||||
{
|
||||
this->last_eid = last_eid;
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, get_eid, uint32_t,
|
||||
private_swima_events_t *this, uint32_t *epoch, uint32_t *last_eid)
|
||||
{
|
||||
if (epoch)
|
||||
{
|
||||
*epoch = this->epoch;
|
||||
}
|
||||
if (last_eid)
|
||||
{
|
||||
*last_eid = this->last_eid;
|
||||
}
|
||||
return this->last_consulted_eid;
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, create_enumerator, enumerator_t*,
|
||||
private_swima_events_t *this)
|
||||
{
|
||||
return this->list->create_enumerator(this->list);
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, get_ref, swima_events_t*,
|
||||
private_swima_events_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, clear, void,
|
||||
private_swima_events_t *this)
|
||||
{
|
||||
this->list->destroy_offset(this->list, offsetof(swima_event_t, destroy));
|
||||
this->list = linked_list_create();
|
||||
}
|
||||
|
||||
METHOD(swima_events_t, destroy, void,
|
||||
private_swima_events_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->list->destroy_offset(this->list, offsetof(swima_event_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
swima_events_t *swima_events_create(void)
|
||||
{
|
||||
private_swima_events_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add = _add,
|
||||
.get_count = _get_count,
|
||||
.set_eid = _set_eid,
|
||||
.set_last_eid = _set_last_eid,
|
||||
.get_eid = _get_eid,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.get_ref = _get_ref,
|
||||
.clear = _clear,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.list = linked_list_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
106
src/libimcv/swima/swima_events.h
Normal file
106
src/libimcv/swima/swima_events.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_events swima_events
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_EVENTS_H_
|
||||
#define SWIMA_EVENTS_H_
|
||||
|
||||
#define SWIMA_MAX_ATTR_SIZE 10000000
|
||||
|
||||
#include "swima_event.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct swima_events_t swima_events_t;
|
||||
|
||||
/**
|
||||
* Class managing list of Software [Identifier] Events
|
||||
*/
|
||||
struct swima_events_t {
|
||||
|
||||
/**
|
||||
* Add event to list
|
||||
*
|
||||
* @param event Event to be added
|
||||
*/
|
||||
void (*add)(swima_events_t *this, swima_event_t *event);
|
||||
|
||||
/**
|
||||
* Get the number of events in the event list
|
||||
*
|
||||
* @return Number of events
|
||||
*/
|
||||
int (*get_count)(swima_events_t *this);
|
||||
|
||||
/**
|
||||
* Set both the Last and Last Consulted Event ID
|
||||
*
|
||||
* @param Last [Consulted] Event ID
|
||||
* @param Epoch of event IDs
|
||||
*/
|
||||
void (*set_eid)(swima_events_t *this, uint32_t eid, uint32_t epoch);
|
||||
|
||||
/**
|
||||
* Set Last Event ID if different from Last Consulted Event ID
|
||||
*
|
||||
* @param last_eid Last Event ID
|
||||
*/
|
||||
void (*set_last_eid)(swima_events_t *this, uint32_t last_eid);
|
||||
|
||||
/**
|
||||
* Get both the Last and Last Consulted Event ID
|
||||
*
|
||||
* @param eid_epoch Event ID Epoch
|
||||
* @param last_eid Last Event ID
|
||||
* @return Last Consulted Event ID
|
||||
*/
|
||||
uint32_t (*get_eid)(swima_events_t *this, uint32_t *epoch, uint32_t *last_eid);
|
||||
|
||||
/**
|
||||
* Create an event enumerator
|
||||
*
|
||||
* @return Enumerator returning events
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(swima_events_t *this);
|
||||
|
||||
/**
|
||||
* Get a new reference to a swima_events object
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
swima_events_t* (*get_ref)(swima_events_t *this);
|
||||
|
||||
/**
|
||||
* Clears the events, keeping the eid and epoch values.
|
||||
*/
|
||||
void (*clear)(swima_events_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a swima_events_t object.
|
||||
*/
|
||||
void (*destroy)(swima_events_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a swima_events_t object
|
||||
*/
|
||||
swima_events_t* swima_events_create(void);
|
||||
|
||||
#endif /** SWIMA_EVENTS_H_ @}*/
|
140
src/libimcv/swima/swima_inventory.c
Normal file
140
src/libimcv/swima/swima_inventory.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_inventory.h"
|
||||
#include "swima_record.h"
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_swima_inventory_t private_swima_inventory_t;
|
||||
|
||||
/**
|
||||
* Private data of a swima_inventory_t object.
|
||||
*
|
||||
*/
|
||||
struct private_swima_inventory_t {
|
||||
|
||||
/**
|
||||
* Public swima_inventory_t interface.
|
||||
*/
|
||||
swima_inventory_t public;
|
||||
|
||||
/**
|
||||
* Earliest or last event ID of the inventory
|
||||
*/
|
||||
uint32_t eid;
|
||||
|
||||
/**
|
||||
* Epoch of event IDs
|
||||
*/
|
||||
uint32_t epoch;
|
||||
|
||||
/**
|
||||
* List of SW records
|
||||
*/
|
||||
linked_list_t *list;
|
||||
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
|
||||
};
|
||||
|
||||
METHOD(swima_inventory_t, add, void,
|
||||
private_swima_inventory_t *this, swima_record_t *record)
|
||||
{
|
||||
this->list->insert_last(this->list, record);
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, get_count, int,
|
||||
private_swima_inventory_t *this)
|
||||
{
|
||||
return this->list->get_count(this->list);
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, set_eid, void,
|
||||
private_swima_inventory_t *this, uint32_t eid, uint32_t epoch)
|
||||
{
|
||||
this->eid = eid;
|
||||
this->epoch = epoch;
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, get_eid, uint32_t,
|
||||
private_swima_inventory_t *this, uint32_t *epoch)
|
||||
{
|
||||
if (epoch)
|
||||
{
|
||||
*epoch = this->epoch;
|
||||
}
|
||||
return this->eid;
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, create_enumerator, enumerator_t*,
|
||||
private_swima_inventory_t *this)
|
||||
{
|
||||
return this->list->create_enumerator(this->list);
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, get_ref, swima_inventory_t*,
|
||||
private_swima_inventory_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, clear, void,
|
||||
private_swima_inventory_t *this)
|
||||
{
|
||||
this->list->destroy_offset(this->list, offsetof(swima_record_t, destroy));
|
||||
this->list = linked_list_create();
|
||||
}
|
||||
|
||||
METHOD(swima_inventory_t, destroy, void,
|
||||
private_swima_inventory_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
this->list->destroy_offset(this->list, offsetof(swima_record_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
swima_inventory_t *swima_inventory_create(void)
|
||||
{
|
||||
private_swima_inventory_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add = _add,
|
||||
.get_count = _get_count,
|
||||
.set_eid = _set_eid,
|
||||
.get_eid = _get_eid,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.get_ref = _get_ref,
|
||||
.clear = _clear,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.list = linked_list_create(),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
99
src/libimcv/swima/swima_inventory.h
Normal file
99
src/libimcv/swima/swima_inventory.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_inventory swima_inventory
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_INVENTORY_H_
|
||||
#define SWIMA_INVENTORY_H_
|
||||
|
||||
#define SWIMA_MAX_ATTR_SIZE 10000000
|
||||
|
||||
#include "swima_record.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct swima_inventory_t swima_inventory_t;
|
||||
|
||||
/**
|
||||
* Class managing software inventory
|
||||
*/
|
||||
struct swima_inventory_t {
|
||||
|
||||
/**
|
||||
* Add evidence record to software inventory
|
||||
*
|
||||
* @param record Software evidence record to be added
|
||||
*/
|
||||
void (*add)(swima_inventory_t *this, swima_record_t *record);
|
||||
|
||||
/**
|
||||
* Get the number of evidence records in the software inventory
|
||||
*
|
||||
* @return Number evidence records
|
||||
*/
|
||||
int (*get_count)(swima_inventory_t *this);
|
||||
|
||||
/**
|
||||
* Set the earliest or last event ID of the inventory
|
||||
*
|
||||
* @param Event ID
|
||||
* @param Epoch of event IDs
|
||||
*/
|
||||
void (*set_eid)(swima_inventory_t *this, uint32_t eid, uint32_t epoch);
|
||||
|
||||
/**
|
||||
* Get the earliest or last event ID of the inventory
|
||||
*
|
||||
* @param Epoch of event IDs
|
||||
* @return Event ID
|
||||
*/
|
||||
uint32_t (*get_eid)(swima_inventory_t *this, uint32_t *epoch);
|
||||
|
||||
/**
|
||||
* Create a software inventory evidence record enumerator
|
||||
*
|
||||
* @return Enumerator returning evidence records
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(swima_inventory_t *this);
|
||||
|
||||
/**
|
||||
* Get a new reference to a swima_inventory object
|
||||
*
|
||||
* @return This, with an increased refcount
|
||||
*/
|
||||
swima_inventory_t* (*get_ref)(swima_inventory_t *this);
|
||||
|
||||
/**
|
||||
* Clears the inventory, keeping the eid and epoch values
|
||||
*/
|
||||
void (*clear)(swima_inventory_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a swima_inventory_t object
|
||||
*/
|
||||
void (*destroy)(swima_inventory_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a swima_inventory_t object
|
||||
*
|
||||
*/
|
||||
swima_inventory_t* swima_inventory_create(void);
|
||||
|
||||
#endif /** SWIMA_INVENTORY_H_ @}*/
|
174
src/libimcv/swima/swima_record.c
Normal file
174
src/libimcv/swima/swima_record.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "swima_record.h"
|
||||
#include "swima_data_model.h"
|
||||
|
||||
typedef struct private_swima_record_t private_swima_record_t;
|
||||
|
||||
/**
|
||||
* Private data of a swima_record_t object.
|
||||
*
|
||||
*/
|
||||
struct private_swima_record_t {
|
||||
|
||||
/**
|
||||
* Public swima_record_t interface.
|
||||
*/
|
||||
swima_record_t public;
|
||||
|
||||
/**
|
||||
* Record ID
|
||||
*/
|
||||
uint32_t record_id;
|
||||
|
||||
/**
|
||||
* Software Identity
|
||||
*/
|
||||
chunk_t sw_id;
|
||||
|
||||
/**
|
||||
* Optional Software Locator
|
||||
*/
|
||||
chunk_t sw_locator;
|
||||
|
||||
/**
|
||||
* Data Model
|
||||
*/
|
||||
pen_type_t data_model;
|
||||
|
||||
/**
|
||||
* Source ID
|
||||
*/
|
||||
uint8_t source_id;
|
||||
|
||||
/**g
|
||||
* Optional Software Inventory Evidence Record
|
||||
*/
|
||||
chunk_t record;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(swima_record_t, get_record_id, uint32_t,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
return this->record_id;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, get_sw_id, chunk_t,
|
||||
private_swima_record_t *this, chunk_t *sw_locator)
|
||||
{
|
||||
if (sw_locator)
|
||||
{
|
||||
*sw_locator = this->sw_locator;
|
||||
}
|
||||
return this->sw_id;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, set_data_model, void,
|
||||
private_swima_record_t *this, pen_type_t data_model)
|
||||
{
|
||||
this->data_model = data_model;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, get_data_model, pen_type_t,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
return this->data_model;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, set_source_id, void,
|
||||
private_swima_record_t *this, uint8_t source_id)
|
||||
{
|
||||
this->source_id = source_id;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, get_source_id, uint8_t,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
return this->source_id;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, set_record, void,
|
||||
private_swima_record_t *this, chunk_t record)
|
||||
{
|
||||
chunk_free(&this->record);
|
||||
this->record = chunk_clone(record);
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, get_record, chunk_t,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
return this->record;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, get_ref, swima_record_t*,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
METHOD(swima_record_t, destroy, void,
|
||||
private_swima_record_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
free(this->sw_id.ptr);
|
||||
free(this->sw_locator.ptr);
|
||||
free(this->record.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
swima_record_t *swima_record_create(uint32_t record_id, chunk_t sw_id,
|
||||
chunk_t sw_locator)
|
||||
{
|
||||
private_swima_record_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_record_id = _get_record_id,
|
||||
.get_sw_id = _get_sw_id,
|
||||
.set_data_model = _set_data_model,
|
||||
.get_data_model = _get_data_model,
|
||||
.set_source_id = _set_source_id,
|
||||
.get_source_id = _get_source_id,
|
||||
.set_record = _set_record,
|
||||
.get_record = _get_record,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.record_id = record_id,
|
||||
.data_model = swima_data_model_iso_2015_swid_xml,
|
||||
.sw_id = chunk_clone(sw_id),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
if (sw_locator.len > 0)
|
||||
{
|
||||
this->sw_locator = chunk_clone(sw_locator);
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
115
src/libimcv/swima/swima_record.h
Normal file
115
src/libimcv/swima/swima_record.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup swima_record swima_record
|
||||
* @{ @ingroup libimcv_swima
|
||||
*/
|
||||
|
||||
#ifndef SWIMA_RECORD_H_
|
||||
#define SWIMA_RECORD_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <pen/pen.h>
|
||||
|
||||
typedef struct swima_record_t swima_record_t;
|
||||
|
||||
/**
|
||||
* Class storing a Software Inventory Evidence Collection record
|
||||
*/
|
||||
struct swima_record_t {
|
||||
|
||||
/**
|
||||
* Get Software Identifier and optional Software Location
|
||||
*
|
||||
* @return Record ID
|
||||
*/
|
||||
uint32_t (*get_record_id)(swima_record_t *this);
|
||||
|
||||
/**
|
||||
* Get Software Identifier and optional Software Location
|
||||
*
|
||||
* @param sw_locator Optional Software Locator
|
||||
* @return Software Identifier
|
||||
*/
|
||||
chunk_t (*get_sw_id)(swima_record_t *this, chunk_t *sw_locator);
|
||||
|
||||
/**
|
||||
* Set Data Model
|
||||
*
|
||||
* @param Data model type in PEN namespace
|
||||
*/
|
||||
void (*set_data_model)(swima_record_t *this, pen_type_t data_model);
|
||||
|
||||
/**
|
||||
* Get Data Model
|
||||
*
|
||||
* @return Data model type in PEN namespace
|
||||
*/
|
||||
pen_type_t (*get_data_model)(swima_record_t *this);
|
||||
|
||||
/**
|
||||
* Set Source ID
|
||||
*
|
||||
* @param Source ID
|
||||
*/
|
||||
void (*set_source_id)(swima_record_t *this, uint8_t source_id);
|
||||
|
||||
/**
|
||||
* Get Source ID
|
||||
*
|
||||
* @return Source ID
|
||||
*/
|
||||
uint8_t (*get_source_id)(swima_record_t *this);
|
||||
|
||||
/**
|
||||
* Set Software Inventory Evidence Record
|
||||
*
|
||||
* @param Software Inventory Evidence Record
|
||||
*/
|
||||
void (*set_record)(swima_record_t *this, chunk_t record);
|
||||
|
||||
/**
|
||||
* Get Software Inventory Evidence Record
|
||||
*
|
||||
* @return Software Inventory Evidence Record
|
||||
*/
|
||||
chunk_t (*get_record)(swima_record_t *this);
|
||||
|
||||
/**
|
||||
* Get a new reference to a swima_record object
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
swima_record_t* (*get_ref)(swima_record_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a swima_record_t object.
|
||||
*/
|
||||
void (*destroy)(swima_record_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a swima_record_t object
|
||||
*
|
||||
* @param record_id Record ID
|
||||
* @param sw_id Software Identifierl
|
||||
* @param sw_locator Software Locator or empty chunk
|
||||
*/
|
||||
swima_record_t* swima_record_create(uint32_t record_id, chunk_t sw_id,
|
||||
chunk_t sw_locator);
|
||||
|
||||
#endif /** SWIMA_RECORD_H_ @}*/
|
Loading…
x
Reference in New Issue
Block a user