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, &timestamp);
                    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>