Annotation of embedaddon/strongswan/src/libimcv/plugins/imc_swima/imc_swima.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 "imc_swima_state.h"
                     17: 
                     18: #include <imc/imc_agent.h>
                     19: #include <imc/imc_msg.h>
                     20: #include "ietf/swima/ietf_swima_attr_req.h"
                     21: #include "ietf/swima/ietf_swima_attr_sw_inv.h"
                     22: #include "ietf/swima/ietf_swima_attr_sw_ev.h"
                     23: #include "swima/swima_inventory.h"
                     24: #include "swima/swima_collector.h"
                     25: #include "swima/swima_error.h"
                     26: #include "tcg/seg/tcg_seg_attr_max_size.h"
                     27: #include "tcg/seg/tcg_seg_attr_seg_env.h"
                     28: 
                     29: #include <tncif_pa_subtypes.h>
                     30: #include <pen/pen.h>
                     31: #include <utils/debug.h>
                     32: 
                     33: #include <errno.h>
                     34: #include <poll.h>
                     35: #include <stdio.h>
                     36: #include <stdlib.h>
                     37: #include <sys/inotify.h>
                     38: #include <unistd.h>
                     39: 
                     40: #ifndef SW_COLLECTOR
                     41: #define SW_COLLECTOR NULL
                     42: #endif
                     43: 
                     44: /* IMC definitions */
                     45: 
                     46: static const char imc_name[] = "SWIMA";
                     47: 
                     48: static pen_type_t msg_types[] = {
                     49:        { PEN_IETF, PA_SUBTYPE_IETF_SWIMA }
                     50: };
                     51: 
                     52: static imc_agent_t *imc_swima;
                     53: 
                     54: /**
                     55:  * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
                     56:  */
                     57: TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
                     58:                                                          TNC_Version min_version,
                     59:                                                          TNC_Version max_version,
                     60:                                                          TNC_Version *actual_version)
                     61: {
                     62:        if (imc_swima)
                     63:        {
                     64:                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
                     65:                return TNC_RESULT_ALREADY_INITIALIZED;
                     66:        }
                     67:        imc_swima = imc_agent_create(imc_name, msg_types, countof(msg_types),
                     68:                                                                 imc_id, actual_version);
                     69:        if (!imc_swima)
                     70:        {
                     71:                return TNC_RESULT_FATAL;
                     72:        }
                     73:        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
                     74:        {
                     75:                DBG1(DBG_IMC, "no common IF-IMC version");
                     76:                return TNC_RESULT_NO_COMMON_VERSION;
                     77:        }
                     78:        return TNC_RESULT_SUCCESS;
                     79: }
                     80: 
                     81: /**
                     82:  * Poll for IN_CLOSE_WRITE event on the apt history.log
                     83:  */
                     84: static bool poll_history_log(void)
                     85: {
                     86:        int fd, wd, res;
                     87:        nfds_t nfds;
                     88:        struct pollfd fds[1];
                     89:        char *history_path;
                     90:        bool success = FALSE;
                     91: 
                     92:        history_path = lib->settings->get_str(lib->settings, "sw-collector.history",
                     93:                                                                                  NULL);
                     94:        if (!history_path)
                     95:        {
                     96:                DBG1(DBG_IMC, "sw-collector.history path not set");
                     97:                return FALSE;
                     98:        }
                     99: 
                    100:        /* Create the file descriptor for accessing the inotify API */
                    101:        fd = inotify_init1(IN_NONBLOCK);
                    102:        if (fd == -1)
                    103:        {
                    104:                DBG1(DBG_IMC, "inotify file descriptor could not be created");
                    105:                return FALSE;
                    106:        }
                    107: 
                    108:        /* Watch for CLOSE_WRITE events on history log */
                    109:        wd = inotify_add_watch(fd, history_path, IN_CLOSE_WRITE);
                    110:        if (wd == -1)
                    111:        {
                    112:                DBG1(DBG_IMC, "cannot watch '%s'", history_path);
                    113:                goto end;
                    114:        }
                    115: 
                    116:        /* Prepare for polling */
                    117:        nfds = 1;
                    118: 
                    119:        /* Inotify input */
                    120:        fds[0].fd = fd;
                    121:        fds[0].events = POLLIN;
                    122: 
                    123:        while (1)
                    124:        {
                    125:                DBG1(DBG_IMC, "  waiting for write event on history.log ...");
                    126: 
                    127:                res = poll(fds, nfds, -1);
                    128:                if (res == -1)
                    129:                {
                    130:                        DBG1(DBG_IMC, "  poll failed: %s", strerror(errno));
                    131:                        if (errno == EINTR)
                    132:                        {
                    133:                                continue;
                    134:                        }
                    135:                        goto end;
                    136:                }
                    137:                if (res > 0 &&  fds[0].revents & POLLIN)
                    138:                {
                    139:                        DBG1(DBG_IMC, "  poll successful");
                    140:                        success = TRUE;
                    141:                        break;
                    142:                }
                    143:        }
                    144: 
                    145: end:
                    146:        close(fd);
                    147:        return success;
                    148: }
                    149: 
                    150: /**
                    151:  * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
                    152:  */
                    153: TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
                    154:                                                                                  TNC_ConnectionID connection_id,
                    155:                                                                                  TNC_ConnectionState new_state)
                    156: {
                    157:        imc_state_t *state;
                    158:        imc_swima_state_t *swima_state;
                    159:        imc_swima_subscription_t *subscription;
                    160:        TNC_IMV_Evaluation_Result res;
                    161:        TNC_Result result;
                    162:        uint32_t eid, eid_epoch;
                    163: 
                    164:        if (!imc_swima)
                    165:        {
                    166:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    167:                return TNC_RESULT_NOT_INITIALIZED;
                    168:        }
                    169:        switch (new_state)
                    170:        {
                    171:                case TNC_CONNECTION_STATE_CREATE:
                    172:                        state = imc_swima_state_create(connection_id);
                    173:                        return imc_swima->create_state(imc_swima, state);
                    174:                case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
                    175:                case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
                    176:                case TNC_CONNECTION_STATE_ACCESS_NONE:
                    177:                        /* get updated IMC state */
                    178:                        result = imc_swima->change_state(imc_swima, connection_id,
                    179:                                                                                         new_state, &state);
                    180:                        if (result != TNC_RESULT_SUCCESS)
                    181:                        {
                    182:                                return TNC_RESULT_FATAL;
                    183:                        }
                    184:                        swima_state = (imc_swima_state_t*)state;
                    185: 
                    186:                        /* do a handshake retry? */
                    187:                        if (swima_state->get_subscription(swima_state, &subscription))
                    188:                        {
                    189:                                /* update earliest EID in subscription target */
                    190:                                if (state->get_result(state, imc_id, &res) &&
                    191:                                        res == TNC_IMV_EVALUATION_RESULT_COMPLIANT)
                    192:                                {
                    193:                                        eid = subscription->targets->get_eid(subscription->targets,
                    194:                                                                                                   &eid_epoch);
                    195:                                        if (eid > 0)
                    196:                                        {
                    197:                                                eid = swima_state->get_earliest_eid(swima_state);
                    198:                                                subscription->targets->set_eid(subscription->targets, eid,
                    199:                                                                                                           eid_epoch);
                    200:                                        }
                    201:                                }
                    202:                                DBG1(DBG_IMC, "SWIMA subscription %u:", subscription->request_id);
                    203:                                if (!poll_history_log())
                    204:                                {
                    205:                                        return TNC_RESULT_FATAL;
                    206:                                }
                    207:                                return imc_swima->request_handshake_retry(imc_id, connection_id,
                    208:                                                                                                TNC_RETRY_REASON_IMC_PERIODIC);
                    209:                        }
                    210:                        return TNC_RESULT_SUCCESS;
                    211:                case TNC_CONNECTION_STATE_DELETE:
                    212:                        return imc_swima->delete_state(imc_swima, connection_id);
                    213:                default:
                    214:                        return imc_swima->change_state(imc_swima, connection_id,
                    215:                                                                                   new_state, NULL);
                    216:        }
                    217: }
                    218: 
                    219: /**
                    220:  * Add SWID Inventory or Event attribute to the send queue
                    221:  */
                    222: static void fulfill_request(imc_state_t *state, imc_msg_t *msg,
                    223:                                                           uint32_t request_id, bool sw_id_only,
                    224:                                                           swima_inventory_t *targets)
                    225: {
                    226:        pa_tnc_attr_t *attr;
                    227:        swima_collector_t  *collector;
                    228:        size_t msg_len = 64;
                    229:        char error_msg[msg_len], *id_str;
                    230:        bool collect_inventory = TRUE;
                    231:        int items;
                    232: 
                    233:        collector = swima_collector_create();
                    234:        id_str = sw_id_only ? " ID" : "";
                    235: 
                    236:        if (targets->get_eid(targets, NULL) > 0)
                    237:        {
                    238:                swima_events_t *sw_ev;
                    239:                ietf_swima_attr_sw_ev_t *sw_ev_attr;
                    240:                imc_swima_state_t *swima_state;
                    241:                uint32_t eid_epoch, last_eid = 0;
                    242: 
                    243:                sw_ev = collector->collect_events(collector, sw_id_only, targets);
                    244:                if (!sw_ev)
                    245:                {
                    246:                        snprintf(error_msg, msg_len, "failed to collect SW%s events, "
                    247:                                         "fallback to SW%s inventory", id_str, id_str);
                    248:                        attr = swima_error_create(PA_ERROR_SWIMA, request_id, 0, error_msg);
                    249:                        msg->add_attribute(msg, attr);
                    250:                }
                    251:                else {
                    252:                        items = sw_ev->get_count(sw_ev);
                    253:                        last_eid = sw_ev->get_eid(sw_ev, &eid_epoch, NULL);
                    254: 
                    255:                        DBG1(DBG_IMC, "collected %d SW%s event%s at last eid %d of epoch 0x%08x",
                    256:                                 items, id_str, items == 1 ? "" : "s", last_eid, eid_epoch);
                    257: 
                    258:                        /* Store the earliest EID for the next subscription round */
                    259:                        swima_state = (imc_swima_state_t*)state;
                    260:                        swima_state->set_earliest_eid(swima_state, last_eid + 1);
                    261: 
                    262:                        /* Send an IETF SW [Identity] Events attribute */
                    263:                        attr = ietf_swima_attr_sw_ev_create(IETF_SWIMA_ATTR_SW_INV_FLAG_NONE,
                    264:                                                                                         request_id, sw_id_only);
                    265:                        sw_ev_attr = (ietf_swima_attr_sw_ev_t*)attr;
                    266:                        sw_ev_attr->set_events(sw_ev_attr, sw_ev);
                    267:                        collect_inventory = FALSE;
                    268:                }
                    269:        }
                    270: 
                    271:        if (collect_inventory)
                    272:        {
                    273:                swima_inventory_t *sw_inv;
                    274:                ietf_swima_attr_sw_inv_t *sw_inv_attr;
                    275: 
                    276:                sw_inv = collector->collect_inventory(collector, sw_id_only, targets);
                    277:                if (!sw_inv)
                    278:                {
                    279:                        snprintf(error_msg, msg_len, "failed to collect SW%s inventory",
                    280:                                         id_str);
                    281:                        attr = swima_error_create(PA_ERROR_SWIMA, request_id, 0, error_msg);
                    282:                }
                    283:                else
                    284:                {
                    285:                        items = sw_inv->get_count(sw_inv);
                    286:                        DBG1(DBG_IMC, "collected %d SW%s record%s", items, id_str,
                    287:                                                                                                                items == 1 ? "" : "s");
                    288: 
                    289:                        /* Send an IETF SW [Identity] Inventory attribute */
                    290:                        attr = ietf_swima_attr_sw_inv_create(IETF_SWIMA_ATTR_SW_INV_FLAG_NONE,
                    291:                                                                                                 request_id, sw_id_only);
                    292:                        sw_inv_attr = (ietf_swima_attr_sw_inv_t*)attr;
                    293:                        sw_inv_attr->set_inventory(sw_inv_attr, sw_inv);
                    294:                }
                    295:        }
                    296:        msg->add_attribute(msg, attr);
                    297:        collector->destroy(collector);
                    298: }
                    299: 
                    300: /**
                    301:  * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
                    302:  */
                    303: TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                    304:                                                                  TNC_ConnectionID connection_id)
                    305: {
                    306:        imc_state_t *state;
                    307:        imc_swima_state_t *swima_state;
                    308:        imc_msg_t *out_msg;
                    309:        pa_tnc_attr_t *attr;
                    310:        seg_contract_t *contract;
                    311:        seg_contract_manager_t *contracts;
                    312:        imc_swima_subscription_t *subscription;
                    313:        size_t max_attr_size = SWIMA_MAX_ATTR_SIZE;
                    314:        size_t max_seg_size;
                    315:        char buf[BUF_LEN];
                    316:        TNC_Result result = TNC_RESULT_SUCCESS;
                    317: 
                    318:        if (!imc_swima)
                    319:        {
                    320:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    321:                return TNC_RESULT_NOT_INITIALIZED;
                    322:        }
                    323:        if (!imc_swima->get_state(imc_swima, connection_id, &state))
                    324:        {
                    325:                return TNC_RESULT_FATAL;
                    326:        }
                    327:        swima_state = (imc_swima_state_t*)state;
                    328: 
                    329:        if (swima_state->get_subscription(swima_state, &subscription))
                    330:        {
                    331:                if (system(SW_COLLECTOR) != 0)
                    332:                {
                    333:                        DBG1(DBG_IMC, "calling %s failed", SW_COLLECTOR);
                    334:                        return TNC_RESULT_FATAL;
                    335:                }
                    336:                out_msg = imc_msg_create(imc_swima, state, connection_id, imc_id,
                    337:                                                                 subscription->imv_id, msg_types[0]);
                    338:                fulfill_request(state, out_msg, subscription->request_id,
                    339:                                                subscription->sw_id_only, subscription->targets);
                    340:        }
                    341:        else
                    342:        {
                    343:                /* Determine maximum PA-TNC attribute segment size */
                    344:                max_seg_size = state->get_max_msg_len(state) - PA_TNC_HEADER_SIZE
                    345:                                                                                                         - PA_TNC_ATTR_HEADER_SIZE
                    346:                                                                                                 - TCG_SEG_ATTR_SEG_ENV_HEADER;
                    347: 
                    348:                /* Announce support of PA-TNC segmentation to IMV */
                    349:                contract = seg_contract_create(msg_types[0], max_attr_size, max_seg_size,
                    350:                                                                           TRUE, imc_id, TRUE);
                    351:                contract->get_info_string(contract, buf, BUF_LEN, TRUE);
                    352:                DBG2(DBG_IMC, "%s", buf);
                    353:                contracts = state->get_contracts(state);
                    354:                contracts->add_contract(contracts, contract);
                    355:                attr = tcg_seg_attr_max_size_create(max_attr_size, max_seg_size, TRUE);
                    356: 
                    357:                /* send PA-TNC message with the excl flag not set */
                    358:                out_msg = imc_msg_create(imc_swima, state, connection_id, imc_id,
                    359:                                                                 TNC_IMVID_ANY, msg_types[0]);
                    360:                out_msg->add_attribute(out_msg, attr);
                    361:        }
                    362:        result = out_msg->send(out_msg, FALSE);
                    363:        out_msg->destroy(out_msg);
                    364: 
                    365:        return result;
                    366: }
                    367: 
                    368: static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
                    369: {
                    370:        imc_msg_t *out_msg;
                    371:        imc_swima_state_t *swima_state;
                    372:        pa_tnc_attr_t *attr;
                    373:        enumerator_t *enumerator;
                    374:        pen_type_t type;
                    375:        TNC_Result result;
                    376:        bool fatal_error = FALSE;
                    377: 
                    378:        /* generate an outgoing PA-TNC message - we might need it */
                    379:        out_msg = imc_msg_create_as_reply(in_msg);
                    380: 
                    381:        /* parse received PA-TNC message and handle local and remote errors */
                    382:        result = in_msg->receive(in_msg, out_msg, &fatal_error);
                    383:        if (result != TNC_RESULT_SUCCESS)
                    384:        {
                    385:                out_msg->destroy(out_msg);
                    386:                return result;
                    387:        }
                    388: 
                    389:        /* analyze PA-TNC attributes */
                    390:        enumerator = in_msg->create_attribute_enumerator(in_msg);
                    391:        while (enumerator->enumerate(enumerator, &attr))
                    392:        {
                    393:                ietf_swima_attr_req_t *attr_req;
                    394:                uint8_t flags;
                    395:                uint32_t request_id;
                    396:                bool sw_id_only;
                    397:                swima_inventory_t *targets;
                    398:                type = attr->get_type(attr);
                    399: 
                    400:                if (type.vendor_id != PEN_IETF || type.type != IETF_ATTR_SWIMA_REQUEST)
                    401:                {
                    402:                        continue;
                    403:                }
                    404: 
                    405:                attr_req = (ietf_swima_attr_req_t*)attr;
                    406:                flags = attr_req->get_flags(attr_req);
                    407:                request_id = attr_req->get_request_id(attr_req);
                    408:                targets = attr_req->get_targets(attr_req);
                    409:                sw_id_only = (flags & IETF_SWIMA_ATTR_REQ_FLAG_R);
                    410: 
                    411:                if (flags & (IETF_SWIMA_ATTR_REQ_FLAG_S | IETF_SWIMA_ATTR_REQ_FLAG_C))
                    412:                {
                    413:                        if (imc_swima->has_pt_tls(imc_swima) &&
                    414:                                lib->settings->get_bool(lib->settings,
                    415:                                        "%s.plugins.imc-swima.subscriptions", FALSE, lib->ns))
                    416:                        {
                    417:                                imc_swima_subscription_t *subscription;
                    418: 
                    419:                                swima_state = (imc_swima_state_t*)state;
                    420: 
                    421:                                if (flags & IETF_SWIMA_ATTR_REQ_FLAG_C)
                    422:                                {
                    423:                                        if (swima_state->get_subscription(swima_state, &subscription))
                    424:                                        {
                    425:                                                DBG1(DBG_IMC, "SWIMA subscription %u cleared",
                    426:                                                                           subscription->request_id);
                    427:                                                swima_state->set_subscription(swima_state, NULL, FALSE);
                    428:                                        }
                    429:                                }
                    430:                                else
                    431:                                {
                    432:                                        INIT(subscription,
                    433:                                                .imv_id = in_msg->get_src_id(in_msg),
                    434:                                                .request_id = request_id,
                    435:                                                .targets = targets->get_ref(targets),
                    436:                                                .sw_id_only = sw_id_only,
                    437:                                        );
                    438: 
                    439:                                        swima_state->set_subscription(swima_state, subscription,
                    440:                                                                                                  TRUE);
                    441:                                        DBG1(DBG_IMC, "SWIMA subscription %u established",
                    442:                                                                   subscription->request_id);
                    443:                                        if (system(SW_COLLECTOR) != 0)
                    444:                                        {
                    445:                                                DBG1(DBG_IMC, "calling %s failed", SW_COLLECTOR);
                    446:                                                out_msg->destroy(out_msg);
                    447:                                                return TNC_RESULT_FATAL;
                    448:                                        }
                    449:                                }
                    450:                        }
                    451:                        else
                    452:                        {
                    453:                                attr = swima_error_create(PA_ERROR_SWIMA_SUBSCRIPTION_DENIED,
                    454:                                                        request_id, 0, "subscriptions not enabled");
                    455:                                out_msg->add_attribute(out_msg, attr);
                    456:                        }
                    457:                }
                    458: 
                    459:                fulfill_request(state, out_msg, request_id, sw_id_only, targets);
                    460:                break;
                    461:        }
                    462:        enumerator->destroy(enumerator);
                    463: 
                    464:        if (fatal_error)
                    465:        {
                    466:                result = TNC_RESULT_FATAL;
                    467:        }
                    468:        else
                    469:        {
                    470:                /* send PA-TNC message with the EXCL flag set */
                    471:                result = out_msg->send(out_msg, TRUE);
                    472:        }
                    473:        out_msg->destroy(out_msg);
                    474: 
                    475:        return result;
                    476: }
                    477: 
                    478: /**
                    479:  * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
                    480: 
                    481:  */
                    482: TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                    483:                                                                  TNC_ConnectionID connection_id,
                    484:                                                                  TNC_BufferReference msg,
                    485:                                                                  TNC_UInt32 msg_len,
                    486:                                                                  TNC_MessageType msg_type)
                    487: {
                    488:        imc_state_t *state;
                    489:        imc_msg_t *in_msg;
                    490:        TNC_Result result;
                    491: 
                    492:        if (!imc_swima)
                    493:        {
                    494:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    495:                return TNC_RESULT_NOT_INITIALIZED;
                    496:        }
                    497:        if (!imc_swima->get_state(imc_swima, connection_id, &state))
                    498:        {
                    499:                return TNC_RESULT_FATAL;
                    500:        }
                    501:        in_msg = imc_msg_create_from_data(imc_swima, state, connection_id, msg_type,
                    502:                                                                          chunk_create(msg, msg_len));
                    503:        result = receive_message(state, in_msg);
                    504:        in_msg->destroy(in_msg);
                    505: 
                    506:        return result;
                    507: }
                    508: 
                    509: /**
                    510:  * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
                    511:  */
                    512: TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                    513:                                                                          TNC_ConnectionID connection_id,
                    514:                                                                          TNC_UInt32 msg_flags,
                    515:                                                                          TNC_BufferReference msg,
                    516:                                                                          TNC_UInt32 msg_len,
                    517:                                                                          TNC_VendorID msg_vid,
                    518:                                                                          TNC_MessageSubtype msg_subtype,
                    519:                                                                          TNC_UInt32 src_imv_id,
                    520:                                                                          TNC_UInt32 dst_imc_id)
                    521: {
                    522:        imc_state_t *state;
                    523:        imc_msg_t *in_msg;
                    524:        TNC_Result result;
                    525: 
                    526:        if (!imc_swima)
                    527:        {
                    528:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    529:                return TNC_RESULT_NOT_INITIALIZED;
                    530:        }
                    531:        if (!imc_swima->get_state(imc_swima, connection_id, &state))
                    532:        {
                    533:                return TNC_RESULT_FATAL;
                    534:        }
                    535:        in_msg = imc_msg_create_from_long_data(imc_swima, state, connection_id,
                    536:                                                                src_imv_id, dst_imc_id,msg_vid, msg_subtype,
                    537:                                                                chunk_create(msg, msg_len));
                    538:        result =receive_message(state, in_msg);
                    539:        in_msg->destroy(in_msg);
                    540: 
                    541:        return result;
                    542: }
                    543: 
                    544: /**
                    545:  * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
                    546:  */
                    547: TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
                    548:                                                           TNC_ConnectionID connection_id)
                    549: {
                    550:        if (!imc_swima)
                    551:        {
                    552:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    553:                return TNC_RESULT_NOT_INITIALIZED;
                    554:        }
                    555:        return TNC_RESULT_SUCCESS;
                    556: }
                    557: 
                    558: /**
                    559:  * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
                    560:  */
                    561: TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
                    562: {
                    563:        if (!imc_swima)
                    564:        {
                    565:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    566:                return TNC_RESULT_NOT_INITIALIZED;
                    567:        }
                    568:        imc_swima->destroy(imc_swima);
                    569:        imc_swima = NULL;
                    570: 
                    571:        return TNC_RESULT_SUCCESS;
                    572: }
                    573: 
                    574: /**
                    575:  * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
                    576:  */
                    577: TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
                    578:                                                                           TNC_TNCC_BindFunctionPointer bind_function)
                    579: {
                    580:        if (!imc_swima)
                    581:        {
                    582:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    583:                return TNC_RESULT_NOT_INITIALIZED;
                    584:        }
                    585:        return imc_swima->bind_functions(imc_swima, bind_function);
                    586: }

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