Version bump to 5.9.5rc1
[strongswan.git] / src / libimcv / suites / test_imcv_swima.c
1 /*
2 * Copyright (C) 2017-2018 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include "swima/swima_record.h"
19 #include "swima/swima_data_model.h"
20 #include "swima/swima_inventory.h"
21 #include "swima/swima_event.h"
22 #include "swima/swima_events.h"
23 #include "swima/swima_collector.h"
24 #include "ietf/swima/ietf_swima_attr_req.h"
25 #include "ietf/swima/ietf_swima_attr_sw_inv.h"
26 #include "ietf/swima/ietf_swima_attr_sw_ev.h"
27
28 static pen_type_t ita_data_model = { PEN_ITA, 0x19 };
29
30 static char* sw_id_str[] = {
31 "strongswan.org_strongSwan_5.3.3",
32 "strongswan.org_62251aa6-1a01-479b-aea6-f3dcf0ab1f1a"
33 };
34 static char sw_locator_str[] = "/usr/share/strongswan";
35
36 static char* sw_record_str[] = {
37 "<SoftwareIdentity tagId=\"abc\"></SoftwareIdentity>",
38 "<SoftwareIdentity tagId=\"def\"></SoftwareIdentity>"
39 };
40
41 START_TEST(test_imcv_swima_record)
42 {
43 chunk_t sw_id, sw_locator, locator;
44 swima_record_t *sw_record, *sw_record_cp;
45 uint32_t record_id = 1;
46 uint8_t source_id = 2;
47 chunk_t record = chunk_from_str(sw_record_str[0]);
48
49 sw_id = chunk_from_str(sw_id_str[0]);
50 sw_locator = chunk_from_str(sw_locator_str);
51
52 /* Software Identity with Software Locator */
53 sw_record = swima_record_create(record_id, sw_id, sw_locator),
54 ck_assert(sw_record);
55 sw_record_cp = sw_record->get_ref(sw_record);
56
57 ck_assert(record_id == sw_record->get_record_id(sw_record));
58 ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, NULL));
59 ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
60 ck_assert_chunk_eq(locator, sw_locator);
61
62 sw_record->set_data_model(sw_record, ita_data_model);
63 ck_assert(pen_type_equals(sw_record->get_data_model(sw_record),
64 ita_data_model));
65
66 sw_record->set_source_id(sw_record, source_id);
67 ck_assert(source_id == sw_record->get_source_id(sw_record));
68
69 sw_record->set_record(sw_record, record);
70 ck_assert_chunk_eq(record, sw_record->get_record(sw_record));
71
72 sw_record->destroy(sw_record);
73 sw_record_cp->destroy(sw_record);
74
75 /* Software Identity without Software Locator */
76 sw_record = swima_record_create(record_id, sw_id, chunk_empty),
77 ck_assert(sw_record);
78 ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
79 ck_assert(locator.ptr == NULL && locator.len == 0);
80
81 ck_assert(pen_type_equals(swima_data_model_iso_2015_swid_xml,
82 sw_record->get_data_model(sw_record)));
83
84 sw_record->destroy(sw_record);
85 }
86 END_TEST
87
88 typedef struct req_data_t req_data_t;
89
90 struct req_data_t {
91 uint8_t flags;
92 uint32_t request_id;
93 uint32_t earliest_eid;
94 uint32_t sw_id_count;
95 chunk_t value;
96 };
97
98 static req_data_t req_data[] = {
99 { IETF_SWIMA_ATTR_REQ_FLAG_NONE, 1, 0, 0, chunk_from_chars(
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
101 0x00, 0x00)
102 },
103 { IETF_SWIMA_ATTR_REQ_FLAG_R, 2, 15, 1, chunk_from_chars(
104 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
105 0x00, 0x0F, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
106 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
107 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
108 0x35, 0x2e, 0x33, 0x2e, 0x33)
109 },
110 { IETF_SWIMA_ATTR_REQ_FLAG_S, 3, 256, 2, chunk_from_chars(
111 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
112 0x01, 0x00, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
113 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
114 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
115 0x35, 0x2e, 0x33, 0x2e, 0x33, 0x00, 0x33, 0x73, 0x74, 0x72,
116 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72,
117 0x67, 0x5f, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36,
118 0x2d, 0x31, 0x61, 0x30, 0x31, 0x2d, 0x34, 0x37, 0x39, 0x62,
119 0x2d, 0x61, 0x65, 0x61, 0x36, 0x2d, 0x66, 0x33, 0x64, 0x63,
120 0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61)
121 },
122 };
123
124 START_TEST(test_imcv_swima_sw_req)
125 {
126 pen_type_t type;
127 pen_type_t pen_type = { PEN_IETF, IETF_ATTR_SWIMA_REQUEST };
128 pa_tnc_attr_t *attr, *attr1, *attr2;
129 ietf_swima_attr_req_t *c_attr;
130 swima_record_t *target;
131 swima_inventory_t *targets;
132 chunk_t sw_id, value;
133 enumerator_t *enumerator;
134 uint32_t offset;
135 int n;
136
137 attr = ietf_swima_attr_req_create(req_data[_i].flags,
138 req_data[_i].request_id);
139 ck_assert(attr);
140
141 type = attr->get_type(attr);
142 ck_assert(pen_type_equals(type, pen_type));
143
144 ck_assert(attr->get_noskip_flag(attr) == FALSE);
145 attr->set_noskip_flag(attr, TRUE);
146 ck_assert(attr->get_noskip_flag(attr) == TRUE);
147
148 targets = swima_inventory_create();
149 targets->set_eid(targets, req_data[_i].earliest_eid, 0);
150
151 for (n = 0; n < req_data[_i].sw_id_count; n++)
152 {
153 sw_id = chunk_from_str(sw_id_str[n]);
154 target = swima_record_create(0, sw_id, chunk_empty);
155 targets->add(targets, target);
156 }
157 c_attr = (ietf_swima_attr_req_t*)attr;
158 c_attr->set_targets(c_attr, targets);
159 c_attr->set_targets(c_attr, targets);
160 targets->destroy(targets);
161
162 attr->build(attr);
163 attr->build(attr);
164 value = attr->get_value(attr);
165 ck_assert_chunk_eq(value, req_data[_i].value);
166
167 attr1 = attr->get_ref(attr);
168 attr->destroy(attr);
169
170 attr2 = ietf_swima_attr_req_create_from_data(value.len, value);
171 ck_assert(attr2);
172
173 attr1->destroy(attr1);
174 ck_assert(attr2->process(attr2, &offset) == SUCCESS);
175
176 type = attr2->get_type(attr2);
177 ck_assert(pen_type_equals(type, pen_type));
178
179 c_attr = (ietf_swima_attr_req_t*)attr2;
180 ck_assert(c_attr->get_flags(c_attr) == req_data[_i].flags);
181 ck_assert(c_attr->get_request_id(c_attr) == req_data[_i].request_id);
182
183 targets = c_attr->get_targets(c_attr);
184 ck_assert(targets->get_eid(targets, NULL) == req_data[_i].earliest_eid);
185
186 enumerator = targets->create_enumerator(targets);
187 ck_assert(enumerator);
188 n = 0;
189 while (enumerator->enumerate(enumerator, &target))
190 {
191 sw_id = target->get_sw_id(target, NULL);
192 ck_assert(chunk_equals(sw_id, chunk_from_str(sw_id_str[n++])));
193 }
194 enumerator->destroy(enumerator);
195
196 attr2->destroy(attr2);
197 }
198 END_TEST
199
200 START_TEST(test_imcv_swima_sw_req_trunc)
201 {
202 pa_tnc_attr_t *attr;
203 chunk_t data;
204 uint32_t offset = 100;
205
206 /* Data smaller than minimum size */
207 attr = ietf_swima_attr_req_create_from_data(0, chunk_empty);
208 ck_assert(attr);
209 ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
210 attr->destroy(attr);
211
212 /* Truncate first SW ID */
213 data = req_data[2].value;
214 data.len = 14;
215 attr = ietf_swima_attr_req_create_from_data(data.len, data);
216 ck_assert(attr);
217 ck_assert(attr->process(attr, &offset) == FAILED && offset == 12);
218 attr->destroy(attr);
219
220 /* Truncate second SW ID */
221 data = req_data[2].value;
222 data.len = 47;
223 attr = ietf_swima_attr_req_create_from_data(data.len, data);
224 ck_assert(attr);
225 ck_assert(attr->process(attr, &offset) == FAILED && offset == 45);
226 attr->destroy(attr);
227
228 /* Segmentation */
229 data = req_data[2].value;
230 data.len = 50;
231 attr = ietf_swima_attr_req_create_from_data(req_data[2].value.len, data);
232 ck_assert(attr);
233 ck_assert(attr->process(attr, &offset) == NEED_MORE);
234 data = chunk_skip(req_data[2].value, 50);
235 attr->add_segment(attr, data);
236 ck_assert(attr->process(attr, &offset) == SUCCESS);
237 attr->destroy(attr);
238 }
239 END_TEST
240
241 static pen_type_t sw_inv_types[] = {
242 { PEN_IETF, IETF_ATTR_SW_INVENTORY },
243 { PEN_IETF, IETF_ATTR_SW_ID_INVENTORY }
244 };
245
246 typedef struct sw_inv_data_t sw_inv_data_t;
247
248 struct sw_inv_data_t {
249 uint8_t flags;
250 uint32_t request_id;
251 uint32_t eid_epoch;
252 uint32_t last_eid;
253 chunk_t value;
254 };
255
256 static sw_inv_data_t sw_inv_data[] = {
257 { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
258 chunk_from_chars(
259 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
260 0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
261 },
262 { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
263 chunk_from_chars(
264 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
265 0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
266 },
267 { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
268 chunk_from_chars(
269 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
270 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x73, 0x74,
272 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
273 0x72, 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,
274 0x77, 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,
276 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
277 0x74, 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,
278 0x61, 0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,
279 0x74, 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,
280 0x69, 0x74, 0x79, 0x3E)
281 },
282 { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
283 chunk_from_chars(
284 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
285 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x73, 0x74,
287 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
288 0x72, 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,
289 0x77, 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,
290 0x00)
291 },
292 { IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000034,
293 chunk_from_chars(
294 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
295 0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x73, 0x74,
297 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
298 0x72, 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,
299 0x77, 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,
301 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
302 0x74, 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,
303 0x61, 0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,
304 0x74, 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,
305 0x69, 0x74, 0x79, 0x3E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90,
306 0x2A, 0x19, 0x11, 0x00, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F,
307 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
308 0x5F, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D,
309 0x31, 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D,
310 0x61, 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66,
311 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,
313 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,
314 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x64, 0x65,
315 0x66, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,
316 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
317 0x79, 0x3E)
318 },
319 { IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000034,
320 chunk_from_chars(
321 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
322 0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x73, 0x74,
324 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
325 0x72, 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,
326 0x77, 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A, 0x19, 0x11,
328 0x00, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x73,
329 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F, 0x36, 0x32,
330 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31, 0x61, 0x30,
331 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61, 0x65, 0x61,
332 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30, 0x61, 0x62,
333 0x31, 0x66, 0x31, 0x61, 0x00, 0x00)
334 }
335 };
336
337 START_TEST(test_imcv_swima_inv)
338 {
339 pen_type_t type, data_model;
340 chunk_t sw_id, record, value;
341 ietf_swima_attr_sw_inv_t *c_attr;
342 pa_tnc_attr_t *attr, *attr1, *attr2;
343 swima_record_t *sw_record;
344 swima_inventory_t *sw_inv;
345 enumerator_t *enumerator;
346 uint32_t offset, epoch;
347 uint8_t source_id;
348 bool sw_id_only = _i % 2;
349 int n;
350
351 attr = ietf_swima_attr_sw_inv_create(sw_inv_data[_i].flags,
352 sw_inv_data[_i].request_id,
353 sw_id_only);
354
355 sw_inv = swima_inventory_create();
356 sw_inv->set_eid(sw_inv, sw_inv_data[_i].last_eid, sw_inv_data[_i].eid_epoch);
357 for (n = 0; n < _i/2; n++)
358 {
359 sw_id = chunk_from_str(sw_id_str[n]);
360 sw_record = swima_record_create(n, sw_id, chunk_empty);
361
362 if (n == 1)
363 {
364 sw_record->set_data_model(sw_record, ita_data_model);
365 sw_record->set_source_id(sw_record, 0x11);
366 }
367 if (!sw_id_only)
368 {
369 record = chunk_from_str(sw_record_str[n]);
370 sw_record->set_record(sw_record, record);
371 }
372 sw_inv->add(sw_inv, sw_record);
373 }
374 c_attr = (ietf_swima_attr_sw_inv_t*)attr;
375 c_attr->set_inventory(c_attr, sw_inv);
376 c_attr->set_inventory(c_attr, sw_inv);
377
378 attr->build(attr);
379 attr->build(attr);
380 sw_inv->destroy(sw_inv);
381
382 type = attr->get_type(attr);
383 ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
384
385 ck_assert(attr->get_noskip_flag(attr) == FALSE);
386 attr->set_noskip_flag(attr, TRUE);
387 ck_assert(attr->get_noskip_flag(attr) == TRUE);
388
389 value = attr->get_value(attr);
390 ck_assert_chunk_eq(value, sw_inv_data[_i].value);
391
392 attr1 = attr->get_ref(attr);
393 attr->destroy(attr);
394
395 attr2 = ietf_swima_attr_sw_inv_create_from_data(value.len, value,
396 sw_id_only);
397 ck_assert(attr2);
398 attr1->destroy(attr1);
399 ck_assert(attr2->process(attr2, &offset) == SUCCESS);
400
401 type = attr2->get_type(attr2);
402 ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
403
404 c_attr = (ietf_swima_attr_sw_inv_t*)attr2;
405 ck_assert(c_attr->get_flags(c_attr) == sw_inv_data[_i].flags);
406 ck_assert(c_attr->get_record_count(c_attr) == 0);
407 ck_assert(c_attr->get_request_id(c_attr) == sw_inv_data[_i].request_id);
408
409 sw_inv = c_attr->get_inventory(c_attr);
410 ck_assert(sw_inv->get_eid(sw_inv, NULL) == sw_inv_data[_i].last_eid);
411 ck_assert(sw_inv->get_eid(sw_inv, &epoch) == sw_inv_data[_i].last_eid);
412 ck_assert(epoch == sw_inv_data[_i].eid_epoch);
413 ck_assert(sw_inv);
414 ck_assert(sw_inv->get_count(sw_inv) == _i/2);
415
416 enumerator = sw_inv->create_enumerator(sw_inv);
417 ck_assert(enumerator);
418
419 n = 0;
420 while (enumerator->enumerate(enumerator, &sw_record))
421 {
422 ck_assert(sw_record->get_record_id(sw_record) == n);
423 data_model = sw_record->get_data_model(sw_record);
424 ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
425 swima_data_model_iso_2015_swid_xml));
426 source_id = sw_record->get_source_id(sw_record);
427 ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
428 n++;
429 }
430 enumerator->destroy(enumerator);
431 ck_assert(n == _i/2);
432
433 attr2->destroy(attr2);
434 }
435 END_TEST
436
437 /**
438 * Offsets in sw_inv_data[4].value
439 *
440 * 0 constant header
441 * 12 segment 1 - 12 octets
442 * 16 record_id
443 * 18 segment 2 - 6 octets
444 * 20 data_model_pen
445 * 22 segment 3 - 4 octets
446 * 23 segment 4 - 1 octet
447 * 23 data_model_type
448 * 24 segment 5 - 1 octet
449 * 24 source_id
450 * 25 segment 6 - 1 octet
451 * 25 reserved
452 * 26 sw_id
453 * 27 segment 7 - 2 octets
454 * 59 sw_locator
455 * 60 segment 8 - 33 octets
456 * 61 record
457 * 63 segment 9 - 3 octets
458 * 114 sw record 2
459 * 115 segment 10 - 52 octets
460 * 231 segment 11 - 117 octets
461 */
462
463 START_TEST(test_imcv_swima_sw_inv_trunc)
464 {
465 pa_tnc_attr_t *attr;
466 ietf_swima_attr_sw_inv_t *c_attr;
467 chunk_t data;
468 swima_inventory_t *sw_inv;
469 size_t len = sw_inv_data[4].value.len;
470 uint32_t offset = 100;
471
472 /* Data smaller than minimum size */
473 attr = ietf_swima_attr_sw_inv_create_from_data(0, chunk_empty, FALSE);
474 ck_assert(attr);
475 ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
476 attr->destroy(attr);
477
478 /* Length larger than data */
479 data = sw_inv_data[4].value;
480 attr = ietf_swima_attr_sw_inv_create_from_data(len + 2, data, FALSE);
481 ck_assert(attr);
482 ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
483 attr->destroy(attr);
484
485 /* Segment 1 truncates minimum size */
486 data = sw_inv_data[4].value;
487 data.len = 12;
488 attr = ietf_swima_attr_sw_inv_create_from_data(len, data, FALSE);
489 ck_assert(attr);
490 ck_assert(attr->process(attr, &offset) == NEED_MORE);
491
492 /* Segment 2 truncates record_id */
493 data = chunk_skip(sw_inv_data[4].value, 12);
494 data.len = 6;
495 attr->add_segment(attr, data);
496 ck_assert(attr->process(attr, &offset) == NEED_MORE);
497
498 /* Segment 3 truncates data_model_pen */
499 data = chunk_skip(sw_inv_data[4].value, 18);
500 data.len = 4;
501 attr->add_segment(attr, data);
502 ck_assert(attr->process(attr, &offset) == NEED_MORE);
503
504 /* Segment 4 truncates data_model_type */
505 data = chunk_skip(sw_inv_data[4].value, 22);
506 data.len = 1;
507 attr->add_segment(attr, data);
508 ck_assert(attr->process(attr, &offset) == NEED_MORE);
509
510 /* Segment 5 truncates source_id */
511 data = chunk_skip(sw_inv_data[4].value, 23);
512 data.len = 1;
513 attr->add_segment(attr, data);
514 ck_assert(attr->process(attr, &offset) == NEED_MORE);
515
516 /* Segment 6 truncates reserved */
517 data = chunk_skip(sw_inv_data[4].value, 24);
518 data.len = 1;
519 attr->add_segment(attr, data);
520 ck_assert(attr->process(attr, &offset) == NEED_MORE);
521
522 /* Segment 7 truncates sw_id */
523 data = chunk_skip(sw_inv_data[4].value, 25);
524 data.len = 2;
525 attr->add_segment(attr, data);
526 ck_assert(attr->process(attr, &offset) == NEED_MORE);
527
528 /* Segment 8 truncates sw_locator */
529 data = chunk_skip(sw_inv_data[4].value, 27);
530 data.len = 33;
531 attr->add_segment(attr, data);
532 ck_assert(attr->process(attr, &offset) == NEED_MORE);
533
534 /* Segment 9 truncates record */
535 data = chunk_skip(sw_inv_data[4].value, 60);
536 data.len = 3;
537 attr->add_segment(attr, data);
538 ck_assert(attr->process(attr, &offset) == NEED_MORE);
539
540 /* Segment 10 truncates second sw_record */
541 data = chunk_skip(sw_inv_data[4].value, 63);
542 data.len = 52;
543 attr->add_segment(attr, data);
544 ck_assert(attr->process(attr, &offset) == SUCCESS);
545
546 /* Process first inventory entry */
547 c_attr = (ietf_swima_attr_sw_inv_t*)attr;
548 sw_inv = c_attr->get_inventory(c_attr);
549 ck_assert(sw_inv->get_count(sw_inv) == 1);
550 c_attr->clear_inventory(c_attr);
551
552 /* Segment 11 truncates second sw_record */
553 data = chunk_skip(sw_inv_data[4].value, 115);
554 data.len = 117;
555 attr->add_segment(attr, data);
556 ck_assert(attr->process(attr, &offset) == SUCCESS);
557
558 /* Process second inventory entry */
559 sw_inv = c_attr->get_inventory(c_attr);
560 ck_assert(sw_inv->get_count(sw_inv) == 1);
561 c_attr->clear_inventory(c_attr);
562
563 attr->destroy(attr);
564 }
565 END_TEST
566
567 static char* sw_ev_timestamp_str[] = {
568 "2017-05-30T18:09:25Z",
569 "2017-06-14T15:38:00Z"
570 };
571
572 START_TEST(test_imcv_swima_event)
573 {
574 chunk_t sw_id, sw_timestamp, timestamp;
575 swima_event_t *sw_event, *sw_event_cp;
576 swima_record_t *sw_record;
577 uint32_t record_id = 1, eid = 7;
578 uint8_t action = SWIMA_EVENT_ACTION_CREATION;
579
580 sw_id = chunk_from_str(sw_id_str[0]);
581 sw_timestamp = chunk_from_str(sw_ev_timestamp_str[0]);
582
583 /* Software Identity without Software Locator */
584 sw_record = swima_record_create(record_id, sw_id, chunk_empty),
585 ck_assert(sw_record);
586
587 sw_event = swima_event_create(eid, sw_timestamp, action, sw_record);
588 ck_assert(sw_event);
589 sw_event_cp = sw_event->get_ref(sw_event);
590
591 ck_assert(sw_event->get_eid(sw_event, NULL) == eid);
592 ck_assert(sw_event->get_eid(sw_event, &timestamp) == eid);
593 ck_assert_chunk_eq(sw_timestamp, timestamp);
594 ck_assert(sw_event->get_action(sw_event) == action);
595 sw_event->destroy(sw_event);
596
597 sw_record = sw_event_cp->get_sw_record(sw_event_cp);
598 ck_assert(sw_record);
599 ck_assert(sw_record->get_record_id(sw_record) == record_id);
600 ck_assert_chunk_eq(sw_record->get_sw_id(sw_record, NULL), sw_id);
601 sw_event_cp->destroy(sw_event_cp);
602 }
603 END_TEST
604
605 static pen_type_t sw_ev_types[] = {
606 { PEN_IETF, IETF_ATTR_SW_EVENTS },
607 { PEN_IETF, IETF_ATTR_SW_ID_EVENTS }
608 };
609
610 typedef struct sw_ev_data_t sw_ev_data_t;
611
612 struct sw_ev_data_t {
613 uint8_t flags;
614 uint32_t request_id;
615 uint32_t eid_epoch;
616 uint32_t last_eid;
617 uint32_t last_consulted_eid;
618 chunk_t value;
619 };
620
621 static sw_ev_data_t sw_ev_data[] = {
622 { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
623 0x00000007, chunk_from_chars(
624 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
625 0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
626 },
627 { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
628 0x00000007, chunk_from_chars(
629 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
630 0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
631 },
632 { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
633 0x00000030, chunk_from_chars(
634 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
635 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
636 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
637 '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
638 ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
640 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
641 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
642 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,
644 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,
645 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61, 0x62,
646 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,
647 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
648 0x79, 0x3E)
649 },
650 { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
651 0x00000030, chunk_from_chars(
652 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
653 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
654 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
655 '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
656 ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
658 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
659 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
660 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00)
661 },
662 { IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000050,
663 0x00000034, chunk_from_chars(
664 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
665 0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
666 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
667 '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
668 ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
670 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
671 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
672 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,
674 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,
675 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61, 0x62,
676 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,
677 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
678 0x79, 0x3E, 0x00, 0x00, 0x00, 0x34, '2', '0', '1', '7',
679 '-', '0', '6', '-', '1', '4', 'T', '1', '5', ':',
680 '3', '8', ':', '0', '0', 'Z', 0x00, 0x00, 0x00, 0x01,
681 0x00, 0x90, 0x2A, 0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74,
682 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
683 0x72, 0x67, 0x5F, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61,
684 0x36, 0x2D, 0x31, 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39,
685 0x62, 0x2D, 0x61, 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64,
686 0x63, 0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,
688 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
689 0x74, 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,
690 0x64, 0x65, 0x66, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,
691 0x74, 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,
692 0x69, 0x74, 0x79, 0x3E)
693 },
694 { IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000050,
695 0x00000034, chunk_from_chars(
696 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
697 0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
698 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
699 '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
700 ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
702 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
703 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
704 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x34, '2', '0', '1', '7', '-', '0', '6',
706 '-', '1', '4', 'T', '1', '5', ':', '3', '8', ':',
707 '0', '0', 'Z', 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A,
708 0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E,
709 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F,
710 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31,
711 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61,
712 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30,
713 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00)
714 }
715 };
716
717 START_TEST(test_imcv_swima_ev)
718 {
719 pen_type_t type, data_model;
720 chunk_t sw_id, record, timestamp, value;
721 ietf_swima_attr_sw_ev_t *c_attr;
722 pa_tnc_attr_t *attr, *attr1, *attr2;
723 swima_record_t *sw_record;
724 swima_event_t *sw_event;
725 swima_events_t *sw_ev;
726 enumerator_t *enumerator;
727 uint32_t offset, epoch, eid, last_eid;
728 uint8_t source_id, action;
729 bool sw_id_only = _i % 2;
730 int n;
731
732 attr = ietf_swima_attr_sw_ev_create(sw_ev_data[_i].flags,
733 sw_ev_data[_i].request_id,
734 sw_id_only);
735 sw_ev = swima_events_create();
736 sw_ev->set_eid(sw_ev, sw_ev_data[_i].last_consulted_eid,
737 sw_ev_data[_i].eid_epoch);
738 if (sw_ev_data[_i].last_consulted_eid < sw_ev_data[_i].last_eid)
739 {
740 sw_ev->set_last_eid(sw_ev, sw_ev_data[_i].last_eid);
741 }
742
743 for (n = 0; n < _i/2; n++)
744 {
745 sw_id = chunk_from_str(sw_id_str[n]);
746 sw_record = swima_record_create(n, sw_id, chunk_empty);
747
748 if (n == 1)
749 {
750 sw_record->set_data_model(sw_record, ita_data_model);
751 sw_record->set_source_id(sw_record, 0x11);
752 }
753 if (!sw_id_only)
754 {
755 record = chunk_from_str(sw_record_str[n]);
756 sw_record->set_record(sw_record, record);
757 }
758 eid = 0x30 + 4 * n;
759 timestamp = chunk_from_str(sw_ev_timestamp_str[n]);
760 action = n + 1;
761 sw_event = swima_event_create(eid, timestamp, action, sw_record);
762 sw_ev->add(sw_ev, sw_event);
763 }
764 c_attr = (ietf_swima_attr_sw_ev_t*)attr;
765 c_attr->set_events(c_attr, sw_ev);
766 c_attr->set_events(c_attr, sw_ev);
767
768 attr->build(attr);
769 attr->build(attr);
770 sw_ev->destroy(sw_ev);
771
772 type = attr->get_type(attr);
773 ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
774
775 ck_assert(attr->get_noskip_flag(attr) == FALSE);
776 attr->set_noskip_flag(attr, TRUE);
777 ck_assert(attr->get_noskip_flag(attr) == TRUE);
778
779 value = attr->get_value(attr);
780 ck_assert_chunk_eq(value, sw_ev_data[_i].value);
781
782 attr1 = attr->get_ref(attr);
783 attr->destroy(attr);
784
785 attr2 = ietf_swima_attr_sw_ev_create_from_data(value.len, value,
786 sw_id_only);
787 ck_assert(attr2);
788 attr1->destroy(attr1);
789 ck_assert(attr2->process(attr2, &offset) == SUCCESS);
790
791 type = attr2->get_type(attr2);
792 ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
793
794 c_attr = (ietf_swima_attr_sw_ev_t*)attr2;
795 ck_assert(c_attr->get_flags(c_attr) == sw_ev_data[_i].flags);
796 ck_assert(c_attr->get_event_count(c_attr) == 0);
797 ck_assert(c_attr->get_request_id(c_attr) == sw_ev_data[_i].request_id);
798
799 sw_ev = c_attr->get_events(c_attr);
800 ck_assert(sw_ev);
801 eid = sw_ev->get_eid(sw_ev, NULL, NULL);
802 ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
803 eid = sw_ev->get_eid(sw_ev, &epoch, &last_eid);
804 ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
805 ck_assert(epoch == sw_ev_data[_i].eid_epoch);
806 ck_assert(last_eid == sw_ev_data[_i].last_eid);
807 ck_assert(sw_ev->get_count(sw_ev) == _i/2);
808
809 enumerator = sw_ev->create_enumerator(sw_ev);
810 ck_assert(enumerator);
811
812 n = 0;
813 while (enumerator->enumerate(enumerator, &sw_event))
814 {
815 ck_assert(sw_event->get_eid(sw_event, &timestamp) == 0x30 + 4 * n);
816 ck_assert_chunk_eq(timestamp, chunk_from_str(sw_ev_timestamp_str[n]));
817 sw_record = sw_event->get_sw_record(sw_event);
818 ck_assert(sw_record);
819 ck_assert(sw_record->get_record_id(sw_record) == n);
820 data_model = sw_record->get_data_model(sw_record);
821 ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
822 swima_data_model_iso_2015_swid_xml));
823 source_id = sw_record->get_source_id(sw_record);
824 ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
825 n++;
826 }
827 enumerator->destroy(enumerator);
828 ck_assert(n == _i/2);
829
830 attr2->destroy(attr2);
831 }
832 END_TEST
833
834
835 /**
836 * Offsets in sw_ev_data[4].value
837 *
838 * 0 constant header
839 * 16 segment 1 - 16 octets
840 * 20 eid
841 * 22 segment 2 - 6 octets
842 * 24 timestamp
843 * 26 segment 3 - 4 octets
844 * 44 record_id
845 * 46 segment 4 - 20 octets
846 * 48 data_model_pen
847 * 50 segment 5 - 4 octets
848 * 51 segment 6 - 1 octet
849 * 51 data_model_type
850 * 52 segment 7 - 1 octet
851 * 52 source_id
852 * 53 segment 8 - 1 octet
853 * 53 action
854 * 54 sw_id
855 * 55 segment 9 - 2 octets
856 * 87 sw_locator
857 * 88 segment 10 - 33 octets
858 * 89 record
859 * 91 segment 11 - 3 octets
860 * 142 sw record 2
861 * 143 segment 12 - 52 octets
862 * 284 segment 13 - 141 octets
863 */
864
865 START_TEST(test_imcv_swima_sw_ev_trunc)
866 {
867 pa_tnc_attr_t *attr;
868 ietf_swima_attr_sw_ev_t *c_attr;
869 chunk_t data;
870 swima_events_t *sw_ev;
871 size_t len = sw_ev_data[4].value.len;
872 uint32_t offset = 100;
873
874 /* Data smaller than minimum size */
875 attr = ietf_swima_attr_sw_ev_create_from_data(0, chunk_empty, FALSE);
876 ck_assert(attr);
877 ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
878 attr->destroy(attr);
879
880 /* Length larger than data */
881 data = sw_ev_data[4].value;
882 attr = ietf_swima_attr_sw_ev_create_from_data(len + 2, data, FALSE);
883 ck_assert(attr);
884 ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
885 attr->destroy(attr);
886
887 /* Segment 1 truncates minimum size */
888 data = sw_ev_data[4].value;
889 data.len = 16;
890 attr = ietf_swima_attr_sw_ev_create_from_data(len, data, FALSE);
891 ck_assert(attr);
892 ck_assert(attr->process(attr, &offset) == NEED_MORE);
893
894 /* Segment 2 truncates eid */
895 data = chunk_skip(sw_ev_data[4].value, 16);
896 data.len = 6;
897 attr->add_segment(attr, data);
898 ck_assert(attr->process(attr, &offset) == NEED_MORE);
899
900 /* Segment 3 truncates timestamp */
901 data = chunk_skip(sw_ev_data[4].value, 22);
902 data.len = 4;
903 attr->add_segment(attr, data);
904 ck_assert(attr->process(attr, &offset) == NEED_MORE);
905
906 /* Segment 4 truncates record_id */
907 data = chunk_skip(sw_ev_data[4].value, 26);
908 data.len = 20;
909 attr->add_segment(attr, data);
910 ck_assert(attr->process(attr, &offset) == NEED_MORE);
911
912 /* Segment 5 truncates data_model_pen */
913 data = chunk_skip(sw_ev_data[4].value, 46);
914 data.len = 4;
915 attr->add_segment(attr, data);
916 ck_assert(attr->process(attr, &offset) == NEED_MORE);
917
918 /* Segment 6 truncates data_model_type */
919 data = chunk_skip(sw_ev_data[4].value, 50);
920 data.len = 1;
921 attr->add_segment(attr, data);
922 ck_assert(attr->process(attr, &offset) == NEED_MORE);
923
924 /* Segment 7 truncates source_id */
925 data = chunk_skip(sw_ev_data[4].value, 51);
926 data.len = 1;
927 attr->add_segment(attr, data);
928 ck_assert(attr->process(attr, &offset) == NEED_MORE);
929
930 /* Segment 8 truncates action */
931 data = chunk_skip(sw_ev_data[4].value, 52);
932 data.len = 1;
933 attr->add_segment(attr, data);
934 ck_assert(attr->process(attr, &offset) == NEED_MORE);
935
936 /* Segment 9 truncates sw_id */
937 data = chunk_skip(sw_ev_data[4].value, 53);
938 data.len = 2;
939 attr->add_segment(attr, data);
940 ck_assert(attr->process(attr, &offset) == NEED_MORE);
941
942 /* Segment 10 truncates sw_locator */
943 data = chunk_skip(sw_ev_data[4].value, 55);
944 data.len = 33;
945 attr->add_segment(attr, data);
946 ck_assert(attr->process(attr, &offset) == NEED_MORE);
947
948 /* Segment 11 truncates record */
949 data = chunk_skip(sw_ev_data[4].value, 88);
950 data.len = 3;
951 attr->add_segment(attr, data);
952 ck_assert(attr->process(attr, &offset) == NEED_MORE);
953
954 /* Segment 12 truncates second sw_entry */
955 data = chunk_skip(sw_ev_data[4].value, 91);
956 data.len = 52;
957 attr->add_segment(attr, data);
958 ck_assert(attr->process(attr, &offset) == SUCCESS);
959
960 /* Process first event entry */
961 c_attr = (ietf_swima_attr_sw_ev_t*)attr;
962 sw_ev = c_attr->get_events(c_attr);
963 ck_assert(sw_ev->get_count(sw_ev) == 1);
964 c_attr->clear_events(c_attr);
965
966 /* Segment 13 truncates second sw_record */
967 data = chunk_skip(sw_ev_data[4].value, 143);
968 data.len = 141;
969 attr->add_segment(attr, data);
970 ck_assert(attr->process(attr, &offset) == SUCCESS);
971
972 /* Process second event entry */
973 sw_ev = c_attr->get_events(c_attr);
974 ck_assert(sw_ev->get_count(sw_ev) == 1);
975 c_attr->clear_events(c_attr);
976 attr->destroy(attr);
977
978 /* Invalid Action values */
979 data = chunk_clone(sw_ev_data[2].value);
980 data.ptr[53] = 0;
981 attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
982 ck_assert(attr);
983 ck_assert(attr->process(attr, &offset) == FAILED);
984 attr->destroy(attr);
985
986 data.ptr[53] = SWIMA_EVENT_ACTION_LAST + 1;
987 attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
988 ck_assert(attr);
989 ck_assert(attr->process(attr, &offset) == FAILED && offset == 20);
990 attr->destroy(attr);
991 chunk_free(&data);
992 }
993 END_TEST
994
995 START_TEST(test_imcv_swima_sw_collector)
996 {
997 swima_collector_t *collector;
998 swima_inventory_t *targets, *inventory;
999 swima_events_t *events;
1000 swima_record_t *sw_record;
1001 swima_event_t *sw_event;
1002 chunk_t sw_id, sw_locator, swid_tag;
1003 enumerator_t *enumerator;
1004 uint8_t source_id;
1005 int item = 0, items;
1006
1007 targets = swima_inventory_create();
1008 collector = swima_collector_create();
1009
1010 /* software identifier events only */
1011 events = collector->collect_events(collector, TRUE, targets);
1012 if (events)
1013 {
1014 items = events->get_count(events);
1015 DBG1(DBG_IMC, "%d software identifiers collected", items);
1016
1017 enumerator = events->create_enumerator(events);
1018 while (enumerator->enumerate(enumerator, &sw_event))
1019 {
1020 item++;
1021 if ( item == 1 || item == items)
1022 {
1023 sw_record = sw_event->get_sw_record(sw_event);
1024 sw_id = sw_record->get_sw_id(sw_record, NULL);
1025 source_id =sw_record->get_source_id(sw_record);
1026 DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
1027 }
1028 }
1029 enumerator->destroy(enumerator);
1030 }
1031
1032 /* software identifier inventory only */
1033 inventory = collector->collect_inventory(collector, TRUE, targets);
1034 if (inventory)
1035 {
1036 items = inventory->get_count(inventory);
1037 DBG1(DBG_IMC, "%d software identifiers collected", items);
1038
1039 enumerator = inventory->create_enumerator(inventory);
1040 while (enumerator->enumerate(enumerator, &sw_record))
1041 {
1042 item++;
1043 if ( item == 1 || item == items)
1044 {
1045 sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
1046 source_id =sw_record->get_source_id(sw_record);
1047 DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
1048 if (sw_locator.len > 0)
1049 {
1050 DBG1(DBG_IMC, " locator: %.*s",
1051 sw_locator.len, sw_locator.ptr);
1052 }
1053 targets->add(targets, sw_record->get_ref(sw_record));
1054 }
1055 }
1056 enumerator->destroy(enumerator);
1057 }
1058
1059 /* targeted software inventory */
1060 inventory = collector->collect_inventory(collector, FALSE, targets);
1061 if (inventory)
1062 {
1063 items = inventory->get_count(inventory);
1064 DBG1(DBG_IMC, "%d SWID tags collected", items);
1065
1066 enumerator = inventory->create_enumerator(inventory);
1067 while (enumerator->enumerate(enumerator, &sw_record))
1068 {
1069 sw_id = sw_record->get_sw_id(sw_record, NULL);
1070 source_id =sw_record->get_source_id(sw_record);
1071 swid_tag = sw_record->get_record(sw_record);
1072 DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
1073 DBG2(DBG_IMC, "%B", &swid_tag);
1074 }
1075 enumerator->destroy(enumerator);
1076 }
1077
1078 collector->destroy(collector);
1079 targets->destroy(targets);
1080 }
1081 END_TEST
1082
1083 Suite *imcv_swima_suite_create()
1084 {
1085 Suite *s;
1086 TCase *tc;
1087
1088 s = suite_create("imcv_swima");
1089
1090 tc = tcase_create("sw_record");
1091 tcase_add_test(tc, test_imcv_swima_record);
1092 suite_add_tcase(s, tc);
1093
1094 tc = tcase_create("sw_req");
1095 tcase_add_loop_test(tc, test_imcv_swima_sw_req, 0, countof(req_data));
1096 suite_add_tcase(s, tc);
1097
1098 tc = tcase_create("sw_req_trunc");
1099 tcase_add_test(tc, test_imcv_swima_sw_req_trunc);
1100 suite_add_tcase(s, tc);
1101
1102 tc = tcase_create("sw_inv");
1103 tcase_add_loop_test(tc, test_imcv_swima_inv, 0, 6);
1104 suite_add_tcase(s, tc);
1105
1106 tc = tcase_create("sw_inv_trunc");
1107 tcase_add_test(tc, test_imcv_swima_sw_inv_trunc);
1108 suite_add_tcase(s, tc);
1109
1110 tc = tcase_create("sw_event");
1111 tcase_add_test(tc, test_imcv_swima_event);
1112 suite_add_tcase(s, tc);
1113
1114 tc = tcase_create("sw_ev");
1115 tcase_add_loop_test(tc, test_imcv_swima_ev, 0, 6);
1116 suite_add_tcase(s, tc);
1117
1118 tc = tcase_create("sw_ev_trunc");
1119 tcase_add_test(tc, test_imcv_swima_sw_ev_trunc);
1120 suite_add_tcase(s, tc);
1121
1122 tc = tcase_create("sw_collector");
1123 tcase_add_test(tc, test_imcv_swima_sw_collector);
1124 suite_add_tcase(s, tc);
1125
1126 return s;
1127 }