Annotation of embedaddon/strongswan/src/libimcv/plugins/imc_os/imc_os.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011-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_os_state.h"
                     17: 
                     18: #include <imc/imc_agent.h>
                     19: #include <imc/imc_msg.h>
                     20: #include <imc/imc_os_info.h>
                     21: #include <generic/generic_attr_bool.h>
                     22: #include <generic/generic_attr_string.h>
                     23: #include <ietf/ietf_attr.h>
                     24: #include <ietf/ietf_attr_attr_request.h>
                     25: #include "ietf/ietf_attr_fwd_enabled.h"
                     26: #include <ietf/ietf_attr_installed_packages.h>
                     27: #include <ietf/ietf_attr_numeric_version.h>
                     28: #include <ietf/ietf_attr_op_status.h>
                     29: #include <ietf/ietf_attr_product_info.h>
                     30: #include <ietf/ietf_attr_string_version.h>
                     31: #include <ita/ita_attr.h>
                     32: #include <ita/ita_attr_get_settings.h>
                     33: #include <ita/ita_attr_settings.h>
                     34: 
                     35: #include <tncif_pa_subtypes.h>
                     36: 
                     37: #include <pen/pen.h>
                     38: #include <utils/debug.h>
                     39: 
                     40: /* IMC definitions */
                     41: 
                     42: static const char imc_name[] = "OS";
                     43: 
                     44: static pen_type_t msg_types[] = {
                     45:        { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM }
                     46: };
                     47: 
                     48: static imc_agent_t *imc_os;
                     49: static imc_os_info_t *os;
                     50: 
                     51: /**
                     52:  * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
                     53:  */
                     54: TNC_Result TNC_IMC_API TNC_IMC_Initialize(TNC_IMCID imc_id,
                     55:                                                                                  TNC_Version min_version,
                     56:                                                                                  TNC_Version max_version,
                     57:                                                                                  TNC_Version *actual_version)
                     58: {
                     59:        if (imc_os)
                     60:        {
                     61:                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
                     62:                return TNC_RESULT_ALREADY_INITIALIZED;
                     63:        }
                     64:        imc_os = imc_agent_create(imc_name, msg_types, countof(msg_types),
                     65:                                                          imc_id, actual_version);
                     66:        if (!imc_os)
                     67:        {
                     68:                return TNC_RESULT_FATAL;
                     69:        }
                     70: 
                     71:        os = imc_os_info_create();
                     72:        if (!os)
                     73:        {
                     74:                imc_os->destroy(imc_os);
                     75:                imc_os = NULL;
                     76: 
                     77:                return TNC_RESULT_FATAL;
                     78:        }
                     79: 
                     80:        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
                     81:        {
                     82:                DBG1(DBG_IMC, "no common IF-IMC version");
                     83:                return TNC_RESULT_NO_COMMON_VERSION;
                     84:        }
                     85:        return TNC_RESULT_SUCCESS;
                     86: }
                     87: 
                     88: /**
                     89:  * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
                     90:  */
                     91: TNC_Result TNC_IMC_API TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
                     92:                                TNC_ConnectionID connection_id, TNC_ConnectionState new_state)
                     93: {
                     94:        imc_state_t *state;
                     95: 
                     96:        if (!imc_os)
                     97:        {
                     98:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                     99:                return TNC_RESULT_NOT_INITIALIZED;
                    100:        }
                    101:        switch (new_state)
                    102:        {
                    103:                case TNC_CONNECTION_STATE_CREATE:
                    104:                        state = imc_os_state_create(connection_id);
                    105:                        return imc_os->create_state(imc_os, state);
                    106:                case TNC_CONNECTION_STATE_DELETE:
                    107:                        return imc_os->delete_state(imc_os, connection_id);
                    108:                default:
                    109:                        return imc_os->change_state(imc_os, connection_id,
                    110:                                                                                         new_state, NULL);
                    111:        }
                    112: }
                    113: 
                    114: /**
                    115:  * Add IETF Product Information attribute to the send queue
                    116:  */
                    117: static void add_product_info(imc_msg_t *msg)
                    118: {
                    119:        pa_tnc_attr_t *attr;
                    120:        os_type_t os_type;
                    121:        pen_t vendor_id = PEN_IETF;
                    122:        int i;
                    123: 
                    124:        typedef struct vendor_pen_t {
                    125:                os_type_t os_type;
                    126:                pen_t pen;
                    127:        } vendor_pen_t;
                    128: 
                    129:        vendor_pen_t vendor_pens[] = {
                    130:                { OS_TYPE_DEBIAN,  PEN_DEBIAN },
                    131:                { OS_TYPE_UBUNTU,  PEN_CANONICAL },
                    132:                { OS_TYPE_FEDORA,  PEN_FEDORA },
                    133:                { OS_TYPE_REDHAT,  PEN_REDHAT },
                    134:                { OS_TYPE_ANDROID, PEN_GOOGLE }
                    135:        };
                    136: 
                    137:        os_type = os->get_type(os);
                    138:        for (i = 0; i < countof(vendor_pens); i++)
                    139:        {
                    140:                if (os_type == vendor_pens[i].os_type)
                    141:                {
                    142:                        vendor_id = vendor_pens[i].pen;
                    143:                        break;
                    144:                }
                    145:        }
                    146:        attr = ietf_attr_product_info_create(vendor_id, 0, os->get_name(os));
                    147:        msg->add_attribute(msg, attr);
                    148: }
                    149: 
                    150: /**
                    151:  * Add IETF Numeric Version attribute to the send queue
                    152:  */
                    153: static void add_numeric_version(imc_msg_t *msg)
                    154: {
                    155:        pa_tnc_attr_t *attr;
                    156:        uint32_t major, minor;
                    157: 
                    158:        os->get_numeric_version(os, &major, &minor);
                    159:        DBG1(DBG_IMC, "operating system numeric version is %d.%d",
                    160:                                   major, minor);
                    161: 
                    162:        attr = ietf_attr_numeric_version_create(major, minor, 0, 0, 0);
                    163:        msg->add_attribute(msg, attr);
                    164: }
                    165: 
                    166: /**
                    167:  * Add IETF String Version attribute to the send queue
                    168:  */
                    169: static void add_string_version(imc_msg_t *msg)
                    170: {
                    171:        pa_tnc_attr_t *attr;
                    172: 
                    173:        attr = ietf_attr_string_version_create(os->get_version(os),
                    174:                                                                                   chunk_empty, chunk_empty);
                    175:        msg->add_attribute(msg, attr);
                    176: }
                    177: 
                    178: /**
                    179:  * Add IETF Operational Status attribute to the send queue
                    180:  */
                    181: static void add_op_status(imc_msg_t *msg)
                    182: {
                    183:        pa_tnc_attr_t *attr;
                    184:        time_t uptime, last_boot;
                    185: 
                    186:        uptime = os->get_uptime(os);
                    187:        last_boot = uptime ? time(NULL) - uptime : UNDEFINED_TIME;
                    188:        if (last_boot != UNDEFINED_TIME)
                    189:        {
                    190:                DBG1(DBG_IMC, "last boot: %T, %u s ago", &last_boot, TRUE, uptime);
                    191:        }
                    192:        attr = ietf_attr_op_status_create(OP_STATUS_OPERATIONAL,
                    193:                                                                          OP_RESULT_SUCCESSFUL, last_boot);
                    194:        msg->add_attribute(msg, attr);
                    195: }
                    196: 
                    197: /**
                    198:  * Add IETF Forwarding Enabled attribute to the send queue
                    199:  */
                    200: static void add_fwd_enabled(imc_msg_t *msg)
                    201: {
                    202:        pa_tnc_attr_t *attr;
                    203:        os_fwd_status_t fwd_status;
                    204: 
                    205:        fwd_status = os->get_fwd_status(os);
                    206:        DBG1(DBG_IMC, "IPv4 forwarding is %N", os_fwd_status_names, fwd_status);
                    207:        attr = ietf_attr_fwd_enabled_create(fwd_status,
                    208:                                pen_type_create(PEN_IETF, IETF_ATTR_FORWARDING_ENABLED));
                    209:        msg->add_attribute(msg, attr);
                    210: }
                    211: 
                    212: /**
                    213:  * Add IETF Factory Default Password Enabled attribute to the send queue
                    214:  */
                    215: static void add_default_pwd_enabled(imc_msg_t *msg)
                    216: {
                    217:        pa_tnc_attr_t *attr;
                    218:        bool status;
                    219: 
                    220:        status = os->get_default_pwd_status(os);
                    221:        DBG1(DBG_IMC, "factory default password is %sabled", status ? "en" : "dis");
                    222:        attr = generic_attr_bool_create(status,
                    223:                        pen_type_create(PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED));
                    224:        msg->add_attribute(msg, attr);
                    225: }
                    226: 
                    227: /**
                    228:  * Add ITA Device ID attribute to the send queue
                    229:  */
                    230: static void add_device_id(imc_msg_t *msg)
                    231: {
                    232:        pa_tnc_attr_t *attr;
                    233:        chunk_t chunk, value = chunk_empty, keyid;
                    234:        char *name, *device_id, *device_handle, *cert_path;
                    235:        certificate_t *cert = NULL;
                    236:        private_key_t *privkey = NULL;
                    237:        public_key_t *pubkey;
                    238: 
                    239:        /* Get the device ID as a character string */
                    240:        device_id = lib->settings->get_str(lib->settings,
                    241:                                                "%s.plugins.imc-os.device_id", NULL, lib->ns);
                    242:        if (device_id)
                    243:        {
                    244:                value = chunk_clone(chunk_from_str(device_id));
                    245:        }
                    246: 
                    247:        if (value.len == 0)
                    248:        {
                    249:                /* Derive the device ID from a private key bound to a smartcard or TPM */
                    250:                device_handle = lib->settings->get_str(lib->settings,
                    251:                                                "%s.plugins.imc-os.device_handle", NULL, lib->ns);
                    252:                if (device_handle)
                    253:                {
                    254:                        chunk = chunk_from_hex(
                    255:                                        chunk_create(device_handle, strlen(device_handle)), NULL);
                    256:                        privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
                    257:                                                                                 BUILD_PKCS11_KEYID, chunk, BUILD_END);
                    258:                        free(chunk.ptr);
                    259: 
                    260:                        if (privkey)
                    261:                        {
                    262:                                if (privkey->get_fingerprint(privkey, KEYID_PUBKEY_INFO_SHA1,
                    263:                                                                                         &keyid))
                    264:                                {
                    265:                                        value = chunk_to_hex(keyid, NULL, FALSE);
                    266:                                }
                    267:                                privkey->destroy(privkey);
                    268: 
                    269:                        }
                    270:                }
                    271:        }
                    272: 
                    273:        if (value.len == 0)
                    274:        {
                    275:                /* Derive the device ID from a raw public key */
                    276:                cert_path = lib->settings->get_str(lib->settings,
                    277:                                                        "%s.plugins.imc-os.device_pubkey", NULL, lib->ns);
                    278:                if (cert_path)
                    279:                {
                    280:                        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
                    281:                                                                          CERT_TRUSTED_PUBKEY, BUILD_FROM_FILE,
                    282:                                                                          cert_path, BUILD_END);
                    283:                        if (cert)
                    284:                        {
                    285:                                DBG2(DBG_IMC, "loaded device public key from '%s'", cert_path);
                    286:                        }
                    287:                        else
                    288:                        {
                    289:                                DBG1(DBG_IMC, "loading device public key from '%s' failed",
                    290:                                                           cert_path);
                    291:                        }
                    292:                }
                    293: 
                    294:                if (!cert)
                    295:                {
                    296:                        /* Derive the device ID from the public key contained in a certificate */
                    297:                        cert_path = lib->settings->get_str(lib->settings,
                    298:                                                                "%s.plugins.imc-os.device_cert", NULL, lib->ns);
                    299:                        if (cert_path)
                    300:                        {
                    301:                                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
                    302:                                                                                  CERT_X509, BUILD_FROM_FILE,
                    303:                                                                                  cert_path, BUILD_END);
                    304:                                if (cert)
                    305:                                {
                    306:                                        DBG2(DBG_IMC, "loaded device certificate from '%s'", cert_path);
                    307:                                }
                    308:                                else
                    309:                                {
                    310:                                        DBG1(DBG_IMC, "loading device certificate from '%s' failed",
                    311:                                                                   cert_path);
                    312:                                }
                    313:                        }
                    314:                }
                    315: 
                    316:                /* Compute the SHA-1 keyid of the retrieved device public key */
                    317:                if (cert)
                    318:                {
                    319:                        pubkey = cert->get_public_key(cert);
                    320:                        if (pubkey)
                    321:                        {
                    322:                                if (pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1,
                    323:                                                                                        &keyid))
                    324:                                {
                    325:                                        value = chunk_to_hex(keyid, NULL, FALSE);
                    326:                                }
                    327:                                pubkey->destroy(pubkey);
                    328:                        }
                    329:                        cert->destroy(cert);
                    330:                }
                    331:        }
                    332: 
                    333:        if (value.len == 0)
                    334:        {
                    335:                /* Derive the device ID from some unique OS settings */
                    336:                name = os->get_type(os) == OS_TYPE_ANDROID ?
                    337:                                          "android_id" : "/var/lib/dbus/machine-id";
                    338:                value = os->get_setting(os, name);
                    339: 
                    340:                /* Trim trailing newline character */
                    341:                if (value.len > 0 && value.ptr[value.len - 1] == '\n')
                    342:                {
                    343:                        value.len--;
                    344:                }
                    345:        }
                    346: 
                    347:        if (value.len == 0)
                    348:        {
                    349:                DBG1(DBG_IMC, "no device ID available");
                    350:                return;
                    351:        }
                    352: 
                    353:        DBG1(DBG_IMC, "device ID is %.*s", value.len, value.ptr);
                    354:        attr = generic_attr_string_create(value, pen_type_create(PEN_ITA,
                    355:                                                                          ITA_ATTR_DEVICE_ID));
                    356:        msg->add_attribute(msg, attr);
                    357:        free(value.ptr);
                    358: }
                    359: 
                    360: /**
                    361:  * Add an IETF Installed Packages attribute to the send queue
                    362:  */
                    363: static void add_installed_packages(imc_state_t *state, imc_msg_t *msg)
                    364: {
                    365:        pa_tnc_attr_t *attr;
                    366:        ietf_attr_installed_packages_t *attr_cast;
                    367:        enumerator_t *enumerator;
                    368:        chunk_t name, version;
                    369: 
                    370:        enumerator = os->create_package_enumerator(os);
                    371:        if (!enumerator)
                    372:        {
                    373:                return;
                    374:        }
                    375:        attr = ietf_attr_installed_packages_create();
                    376: 
                    377:        while (enumerator->enumerate(enumerator, &name, &version))
                    378:        {
                    379:                DBG2(DBG_IMC, "package '%.*s' (%.*s)",
                    380:                                           name.len, name.ptr, version.len, version.ptr);
                    381:                attr_cast = (ietf_attr_installed_packages_t*)attr;
                    382:                attr_cast->add(attr_cast, name, version);
                    383:        }
                    384:        enumerator->destroy(enumerator);
                    385: 
                    386:        msg->add_attribute(msg, attr);
                    387: }
                    388: 
                    389: /**
                    390:  * Add ITA Settings attribute to the send queue
                    391:  */
                    392: static void add_settings(enumerator_t *enumerator, imc_msg_t *msg)
                    393: {
                    394:        pa_tnc_attr_t *attr = NULL;
                    395:        ita_attr_settings_t *attr_cast;
                    396:        chunk_t value;
                    397:        char *name;
                    398:        bool first = TRUE;
                    399: 
                    400:        while (enumerator->enumerate(enumerator, &name))
                    401:        {
                    402:                DBG1(DBG_IMC, "setting '%s'", name);
                    403: 
                    404:                value = os->get_setting(os, name);
                    405:                if (!value.ptr)
                    406:                {
                    407:                        continue;
                    408:                }
                    409:                if (first)
                    410:                {
                    411:                        attr = ita_attr_settings_create();
                    412:                        first = FALSE;
                    413:                }
                    414:                attr_cast = (ita_attr_settings_t*)attr;
                    415:                attr_cast->add(attr_cast, name, value);
                    416:                chunk_free(&value);
                    417:        }
                    418: 
                    419:        if (attr)
                    420:        {
                    421:                msg->add_attribute(msg, attr);
                    422:        }
                    423: }
                    424: 
                    425: /**
                    426:  * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
                    427:  */
                    428: TNC_Result TNC_IMC_API TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                    429:                                                                                          TNC_ConnectionID connection_id)
                    430: {
                    431:        imc_state_t *state;
                    432:        imc_msg_t *out_msg;
                    433:        TNC_Result result = TNC_RESULT_SUCCESS;
                    434: 
                    435:        if (!imc_os)
                    436:        {
                    437:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    438:                return TNC_RESULT_NOT_INITIALIZED;
                    439:        }
                    440:        if (!imc_os->get_state(imc_os, connection_id, &state))
                    441:        {
                    442:                return TNC_RESULT_FATAL;
                    443:        }
                    444:        if (lib->settings->get_bool(lib->settings,
                    445:                                                                "%s.plugins.imc-os.push_info", TRUE, lib->ns))
                    446:        {
                    447:                out_msg = imc_msg_create(imc_os, state, connection_id, imc_id,
                    448:                                                                 TNC_IMVID_ANY, msg_types[0]);
                    449:                add_product_info(out_msg);
                    450:                add_string_version(out_msg);
                    451:                add_numeric_version(out_msg);
                    452:                add_op_status(out_msg);
                    453:                add_fwd_enabled(out_msg);
                    454:                add_default_pwd_enabled(out_msg);
                    455:                add_device_id(out_msg);
                    456: 
                    457:                /* send PA-TNC message with the excl flag not set */
                    458:                result = out_msg->send(out_msg, FALSE);
                    459:                out_msg->destroy(out_msg);
                    460:        }
                    461: 
                    462:        return result;
                    463: }
                    464: 
                    465: static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
                    466: {
                    467:        imc_msg_t *out_msg;
                    468:        enumerator_t *enumerator;
                    469:        pa_tnc_attr_t *attr;
                    470:        pen_type_t type;
                    471:        TNC_Result result;
                    472:        bool fatal_error = FALSE;
                    473: 
                    474:        /* generate an outgoing PA-TNC message - we might need it */
                    475:        out_msg = imc_msg_create_as_reply(in_msg);
                    476: 
                    477:        /* parse received PA-TNC message and handle local and remote errors */
                    478:        result = in_msg->receive(in_msg, out_msg, &fatal_error);
                    479:        if (result != TNC_RESULT_SUCCESS)
                    480:        {
                    481:                out_msg->destroy(out_msg);
                    482:                return result;
                    483:        }
                    484: 
                    485:        /* analyze PA-TNC attributes */
                    486:        enumerator = in_msg->create_attribute_enumerator(in_msg);
                    487:        while (enumerator->enumerate(enumerator, &attr))
                    488:        {
                    489:                type = attr->get_type(attr);
                    490: 
                    491:                if (type.vendor_id == PEN_IETF)
                    492:                {
                    493:                        if (type.type == IETF_ATTR_ATTRIBUTE_REQUEST)
                    494:                        {
                    495:                                ietf_attr_attr_request_t *attr_cast;
                    496:                                pen_type_t *entry;
                    497:                                enumerator_t *e;
                    498: 
                    499:                                attr_cast = (ietf_attr_attr_request_t*)attr;
                    500: 
                    501:                                e = attr_cast->create_enumerator(attr_cast);
                    502:                                while (e->enumerate(e, &entry))
                    503:                                {
                    504:                                        if (entry->vendor_id == PEN_IETF)
                    505:                                        {
                    506:                                                switch (entry->type)
                    507:                                                {
                    508:                                                        case IETF_ATTR_PRODUCT_INFORMATION:
                    509:                                                                add_product_info(out_msg);
                    510:                                                                break;
                    511:                                                        case IETF_ATTR_STRING_VERSION:
                    512:                                                                add_string_version(out_msg);
                    513:                                                                break;
                    514:                                                        case IETF_ATTR_NUMERIC_VERSION:
                    515:                                                                add_numeric_version(out_msg);
                    516:                                                                break;
                    517:                                                        case IETF_ATTR_OPERATIONAL_STATUS:
                    518:                                                                add_op_status(out_msg);
                    519:                                                                break;
                    520:                                                        case IETF_ATTR_FORWARDING_ENABLED:
                    521:                                                                add_fwd_enabled(out_msg);
                    522:                                                                break;
                    523:                                                        case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
                    524:                                                                add_default_pwd_enabled(out_msg);
                    525:                                                                break;
                    526:                                                        case IETF_ATTR_INSTALLED_PACKAGES:
                    527:                                                                add_installed_packages(state, out_msg);
                    528:                                                                break;
                    529:                                                        default:
                    530:                                                                break;
                    531:                                                }
                    532:                                        }
                    533:                                        else if (entry->vendor_id == PEN_ITA)
                    534:                                        {
                    535:                                                switch (entry->type)
                    536:                                                {
                    537:                                                        case ITA_ATTR_DEVICE_ID:
                    538:                                                                add_device_id(out_msg);
                    539:                                                                break;
                    540:                                                        default:
                    541:                                                                break;
                    542:                                                }
                    543:                                        }
                    544:                                }
                    545:                                e->destroy(e);
                    546:                        }
                    547:                }
                    548:                else if (type.vendor_id == PEN_ITA && type.type == ITA_ATTR_GET_SETTINGS)
                    549:                {
                    550:                        ita_attr_get_settings_t *attr_cast;
                    551:                        enumerator_t *e;
                    552: 
                    553:                        attr_cast = (ita_attr_get_settings_t*)attr;
                    554: 
                    555:                        e = attr_cast->create_enumerator(attr_cast);
                    556:                        add_settings(e, out_msg);
                    557:                        e->destroy(e);
                    558:                }
                    559:        }
                    560:        enumerator->destroy(enumerator);
                    561: 
                    562:        if (fatal_error)
                    563:        {
                    564:                result = TNC_RESULT_FATAL;
                    565:        }
                    566:        else
                    567:        {
                    568:                /* send PA-TNC message with the EXCL flag set */
                    569:                result = out_msg->send(out_msg, TRUE);
                    570:        }
                    571:        out_msg->destroy(out_msg);
                    572: 
                    573:        return result;
                    574: }
                    575: 
                    576: /**
                    577:  * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
                    578: 
                    579:  */
                    580: TNC_Result TNC_IMC_API TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                    581:                                                                                          TNC_ConnectionID connection_id,
                    582:                                                                                          TNC_BufferReference msg,
                    583:                                                                                          TNC_UInt32 msg_len,
                    584:                                                                                          TNC_MessageType msg_type)
                    585: {
                    586:        imc_state_t *state;
                    587:        imc_msg_t *in_msg;
                    588:        TNC_Result result;
                    589: 
                    590:        if (!imc_os)
                    591:        {
                    592:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    593:                return TNC_RESULT_NOT_INITIALIZED;
                    594:        }
                    595:        if (!imc_os->get_state(imc_os, connection_id, &state))
                    596:        {
                    597:                return TNC_RESULT_FATAL;
                    598:        }
                    599:        in_msg = imc_msg_create_from_data(imc_os, state, connection_id, msg_type,
                    600:                                                                          chunk_create(msg, msg_len));
                    601:        result = receive_message(state, in_msg);
                    602:        in_msg->destroy(in_msg);
                    603: 
                    604:        return result;
                    605: }
                    606: 
                    607: /**
                    608:  * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
                    609:  */
                    610: TNC_Result TNC_IMC_API TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                    611:                                                                                                  TNC_ConnectionID connection_id,
                    612:                                                                                                  TNC_UInt32 msg_flags,
                    613:                                                                                                  TNC_BufferReference msg,
                    614:                                                                                                  TNC_UInt32 msg_len,
                    615:                                                                                                  TNC_VendorID msg_vid,
                    616:                                                                                                  TNC_MessageSubtype msg_subtype,
                    617:                                                                                                  TNC_UInt32 src_imv_id,
                    618:                                                                                                  TNC_UInt32 dst_imc_id)
                    619: {
                    620:        imc_state_t *state;
                    621:        imc_msg_t *in_msg;
                    622:        TNC_Result result;
                    623: 
                    624:        if (!imc_os)
                    625:        {
                    626:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    627:                return TNC_RESULT_NOT_INITIALIZED;
                    628:        }
                    629:        if (!imc_os->get_state(imc_os, connection_id, &state))
                    630:        {
                    631:                return TNC_RESULT_FATAL;
                    632:        }
                    633:        in_msg = imc_msg_create_from_long_data(imc_os, state, connection_id,
                    634:                                                                src_imv_id, dst_imc_id,msg_vid, msg_subtype,
                    635:                                                                chunk_create(msg, msg_len));
                    636:        result =receive_message(state, in_msg);
                    637:        in_msg->destroy(in_msg);
                    638: 
                    639:        return result;
                    640: }
                    641: 
                    642: /**
                    643:  * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
                    644:  */
                    645: TNC_Result TNC_IMC_API TNC_IMC_BatchEnding(TNC_IMCID imc_id,
                    646:                                                                                   TNC_ConnectionID connection_id)
                    647: {
                    648:        if (!imc_os)
                    649:        {
                    650:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    651:                return TNC_RESULT_NOT_INITIALIZED;
                    652:        }
                    653:        return TNC_RESULT_SUCCESS;
                    654: }
                    655: 
                    656: /**
                    657:  * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
                    658:  */
                    659: TNC_Result TNC_IMC_API TNC_IMC_Terminate(TNC_IMCID imc_id)
                    660: {
                    661:        if (!imc_os)
                    662:        {
                    663:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    664:                return TNC_RESULT_NOT_INITIALIZED;
                    665:        }
                    666:        imc_os->destroy(imc_os);
                    667:        imc_os = NULL;
                    668: 
                    669:        os->destroy(os);
                    670:        os = NULL;
                    671: 
                    672:        return TNC_RESULT_SUCCESS;
                    673: }
                    674: 
                    675: /**
                    676:  * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
                    677:  */
                    678: TNC_Result TNC_IMC_API TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
                    679:                                                                        TNC_TNCC_BindFunctionPointer bind_function)
                    680: {
                    681:        if (!imc_os)
                    682:        {
                    683:                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                    684:                return TNC_RESULT_NOT_INITIALIZED;
                    685:        }
                    686:        return imc_os->bind_functions(imc_os, bind_function);
                    687: }

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