Annotation of embedaddon/strongswan/src/libimcv/imc/imc_msg.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2012-2015 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_msg.h"
        !            17: 
        !            18: #include "ietf/ietf_attr.h"
        !            19: #include "ietf/ietf_attr_assess_result.h"
        !            20: #include "ietf/ietf_attr_remediation_instr.h"
        !            21: #include "tcg/seg/tcg_seg_attr_max_size.h"
        !            22: #include "tcg/seg/tcg_seg_attr_seg_env.h"
        !            23: #include "tcg/seg/tcg_seg_attr_next_seg.h"
        !            24: 
        !            25: #include <tncif_names.h>
        !            26: #include <tncif_pa_subtypes.h>
        !            27: 
        !            28: #include <pen/pen.h>
        !            29: #include <collections/linked_list.h>
        !            30: #include <utils/debug.h>
        !            31: 
        !            32: typedef struct private_imc_msg_t private_imc_msg_t;
        !            33: 
        !            34: /**
        !            35:  * Private data of a imc_msg_t object.
        !            36:  *
        !            37:  */
        !            38: struct private_imc_msg_t {
        !            39: 
        !            40:        /**
        !            41:         * Public imc_msg_t interface.
        !            42:         */
        !            43:        imc_msg_t public;
        !            44: 
        !            45:        /**
        !            46:         * Connection ID
        !            47:         */
        !            48:        TNC_ConnectionID connection_id;
        !            49: 
        !            50:        /**
        !            51:         * source ID
        !            52:         */
        !            53:        TNC_UInt32 src_id;
        !            54: 
        !            55:        /**
        !            56:         * destination ID
        !            57:         */
        !            58:        TNC_UInt32 dst_id;
        !            59: 
        !            60:        /**
        !            61:         * PA-TNC message type
        !            62:         */
        !            63:        pen_type_t msg_type;
        !            64: 
        !            65:        /**
        !            66:         * List of PA-TNC attributes to be sent
        !            67:         */
        !            68:        linked_list_t *attr_list;
        !            69: 
        !            70:        /**
        !            71:         * PA-TNC message
        !            72:         */
        !            73:        pa_tnc_msg_t *pa_msg;
        !            74: 
        !            75:        /**
        !            76:         * Assigned IMC agent
        !            77:         */
        !            78:        imc_agent_t *agent;
        !            79: 
        !            80:        /**
        !            81:         * Assigned IMC state
        !            82:         */
        !            83:        imc_state_t *state;
        !            84: };
        !            85: 
        !            86: METHOD(imc_msg_t, get_src_id, TNC_UInt32,
        !            87:        private_imc_msg_t *this)
        !            88: {
        !            89:        return this->src_id;
        !            90: }
        !            91: 
        !            92: METHOD(imc_msg_t, get_dst_id, TNC_UInt32,
        !            93:        private_imc_msg_t *this)
        !            94: {
        !            95:        return this->dst_id;
        !            96: }
        !            97: 
        !            98: METHOD(imc_msg_t, get_msg_type, pen_type_t,
        !            99:        private_imc_msg_t *this)
        !           100: {
        !           101:        return this->msg_type;
        !           102: }
        !           103: 
        !           104: METHOD(imc_msg_t, send_, TNC_Result,
        !           105:        private_imc_msg_t *this, bool excl)
        !           106: {
        !           107:        pa_tnc_msg_t *pa_tnc_msg;
        !           108:        pa_tnc_attr_t *attr;
        !           109:        TNC_UInt32 msg_flags;
        !           110:        TNC_MessageType msg_type;
        !           111:        size_t max_msg_len, min_seg_attr_len, space_left;
        !           112:        bool attr_added, oversize;
        !           113:        chunk_t msg;
        !           114:        seg_contract_t *contract;
        !           115:        seg_contract_manager_t *contracts;
        !           116:        enumerator_t *enumerator;
        !           117:        TNC_Result result = TNC_RESULT_SUCCESS;
        !           118: 
        !           119:        /* Get IF-M segmentation contract for this subtype if any */
        !           120:        contracts = this->state->get_contracts(this->state);
        !           121:        contract = contracts->get_contract(contracts, this->msg_type,
        !           122:                                                                           FALSE, this->dst_id);
        !           123: 
        !           124:        /* Retrieve maximum allowed PA-TNC message size if set */
        !           125:        max_msg_len = this->state->get_max_msg_len(this->state);
        !           126: 
        !           127:        /* Minimum size needed for Segmentation Envelope Attribute */
        !           128:        min_seg_attr_len = PA_TNC_ATTR_HEADER_SIZE + TCG_SEG_ATTR_SEG_ENV_HEADER +
        !           129:                                           PA_TNC_ATTR_HEADER_SIZE;
        !           130: 
        !           131:        while (this->attr_list->get_count(this->attr_list))
        !           132:        {
        !           133:                pa_tnc_msg = pa_tnc_msg_create(max_msg_len);
        !           134:                attr_added = FALSE;
        !           135: 
        !           136:                enumerator = this->attr_list->create_enumerator(this->attr_list);
        !           137:                while (enumerator->enumerate(enumerator, &attr))
        !           138:                {
        !           139:                        space_left = pa_tnc_msg->get_space(pa_tnc_msg);
        !           140: 
        !           141:                        if (contract && contract->check_size(contract, attr, &oversize))
        !           142:                        {
        !           143:                                if (oversize)
        !           144:                                {
        !           145:                                        /* TODO handle oversized attributes */
        !           146:                                }
        !           147:                                else if (max_msg_len == 0 || space_left >= min_seg_attr_len)
        !           148:                                {
        !           149:                                        attr = contract->first_segment(contract, attr, space_left);
        !           150:                                }
        !           151:                                else
        !           152:                                {
        !           153:                                        /* segment attribute in next iteration */
        !           154:                                        break;
        !           155:                                }
        !           156:                        }
        !           157:                        if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
        !           158:                        {
        !           159:                                attr_added = TRUE;
        !           160:                        }
        !           161:                        else
        !           162:                        {
        !           163:                                if (attr_added)
        !           164:                                {
        !           165:                                        /* there might be space for attribute in next iteration */
        !           166:                                        break;
        !           167:                                }
        !           168:                                else
        !           169:                                {
        !           170:                                        DBG1(DBG_IMV, "PA-TNC attribute too large to send, deleted");
        !           171:                                        attr->destroy(attr);
        !           172:                                }
        !           173:                        }
        !           174:                        this->attr_list->remove_at(this->attr_list, enumerator);
        !           175:                }
        !           176:                enumerator->destroy(enumerator);
        !           177: 
        !           178:                /* build and send the PA-TNC message via the IF-IMC interface */
        !           179:                if (!pa_tnc_msg->build(pa_tnc_msg))
        !           180:                {
        !           181:                        pa_tnc_msg->destroy(pa_tnc_msg);
        !           182:                        return TNC_RESULT_FATAL;
        !           183:                }
        !           184:                msg = pa_tnc_msg->get_encoding(pa_tnc_msg);
        !           185:                DBG3(DBG_IMC, "created PA-TNC message: %B", &msg);
        !           186: 
        !           187:                if (this->state->has_long(this->state) && this->agent->send_message_long)
        !           188:                {
        !           189:                        excl = excl && this->state->has_excl(this->state) &&
        !           190:                                                   this->dst_id != TNC_IMVID_ANY;
        !           191:                        msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
        !           192:                        result = this->agent->send_message_long(this->src_id,
        !           193:                                                        this->connection_id, msg_flags, msg.ptr, msg.len,
        !           194:                                                        this->msg_type.vendor_id, this->msg_type.type,
        !           195:                                                        this->dst_id);
        !           196:                }
        !           197:                else if (this->agent->send_message)
        !           198:                {
        !           199:                        msg_type = (this->msg_type.vendor_id << 8) |
        !           200:                                           (this->msg_type.type & 0x000000ff);
        !           201:                        result = this->agent->send_message(this->src_id, this->connection_id,
        !           202:                                                                                           msg.ptr, msg.len, msg_type);
        !           203:                }
        !           204: 
        !           205:                pa_tnc_msg->destroy(pa_tnc_msg);
        !           206: 
        !           207:                if (result != TNC_RESULT_SUCCESS)
        !           208:                {
        !           209:                        break;
        !           210:                }
        !           211:        }
        !           212:        return result;
        !           213: }
        !           214: 
        !           215: /**
        !           216:  * Print a clearly visible assessment header to the log
        !           217:  */
        !           218: static void print_assessment_header(const char *name, TNC_UInt32 dst_id,
        !           219:                                                                        TNC_UInt32 src_id, bool *first)
        !           220: {
        !           221:        if (*first)
        !           222:        {
        !           223:                if (src_id == TNC_IMCID_ANY)
        !           224:                {
        !           225:                        DBG1(DBG_IMC, "***** assessment of IMC %u \"%s\" *****",
        !           226:                                                   dst_id, name);
        !           227:                }
        !           228:                else
        !           229:                {
        !           230:                        DBG1(DBG_IMC, "***** assessment of IMC %u \"%s\" from IMV %u *****",
        !           231:                                                   dst_id, name, src_id);
        !           232:                }
        !           233:                *first = FALSE;
        !           234:        }
        !           235: }
        !           236: 
        !           237: /**
        !           238:  * Print a clearly visible assessment trailer to the log
        !           239:  */
        !           240: static void print_assessment_trailer(bool first)
        !           241: {
        !           242:        if (!first)
        !           243:        {
        !           244:                DBG1(DBG_IMC, "***** end of assessment *****");
        !           245:        }
        !           246: }
        !           247: 
        !           248: METHOD(imc_msg_t, receive, TNC_Result,
        !           249:        private_imc_msg_t *this, imc_msg_t *out_msg, bool *fatal_error)
        !           250: {
        !           251:        linked_list_t *non_fatal_types;
        !           252:        TNC_UInt32 target_imc_id;
        !           253:        enumerator_t *enumerator;
        !           254:        pa_tnc_attr_t *attr;
        !           255:        pen_type_t attr_type;
        !           256:        chunk_t msg;
        !           257:        bool first = TRUE;
        !           258: 
        !           259:        if (this->state->has_long(this->state))
        !           260:        {
        !           261:                if (this->dst_id != TNC_IMCID_ANY)
        !           262:                {
        !           263:                        DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
        !           264:                                                  "from IMV %u to IMC %u",
        !           265:                                                   this->agent->get_id(this->agent),
        !           266:                                                   this->agent->get_name(this->agent),
        !           267:                                                   this->connection_id, this->src_id, this->dst_id);
        !           268:                }
        !           269:                else
        !           270:                {
        !           271:                        DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
        !           272:                                                  "from IMV %u", this->agent->get_id(this->agent),
        !           273:                                                   this->agent->get_name(this->agent),
        !           274:                                                   this->connection_id, this->src_id);
        !           275:                }
        !           276:        }
        !           277:        else
        !           278:        {
        !           279:                DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u",
        !           280:                                           this->agent->get_id(this->agent),
        !           281:                                           this->agent->get_name(this->agent),
        !           282:                                           this->connection_id);
        !           283:        }
        !           284:        msg = this->pa_msg->get_encoding(this->pa_msg);
        !           285:        DBG3(DBG_IMC, "%B", &msg);
        !           286: 
        !           287:        switch (this->pa_msg->process(this->pa_msg))
        !           288:        {
        !           289:                case SUCCESS:
        !           290:                        break;
        !           291:                case VERIFY_ERROR:
        !           292:                {
        !           293:                        /* extract and copy by reference all error attributes */
        !           294:                        enumerator = this->pa_msg->create_error_enumerator(this->pa_msg);
        !           295:                        while (enumerator->enumerate(enumerator, &attr))
        !           296:                        {
        !           297:                                out_msg->add_attribute(out_msg, attr->get_ref(attr));
        !           298:                        }
        !           299:                        enumerator->destroy(enumerator);
        !           300:                        return TNC_RESULT_SUCCESS;
        !           301:                }
        !           302:                case FAILED:
        !           303:                default:
        !           304:                        return TNC_RESULT_FATAL;
        !           305:        }
        !           306: 
        !           307:        /* determine target IMC ID */
        !           308:        target_imc_id = (this->dst_id != TNC_IMCID_ANY) ?
        !           309:                                         this->dst_id : this->agent->get_id(this->agent);
        !           310: 
        !           311:        /* process any IF-M segmentation contracts */
        !           312:        enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
        !           313:        while (enumerator->enumerate(enumerator, &attr))
        !           314:        {
        !           315:                uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size;
        !           316:                seg_contract_t *contract;
        !           317:                seg_contract_manager_t *contracts;
        !           318:                char buf[BUF_LEN];
        !           319:                pen_type_t type;
        !           320: 
        !           321:                type = attr->get_type(attr);
        !           322: 
        !           323:                contracts = this->state->get_contracts(this->state);
        !           324: 
        !           325:                if (type.vendor_id != PEN_TCG)
        !           326:                {
        !           327:                        continue;
        !           328:                }
        !           329: 
        !           330:                switch (type.type)
        !           331:                {
        !           332:                        case TCG_SEG_MAX_ATTR_SIZE_REQ:
        !           333:                        {
        !           334:                                tcg_seg_attr_max_size_t *attr_cast;
        !           335: 
        !           336:                                attr_cast = (tcg_seg_attr_max_size_t*)attr;
        !           337:                                attr_cast->get_attr_size(attr_cast, &max_attr_size,
        !           338:                                                                                                        &max_seg_size);
        !           339:                                contract = contracts->get_contract(contracts, this->msg_type,
        !           340:                                                                                                   FALSE, this->src_id);
        !           341:                                if (contract)
        !           342:                                {
        !           343:                                        contract->set_max_size(contract, max_attr_size,
        !           344:                                                                                                         max_seg_size);
        !           345:                                }
        !           346:                                else
        !           347:                                {
        !           348:                                        contract = seg_contract_create(this->msg_type, max_attr_size,
        !           349:                                                                        max_seg_size, FALSE, this->src_id, TRUE);
        !           350:                                        contract->set_responder(contract, target_imc_id);
        !           351:                                        contracts->add_contract(contracts, contract);
        !           352:                                }
        !           353:                                contract->get_info_string(contract, buf, BUF_LEN, TRUE);
        !           354:                                DBG2(DBG_IMC, "%s", buf);
        !           355: 
        !           356:                                /* Determine maximum PA-TNC attribute segment size */
        !           357:                                my_max_seg_size = this->state->get_max_msg_len(this->state)
        !           358:                                                                        - PA_TNC_HEADER_SIZE
        !           359:                                                                        - PA_TNC_ATTR_HEADER_SIZE
        !           360:                                                                        - TCG_SEG_ATTR_SEG_ENV_HEADER;
        !           361: 
        !           362:                                /* If segmentation is possible select lower segment size */
        !           363:                                if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
        !           364:                                        max_seg_size > my_max_seg_size)
        !           365:                                {
        !           366:                                        max_seg_size = my_max_seg_size;
        !           367:                                        contract->set_max_size(contract, max_attr_size,
        !           368:                                                                                                         max_seg_size);
        !           369:                                        DBG2(DBG_IMC, "  lowered maximum segment size to %u bytes",
        !           370:                                                 max_seg_size);
        !           371:                                }
        !           372: 
        !           373:                                /* Add Maximum Attribute Size Response attribute */
        !           374:                                attr = tcg_seg_attr_max_size_create(max_attr_size,
        !           375:                                                                                                        max_seg_size, FALSE);
        !           376:                                out_msg->add_attribute(out_msg, attr);
        !           377:                                break;
        !           378:                        }
        !           379:                        case TCG_SEG_MAX_ATTR_SIZE_RESP:
        !           380:                        {
        !           381:                                tcg_seg_attr_max_size_t *attr_cast;
        !           382: 
        !           383:                                attr_cast = (tcg_seg_attr_max_size_t*)attr;
        !           384:                                attr_cast->get_attr_size(attr_cast, &max_attr_size,
        !           385:                                                                                                        &max_seg_size);
        !           386:                                contract = contracts->get_contract(contracts, this->msg_type,
        !           387:                                                                                                   TRUE, this->src_id);
        !           388:                                if (!contract)
        !           389:                                {
        !           390:                                        contract = contracts->get_contract(contracts, this->msg_type,
        !           391:                                                                                                           TRUE, TNC_IMCID_ANY);
        !           392:                                        if (contract)
        !           393:                                        {
        !           394:                                                contract = contract->clone(contract);
        !           395:                                                contract->set_responder(contract, this->src_id);
        !           396:                                                contracts->add_contract(contracts, contract);
        !           397:                                        }
        !           398:                                }
        !           399:                                if (contract)
        !           400:                                {
        !           401:                                        contract->get_max_size(contract, &my_max_attr_size,
        !           402:                                                                                                         &my_max_seg_size);
        !           403:                                        if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
        !           404:                                                my_max_seg_size > max_seg_size)
        !           405:                                        {
        !           406:                                                my_max_seg_size = max_seg_size;
        !           407:                                                contract->set_max_size(contract, my_max_attr_size,
        !           408:                                                                                                                 my_max_seg_size);
        !           409:                                        }
        !           410:                                        contract->get_info_string(contract, buf, BUF_LEN, FALSE);
        !           411:                                        DBG2(DBG_IMC, "%s", buf);
        !           412:                                }
        !           413:                                else
        !           414:                                {
        !           415:                                        /* TODO no request pending */
        !           416:                                        DBG1(DBG_IMC, "no contract for this PA message type found");
        !           417:                                }
        !           418:                                break;
        !           419:                        }
        !           420:                        case TCG_SEG_ATTR_SEG_ENV:
        !           421:                        {
        !           422:                                tcg_seg_attr_seg_env_t *seg_env_attr;
        !           423:                                pa_tnc_attr_t *error;
        !           424:                                uint32_t base_attr_id;
        !           425:                                bool more;
        !           426: 
        !           427:                                seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
        !           428:                                base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
        !           429: 
        !           430:                                contract = contracts->get_contract(contracts, this->msg_type,
        !           431:                                                                                                   TRUE, this->src_id);
        !           432:                                if (!contract)
        !           433:                                {
        !           434:                                        DBG2(DBG_IMC, "no contract for received attribute segment "
        !           435:                                                 "with base attribute ID %u", base_attr_id);
        !           436:                                        continue;
        !           437:                                }
        !           438:                                attr = contract->add_segment(contract, attr, &error, &more);
        !           439:                                if (error)
        !           440:                                {
        !           441:                                        out_msg->add_attribute(out_msg, error);
        !           442:                                }
        !           443:                                if (attr)
        !           444:                                {
        !           445:                                        this->pa_msg->add_attribute(this->pa_msg, attr);
        !           446:                                }
        !           447:                                if (more)
        !           448:                                {
        !           449:                                        /* Send Next Segment Request */
        !           450:                                        attr = tcg_seg_attr_next_seg_create(base_attr_id, FALSE);
        !           451:                                        out_msg->add_attribute(out_msg, attr);
        !           452:                                }
        !           453:                                break;
        !           454:                        }
        !           455:                        case TCG_SEG_NEXT_SEG_REQ:
        !           456:                        {
        !           457:                                tcg_seg_attr_next_seg_t *attr_cast;
        !           458:                                uint32_t base_attr_id;
        !           459: 
        !           460:                                attr_cast = (tcg_seg_attr_next_seg_t*)attr;
        !           461:                                base_attr_id = attr_cast->get_base_attr_id(attr_cast);
        !           462: 
        !           463:                                contract = contracts->get_contract(contracts, this->msg_type,
        !           464:                                                                                                   FALSE, this->src_id);
        !           465:                                if (!contract)
        !           466:                                {
        !           467:                                        /* TODO no contract - generate error message */
        !           468:                                        DBG1(DBG_IMC, "no contract for received next segment "
        !           469:                                                 "request with base attribute ID %u", base_attr_id);
        !           470:                                        continue;
        !           471:                                }
        !           472:                                attr = contract->next_segment(contract, base_attr_id);
        !           473:                                if (attr)
        !           474:                                {
        !           475:                                        out_msg->add_attribute(out_msg, attr);
        !           476:                                }
        !           477:                                else
        !           478:                                {
        !           479:                                        /* TODO no more segments - generate error message */
        !           480:                                        DBG1(DBG_IMC, "no more segments found for "
        !           481:                                                 "base attribute ID %u", base_attr_id);
        !           482:                                }
        !           483:                                break;
        !           484:                        }
        !           485:                        default:
        !           486:                                break;
        !           487:                }
        !           488:        }
        !           489:        enumerator->destroy(enumerator);
        !           490: 
        !           491:        /* preprocess any received IETF standard error attributes */
        !           492:        non_fatal_types = this->agent->get_non_fatal_attr_types(this->agent);
        !           493:        *fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg,
        !           494:                                                                                                                 non_fatal_types);
        !           495: 
        !           496:        /* preprocess any received IETF assessment result attribute */
        !           497:        enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
        !           498:        while (enumerator->enumerate(enumerator, &attr))
        !           499:        {
        !           500:                attr_type = attr->get_type(attr);
        !           501: 
        !           502:                if (attr_type.vendor_id != PEN_IETF)
        !           503:                {
        !           504:                        continue;
        !           505:                }
        !           506:                if (attr_type.type == IETF_ATTR_ASSESSMENT_RESULT)
        !           507:                {
        !           508:                        ietf_attr_assess_result_t *attr_cast;
        !           509:                        TNC_IMV_Evaluation_Result res;
        !           510: 
        !           511:                        attr_cast = (ietf_attr_assess_result_t*)attr;
        !           512:                        res =  attr_cast->get_result(attr_cast);
        !           513:                        this->state->set_result(this->state, target_imc_id, res);
        !           514: 
        !           515:                        print_assessment_header(this->agent->get_name(this->agent),
        !           516:                                                                        target_imc_id, this->src_id, &first);
        !           517:                        DBG1(DBG_IMC, "assessment result is '%N'",
        !           518:                                 TNC_IMV_Evaluation_Result_names, res);
        !           519:                }
        !           520:                else if (attr_type.type == IETF_ATTR_REMEDIATION_INSTRUCTIONS)
        !           521:                {
        !           522:                        ietf_attr_remediation_instr_t *attr_cast;
        !           523:                        pen_type_t parameters_type;
        !           524:                        chunk_t parameters, string, lang_code;
        !           525: 
        !           526:                        attr_cast = (ietf_attr_remediation_instr_t*)attr;
        !           527:                        parameters_type = attr_cast->get_parameters_type(attr_cast);
        !           528:                        parameters = attr_cast->get_parameters(attr_cast);
        !           529: 
        !           530:                        print_assessment_header(this->agent->get_name(this->agent),
        !           531:                                                                        target_imc_id, this->src_id, &first);
        !           532:                        if (parameters_type.vendor_id == PEN_IETF)
        !           533:                        {
        !           534:                                switch (parameters_type.type)
        !           535:                                {
        !           536:                                        case IETF_REMEDIATION_PARAMETERS_URI:
        !           537:                                                DBG1(DBG_IMC, "remediation uri: %.*s",
        !           538:                                                                           parameters.len, parameters.ptr);
        !           539:                                                break;
        !           540:                                        case IETF_REMEDIATION_PARAMETERS_STRING:
        !           541:                                                string = attr_cast->get_string(attr_cast, &lang_code);
        !           542:                                                DBG1(DBG_IMC, "remediation string: [%.*s]\n%.*s",
        !           543:                                                                           lang_code.len, lang_code.ptr,
        !           544:                                                                           string.len, string.ptr);
        !           545:                                                break;
        !           546:                                        default:
        !           547:                                                DBG1(DBG_IMC, "remediation parameters: %B", &parameters);
        !           548:                                }
        !           549:                        }
        !           550:                        else
        !           551:                        {
        !           552:                                DBG1(DBG_IMC, "remediation parameters: %B", &parameters);
        !           553:                        }
        !           554:                }
        !           555:        }
        !           556:        enumerator->destroy(enumerator);
        !           557: 
        !           558:        print_assessment_trailer(first);
        !           559: 
        !           560:        return TNC_RESULT_SUCCESS;
        !           561: }
        !           562: 
        !           563: METHOD(imc_msg_t, add_attribute, void,
        !           564:        private_imc_msg_t *this, pa_tnc_attr_t *attr)
        !           565: {
        !           566:        this->attr_list->insert_last(this->attr_list, attr);
        !           567: }
        !           568: 
        !           569: METHOD(imc_msg_t, create_attribute_enumerator, enumerator_t*,
        !           570:        private_imc_msg_t *this)
        !           571: {
        !           572:        return this->pa_msg->create_attribute_enumerator(this->pa_msg);
        !           573: }
        !           574: 
        !           575: METHOD(imc_msg_t, get_encoding, chunk_t,
        !           576:        private_imc_msg_t *this)
        !           577: {
        !           578:        if (this->pa_msg)
        !           579:        {
        !           580:                return this->pa_msg->get_encoding(this->pa_msg);
        !           581:        }
        !           582:        return chunk_empty;
        !           583: }
        !           584: 
        !           585: METHOD(imc_msg_t, destroy, void,
        !           586:        private_imc_msg_t *this)
        !           587: {
        !           588:        this->attr_list->destroy_offset(this->attr_list,
        !           589:                                                                        offsetof(pa_tnc_attr_t, destroy));
        !           590:        DESTROY_IF(this->pa_msg);
        !           591:        free(this);
        !           592: }
        !           593: 
        !           594: /**
        !           595:  * See header
        !           596:  */
        !           597: imc_msg_t *imc_msg_create(imc_agent_t *agent, imc_state_t *state,
        !           598:                                                  TNC_ConnectionID connection_id,
        !           599:                                                  TNC_UInt32 src_id, TNC_UInt32 dst_id,
        !           600:                                                  pen_type_t msg_type)
        !           601: {
        !           602:        private_imc_msg_t *this;
        !           603: 
        !           604:        INIT(this,
        !           605:                .public = {
        !           606:                        .get_src_id = _get_src_id,
        !           607:                        .get_dst_id = _get_dst_id,
        !           608:                        .get_msg_type = _get_msg_type,
        !           609:                        .send = _send_,
        !           610:                        .receive = _receive,
        !           611:                        .add_attribute = _add_attribute,
        !           612:                        .create_attribute_enumerator = _create_attribute_enumerator,
        !           613:                        .get_encoding = _get_encoding,
        !           614:                        .destroy = _destroy,
        !           615:                },
        !           616:                .connection_id = connection_id,
        !           617:                .src_id = src_id,
        !           618:                .dst_id = dst_id,
        !           619:                .msg_type = msg_type,
        !           620:                .attr_list = linked_list_create(),
        !           621:                .agent = agent,
        !           622:                .state = state,
        !           623:        );
        !           624: 
        !           625:        return &this->public;
        !           626: }
        !           627: 
        !           628: /**
        !           629:  * See header
        !           630:  */
        !           631: imc_msg_t* imc_msg_create_as_reply(imc_msg_t *msg)
        !           632: {
        !           633:        private_imc_msg_t *in;
        !           634:        TNC_UInt32 src_id;
        !           635: 
        !           636:        in = (private_imc_msg_t*)msg;
        !           637:        src_id = (in->dst_id != TNC_IMCID_ANY) ?
        !           638:                          in->dst_id : in->agent->get_id(in->agent);
        !           639: 
        !           640:        return imc_msg_create(in->agent, in->state, in->connection_id, src_id,
        !           641:                                                  in->src_id, in->msg_type);
        !           642: }
        !           643: 
        !           644: /**
        !           645:  * See header
        !           646:  */
        !           647: imc_msg_t *imc_msg_create_from_data(imc_agent_t *agent, imc_state_t *state,
        !           648:                                                                        TNC_ConnectionID connection_id,
        !           649:                                                                        TNC_MessageType msg_type,
        !           650:                                                                        chunk_t msg)
        !           651: {
        !           652:        TNC_VendorID msg_vid;
        !           653:        TNC_MessageSubtype msg_subtype;
        !           654: 
        !           655:        msg_vid = msg_type >> 8;
        !           656:        msg_subtype = msg_type & TNC_SUBTYPE_ANY;
        !           657: 
        !           658:        return imc_msg_create_from_long_data(agent, state, connection_id,
        !           659:                                                                TNC_IMVID_ANY, agent->get_id(agent),
        !           660:                                                                msg_vid, msg_subtype, msg);
        !           661: }
        !           662: 
        !           663: /**
        !           664:  * See header
        !           665:  */
        !           666: imc_msg_t *imc_msg_create_from_long_data(imc_agent_t *agent, imc_state_t *state,
        !           667:                                                                                 TNC_ConnectionID connection_id,
        !           668:                                                                                 TNC_UInt32 src_id,
        !           669:                                                                                 TNC_UInt32 dst_id,
        !           670:                                                                                 TNC_VendorID msg_vid,
        !           671:                                                                                 TNC_MessageSubtype msg_subtype,
        !           672:                                                                                 chunk_t msg)
        !           673: {
        !           674:        private_imc_msg_t *this;
        !           675: 
        !           676:        this = (private_imc_msg_t*)imc_msg_create(agent, state,
        !           677:                                                                                connection_id, src_id, dst_id,
        !           678:                                                                                pen_type_create(msg_vid, msg_subtype));
        !           679:        this->pa_msg = pa_tnc_msg_create_from_data(msg);
        !           680: 
        !           681:        return &this->public;
        !           682: }

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