Annotation of embedaddon/strongswan/src/libimcv/plugins/imc_test/imc_test.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2011-2012 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 "imc_test_state.h"
        !            17: 
        !            18: #include <imc/imc_agent.h>
        !            19: #include <imc/imc_msg.h>
        !            20: #include <ietf/ietf_attr.h>
        !            21: #include <ita/ita_attr.h>
        !            22: #include <ita/ita_attr_command.h>
        !            23: #include <ita/ita_attr_dummy.h>
        !            24: 
        !            25: #include <tncif_pa_subtypes.h>
        !            26: 
        !            27: #include <pen/pen.h>
        !            28: #include <utils/debug.h>
        !            29: 
        !            30: /* IMC definitions */
        !            31: 
        !            32: static const char imc_name[] = "Test";
        !            33: 
        !            34: static pen_type_t msg_types[] = {
        !            35:        { PEN_ITA, PA_SUBTYPE_ITA_TEST }
        !            36: };
        !            37: 
        !            38: static imc_agent_t *imc_test;
        !            39: 
        !            40: /**
        !            41:  * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
        !            42:  */
        !            43: TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
        !            44:                                                          TNC_Version min_version,
        !            45:                                                          TNC_Version max_version,
        !            46:                                                          TNC_Version *actual_version)
        !            47: {
        !            48:        if (imc_test)
        !            49:        {
        !            50:                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
        !            51:                return TNC_RESULT_ALREADY_INITIALIZED;
        !            52:        }
        !            53:        imc_test = imc_agent_create(imc_name, msg_types, countof(msg_types),
        !            54:                                                                imc_id, actual_version);
        !            55:        if (!imc_test)
        !            56:        {
        !            57:                return TNC_RESULT_FATAL;
        !            58:        }
        !            59:        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
        !            60:        {
        !            61:                DBG1(DBG_IMC, "no common IF-IMC version");
        !            62:                return TNC_RESULT_NO_COMMON_VERSION;
        !            63:        }
        !            64:        return TNC_RESULT_SUCCESS;
        !            65: }
        !            66: 
        !            67: /**
        !            68:  * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
        !            69:  */
        !            70: TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
        !            71:                                                                                  TNC_ConnectionID connection_id,
        !            72:                                                                                  TNC_ConnectionState new_state)
        !            73: {
        !            74:        imc_state_t *state;
        !            75:        imc_test_state_t *test_state;
        !            76:        TNC_Result result;
        !            77:        TNC_UInt32 additional_id;
        !            78:        char *command;
        !            79:        bool retry;
        !            80:        void *pointer;
        !            81:        enumerator_t *enumerator;
        !            82:        int dummy_size, additional_ids;
        !            83: 
        !            84:        if (!imc_test)
        !            85:        {
        !            86:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !            87:                return TNC_RESULT_NOT_INITIALIZED;
        !            88:        }
        !            89: 
        !            90:        switch (new_state)
        !            91:        {
        !            92:                case TNC_CONNECTION_STATE_CREATE:
        !            93:                        command = lib->settings->get_str(lib->settings,
        !            94:                                                                "%s.plugins.imc-test.command", "none", lib->ns);
        !            95:                        dummy_size = lib->settings->get_int(lib->settings,
        !            96:                                                                "%s.plugins.imc-test.dummy_size", 0, lib->ns);
        !            97:                        retry = lib->settings->get_bool(lib->settings,
        !            98:                                                                "%s.plugins.imc-test.retry", FALSE, lib->ns);
        !            99:                        state = imc_test_state_create(connection_id, command, dummy_size,
        !           100:                                                                                  retry);
        !           101: 
        !           102:                        result = imc_test->create_state(imc_test, state);
        !           103:                        if (result != TNC_RESULT_SUCCESS)
        !           104:                        {
        !           105:                                return result;
        !           106:                        }
        !           107: 
        !           108:                        /* Optionally reserve additional IMC IDs */
        !           109:                        additional_ids = lib->settings->get_int(lib->settings,
        !           110:                                                        "%s.plugins.imc-test.additional_ids", 0, lib->ns);
        !           111:                        imc_test->reserve_additional_ids(imc_test, additional_ids -
        !           112:                                                                imc_test->count_additional_ids(imc_test));
        !           113: 
        !           114:                        return TNC_RESULT_SUCCESS;
        !           115: 
        !           116:                case TNC_CONNECTION_STATE_HANDSHAKE:
        !           117:                        /* get updated IMC state */
        !           118:                        result = imc_test->change_state(imc_test, connection_id,
        !           119:                                                                                        new_state, &state);
        !           120:                        if (result != TNC_RESULT_SUCCESS)
        !           121:                        {
        !           122:                                return TNC_RESULT_FATAL;
        !           123:                        }
        !           124:                        test_state = (imc_test_state_t*)state;
        !           125: 
        !           126:                        /* is it the first handshake or a retry ? */
        !           127:                        if (!test_state->is_first_handshake(test_state))
        !           128:                        {
        !           129:                                command = lib->settings->get_str(lib->settings,
        !           130:                                                                "%s.plugins.imc-test.retry_command",
        !           131:                                                                test_state->get_command(test_state), lib->ns);
        !           132:                                test_state->set_command(test_state, command);
        !           133:                        }
        !           134: 
        !           135:                        state->set_result(state, imc_id, TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
        !           136: 
        !           137:                        /* Exit if there are no additional IMC IDs */
        !           138:                        if (!imc_test->count_additional_ids(imc_test))
        !           139:                        {
        !           140:                                return result;
        !           141:                        }
        !           142: 
        !           143:                        enumerator = imc_test->create_id_enumerator(imc_test);
        !           144:                        while (enumerator->enumerate(enumerator, &pointer))
        !           145:                        {
        !           146:                                /* interpret pointer as scalar value */
        !           147:                                additional_id = (TNC_UInt32)pointer;
        !           148: 
        !           149:                                state->set_result(state, additional_id,
        !           150:                                                                  TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
        !           151:                        }
        !           152:                        enumerator->destroy(enumerator);
        !           153: 
        !           154:                        return TNC_RESULT_SUCCESS;
        !           155: 
        !           156:                case TNC_CONNECTION_STATE_DELETE:
        !           157:                        return imc_test->delete_state(imc_test, connection_id);
        !           158: 
        !           159:                case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
        !           160:                case TNC_CONNECTION_STATE_ACCESS_NONE:
        !           161:                        /* get updated IMC state */
        !           162:                        result = imc_test->change_state(imc_test, connection_id,
        !           163:                                                                                        new_state, &state);
        !           164:                        if (result != TNC_RESULT_SUCCESS)
        !           165:                        {
        !           166:                                return TNC_RESULT_FATAL;
        !           167:                        }
        !           168:                        test_state = (imc_test_state_t*)state;
        !           169: 
        !           170:                        /* do a handshake retry? */
        !           171:                        if (test_state->do_handshake_retry(test_state))
        !           172:                        {
        !           173:                                return imc_test->request_handshake_retry(imc_id, connection_id,
        !           174:                                                                        TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE);
        !           175:                        }
        !           176:                        return TNC_RESULT_SUCCESS;
        !           177: 
        !           178:                default:
        !           179:                        return imc_test->change_state(imc_test, connection_id,
        !           180:                                                                                  new_state, NULL);
        !           181:        }
        !           182: }
        !           183: 
        !           184: static void create_message(imc_state_t *state, imc_msg_t *out_msg)
        !           185: {
        !           186:        imc_test_state_t *test_state;
        !           187:        pa_tnc_attr_t *attr;
        !           188: 
        !           189:        test_state = (imc_test_state_t*)state;
        !           190:        if (test_state->get_dummy_size(test_state))
        !           191:        {
        !           192:                attr = ita_attr_dummy_create(test_state->get_dummy_size(test_state));
        !           193:                attr->set_noskip_flag(attr, TRUE);
        !           194:                out_msg->add_attribute(out_msg, attr);
        !           195:        }
        !           196:        attr = ita_attr_command_create(test_state->get_command(test_state));
        !           197:        attr->set_noskip_flag(attr, TRUE);
        !           198:        out_msg->add_attribute(out_msg, attr);
        !           199: }
        !           200: 
        !           201: /**
        !           202:  * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
        !           203:  */
        !           204: TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
        !           205:                                                                  TNC_ConnectionID connection_id)
        !           206: {
        !           207:        imc_state_t *state;
        !           208:        imc_msg_t *out_msg;
        !           209:        enumerator_t *enumerator;
        !           210:        void *pointer;
        !           211:        TNC_UInt32 additional_id;
        !           212:        TNC_Result result;
        !           213: 
        !           214:        if (!imc_test)
        !           215:        {
        !           216:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           217:                return TNC_RESULT_NOT_INITIALIZED;
        !           218:        }
        !           219:        if (!imc_test->get_state(imc_test, connection_id, &state))
        !           220:        {
        !           221:                return TNC_RESULT_FATAL;
        !           222:        }
        !           223: 
        !           224:        /* send PA message for primary IMC ID with the EXCL flag set */
        !           225:        out_msg = imc_msg_create(imc_test, state, connection_id, imc_id,
        !           226:                                                         TNC_IMVID_ANY, msg_types[0]);
        !           227:        create_message(state, out_msg);
        !           228:        result = out_msg->send(out_msg, TRUE);
        !           229:        out_msg->destroy(out_msg);
        !           230: 
        !           231:        /* Exit if there are no additional IMC IDs */
        !           232:        if (!imc_test->count_additional_ids(imc_test))
        !           233:        {
        !           234:                return result;
        !           235:        }
        !           236: 
        !           237:        /* Do we have support for transporting multiple IMC IDs? */
        !           238:        if (!state->has_long(state))
        !           239:        {
        !           240:                DBG1(DBG_IMC, "IMC %u \"%s\" did not detect support for transporting "
        !           241:                                          "multiple IMC IDs", imc_id, imc_name);
        !           242:                return result;
        !           243:        }
        !           244: 
        !           245:        /* send PA messages for additional IMC IDs */
        !           246:        enumerator = imc_test->create_id_enumerator(imc_test);
        !           247:        while (result == TNC_RESULT_SUCCESS &&
        !           248:                   enumerator->enumerate(enumerator, &pointer))
        !           249:        {
        !           250:                /* interpret pointer as scalar value */
        !           251:                additional_id = (TNC_UInt32)pointer;
        !           252:                out_msg = imc_msg_create(imc_test, state, connection_id, additional_id,
        !           253:                                                                 TNC_IMVID_ANY, msg_types[0]);
        !           254:                create_message(state, out_msg);
        !           255:                result = out_msg->send(out_msg, TRUE);
        !           256:                out_msg->destroy(out_msg);
        !           257:        }
        !           258:        enumerator->destroy(enumerator);
        !           259: 
        !           260:        return result;
        !           261: }
        !           262: 
        !           263: static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
        !           264: {
        !           265:        imc_msg_t *out_msg;
        !           266:        enumerator_t *enumerator;
        !           267:        pa_tnc_attr_t *attr;
        !           268:        pen_type_t attr_type;
        !           269:        TNC_Result result = TNC_RESULT_SUCCESS;
        !           270:        bool fatal_error = FALSE;
        !           271: 
        !           272:        /* generate an outgoing PA-TNC message - we might need it */
        !           273:        out_msg = imc_msg_create_as_reply(in_msg);
        !           274: 
        !           275:        /* parse received PA-TNC message and handle local and remote errors */
        !           276:        result = in_msg->receive(in_msg, out_msg, &fatal_error);
        !           277:        if (result != TNC_RESULT_SUCCESS)
        !           278:        {
        !           279:                out_msg->destroy(out_msg);
        !           280:                return result;
        !           281:        }
        !           282: 
        !           283:        /* analyze PA-TNC attributes */
        !           284:        enumerator = in_msg->create_attribute_enumerator(in_msg);
        !           285:        while (enumerator->enumerate(enumerator, &attr))
        !           286:        {
        !           287:                attr_type = attr->get_type(attr);
        !           288: 
        !           289:                if (attr_type.vendor_id != PEN_ITA)
        !           290:                {
        !           291:                        continue;
        !           292:                }
        !           293:                if (attr_type.type == ITA_ATTR_COMMAND)
        !           294:                {
        !           295:                        ita_attr_command_t *ita_attr;
        !           296: 
        !           297:                        ita_attr = (ita_attr_command_t*)attr;
        !           298:                        DBG1(DBG_IMC, "received command '%s'",
        !           299:                                 ita_attr->get_command(ita_attr));
        !           300:                }
        !           301:                else if (attr_type.type == ITA_ATTR_DUMMY)
        !           302:                {
        !           303:                        ita_attr_dummy_t *ita_attr;
        !           304: 
        !           305:                        ita_attr = (ita_attr_dummy_t*)attr;
        !           306:                        DBG1(DBG_IMC, "received dummy attribute value (%d bytes)",
        !           307:                                 ita_attr->get_size(ita_attr));
        !           308:                }
        !           309:        }
        !           310:        enumerator->destroy(enumerator);
        !           311: 
        !           312:        if (fatal_error)
        !           313:        {
        !           314:                result = TNC_RESULT_FATAL;
        !           315:        }
        !           316:        else
        !           317:        {
        !           318:                /* if no assessment result is known then repeat the measurement */
        !           319:                if (!state->get_result(state, in_msg->get_dst_id(in_msg), NULL))
        !           320:                {
        !           321:                        create_message(state, out_msg);
        !           322:                }
        !           323:                result = out_msg->send(out_msg, TRUE);
        !           324:        }
        !           325:        out_msg->destroy(out_msg);
        !           326: 
        !           327:        return result;
        !           328: }
        !           329: 
        !           330: /**
        !           331:  * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
        !           332:  */
        !           333: TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
        !           334:                                                                  TNC_ConnectionID connection_id,
        !           335:                                                                  TNC_BufferReference msg,
        !           336:                                                                  TNC_UInt32 msg_len,
        !           337:                                                                  TNC_MessageType msg_type)
        !           338: {
        !           339:        imc_state_t *state;
        !           340:        imc_msg_t *in_msg;
        !           341:        TNC_Result result;
        !           342: 
        !           343:        if (!imc_test)
        !           344:        {
        !           345:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           346:                return TNC_RESULT_NOT_INITIALIZED;
        !           347:        }
        !           348:        if (!imc_test->get_state(imc_test, connection_id, &state))
        !           349:        {
        !           350:                return TNC_RESULT_FATAL;
        !           351:        }
        !           352: 
        !           353:        in_msg = imc_msg_create_from_data(imc_test, state, connection_id, msg_type,
        !           354:                                                                          chunk_create(msg, msg_len));
        !           355:        result = receive_message(state, in_msg);
        !           356:        in_msg->destroy(in_msg);
        !           357: 
        !           358:        return result;
        !           359: }
        !           360: 
        !           361: /**
        !           362:  * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
        !           363:  */
        !           364: TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
        !           365:                                                                          TNC_ConnectionID connection_id,
        !           366:                                                                          TNC_UInt32 msg_flags,
        !           367:                                                                          TNC_BufferReference msg,
        !           368:                                                                          TNC_UInt32 msg_len,
        !           369:                                                                          TNC_VendorID msg_vid,
        !           370:                                                                          TNC_MessageSubtype msg_subtype,
        !           371:                                                                          TNC_UInt32 src_imv_id,
        !           372:                                                                          TNC_UInt32 dst_imc_id)
        !           373: {
        !           374:        imc_state_t *state;
        !           375:        imc_msg_t *in_msg;
        !           376:        TNC_Result result;
        !           377: 
        !           378:        if (!imc_test)
        !           379:        {
        !           380:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           381:                return TNC_RESULT_NOT_INITIALIZED;
        !           382:        }
        !           383:        if (!imc_test->get_state(imc_test, connection_id, &state))
        !           384:        {
        !           385:                return TNC_RESULT_FATAL;
        !           386:        }
        !           387:        in_msg = imc_msg_create_from_long_data(imc_test, state, connection_id,
        !           388:                                                                src_imv_id, dst_imc_id, msg_vid, msg_subtype,
        !           389:                                                                chunk_create(msg, msg_len));
        !           390:        result =receive_message(state, in_msg);
        !           391:        in_msg->destroy(in_msg);
        !           392: 
        !           393:        return result;
        !           394: }
        !           395: 
        !           396: /**
        !           397:  * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
        !           398:  */
        !           399: TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
        !           400:                                                           TNC_ConnectionID connection_id)
        !           401: {
        !           402:        if (!imc_test)
        !           403:        {
        !           404:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           405:                return TNC_RESULT_NOT_INITIALIZED;
        !           406:        }
        !           407:        return TNC_RESULT_SUCCESS;
        !           408: }
        !           409: 
        !           410: /**
        !           411:  * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
        !           412:  */
        !           413: TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
        !           414: {
        !           415:        if (!imc_test)
        !           416:        {
        !           417:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           418:                return TNC_RESULT_NOT_INITIALIZED;
        !           419:        }
        !           420:        imc_test->destroy(imc_test);
        !           421:        imc_test = NULL;
        !           422: 
        !           423:        return TNC_RESULT_SUCCESS;
        !           424: }
        !           425: 
        !           426: /**
        !           427:  * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
        !           428:  */
        !           429: TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
        !           430:                                                                           TNC_TNCC_BindFunctionPointer bind_function)
        !           431: {
        !           432:        if (!imc_test)
        !           433:        {
        !           434:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
        !           435:                return TNC_RESULT_NOT_INITIALIZED;
        !           436:        }
        !           437:        return imc_test->bind_functions(imc_test, bind_function);
        !           438: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>