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