diff options
Diffstat (limited to 'src/libimcv/plugins/imv_os/imv_os.c')
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os.c | 597 |
1 files changed, 5 insertions, 592 deletions
diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index f1cb74e50..ba0fa8153 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Andreas Steffen + * Copyright (C) 2013 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -13,599 +13,12 @@ * for more details. */ -#include "imv_os_state.h" -#include "imv_os_database.h" - -#include <imv/imv_agent.h> -#include <imv/imv_msg.h> -#include <ietf/ietf_attr.h> -#include <ietf/ietf_attr_attr_request.h> -#include <ietf/ietf_attr_default_pwd_enabled.h> -#include <ietf/ietf_attr_fwd_enabled.h> -#include <ietf/ietf_attr_installed_packages.h> -#include <ietf/ietf_attr_numeric_version.h> -#include <ietf/ietf_attr_op_status.h> -#include <ietf/ietf_attr_pa_tnc_error.h> -#include <ietf/ietf_attr_product_info.h> -#include <ietf/ietf_attr_remediation_instr.h> -#include <ietf/ietf_attr_string_version.h> -#include <ita/ita_attr.h> -#include <ita/ita_attr_get_settings.h> -#include <ita/ita_attr_settings.h> -#include <ita/ita_attr_angel.h> - -#include <tncif_names.h> -#include <tncif_pa_subtypes.h> - -#include <pen/pen.h> -#include <collections/linked_list.h> -#include <utils/debug.h> -#include <utils/lexparser.h> - -/* IMV definitions */ +#include "imv_os_agent.h" static const char imv_name[] = "OS"; +static const imv_agent_create_t imv_agent_create = imv_os_agent_create; -static pen_type_t msg_types[] = { - { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM } -}; - -static imv_agent_t *imv_os; - -/** - * IMV OS database - */ -static imv_os_database_t *os_db; - -/* - * see section 3.8.1 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id, - TNC_Version min_version, - TNC_Version max_version, - TNC_Version *actual_version) -{ - char *uri; - - if (imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name); - return TNC_RESULT_ALREADY_INITIALIZED; - } - imv_os = imv_agent_create(imv_name, msg_types, countof(msg_types), - imv_id, actual_version); - if (!imv_os) - { - return TNC_RESULT_FATAL; - } - if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1) - { - DBG1(DBG_IMV, "no common IF-IMV version"); - return TNC_RESULT_NO_COMMON_VERSION; - } - - /* attach OS database */ - uri = lib->settings->get_str(lib->settings, - "libimcv.plugins.imv-os.database", NULL); - if (uri) - { - os_db = imv_os_database_create(uri); - } - - return TNC_RESULT_SUCCESS; -} - -/** - * see section 3.8.2 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id, - TNC_ConnectionID connection_id, - TNC_ConnectionState new_state) -{ - imv_state_t *state; - - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - switch (new_state) - { - case TNC_CONNECTION_STATE_CREATE: - state = imv_os_state_create(connection_id); - return imv_os->create_state(imv_os, state); - case TNC_CONNECTION_STATE_DELETE: - return imv_os->delete_state(imv_os, connection_id); - default: - return imv_os->change_state(imv_os, connection_id, - new_state, NULL); - } -} - -static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) -{ - imv_msg_t *out_msg; - imv_os_state_t *os_state; - enumerator_t *enumerator; - pa_tnc_attr_t *attr; - pen_type_t type; - TNC_Result result; - chunk_t os_name = chunk_empty; - chunk_t os_version = chunk_empty; - bool fatal_error = FALSE, assessment = FALSE; - char non_market_apps_str[] = "install_non_market_apps"; - char android_id_str[] = "android_id"; - char machine_id_str[] = "/var/lib/dbus/machine-id"; - - os_state = (imv_os_state_t*)state; - - /* parse received PA-TNC message and handle local and remote errors */ - result = in_msg->receive(in_msg, &fatal_error); - if (result != TNC_RESULT_SUCCESS) - { - return result; - } - - out_msg = imv_msg_create_as_reply(in_msg); - - /* analyze PA-TNC attributes */ - enumerator = in_msg->create_attribute_enumerator(in_msg); - while (enumerator->enumerate(enumerator, &attr)) - { - type = attr->get_type(attr); - - if (type.vendor_id == PEN_IETF) - { - switch (type.type) - { - case IETF_ATTR_PRODUCT_INFORMATION: - { - ietf_attr_product_info_t *attr_cast; - pen_t vendor_id; - - attr_cast = (ietf_attr_product_info_t*)attr; - os_name = attr_cast->get_info(attr_cast, &vendor_id, NULL); - if (vendor_id != PEN_IETF) - { - DBG1(DBG_IMV, "operating system name is '%.*s' " - "from vendor %N", os_name.len, os_name.ptr, - pen_names, vendor_id); - } - else - { - DBG1(DBG_IMV, "operating system name is '%.*s'", - os_name.len, os_name.ptr); - } - break; - } - case IETF_ATTR_STRING_VERSION: - { - ietf_attr_string_version_t *attr_cast; - - attr_cast = (ietf_attr_string_version_t*)attr; - os_version = attr_cast->get_version(attr_cast, NULL, NULL); - if (os_version.len) - { - DBG1(DBG_IMV, "operating system version is '%.*s'", - os_version.len, os_version.ptr); - } - break; - } - case IETF_ATTR_NUMERIC_VERSION: - { - ietf_attr_numeric_version_t *attr_cast; - u_int32_t major, minor; - - attr_cast = (ietf_attr_numeric_version_t*)attr; - attr_cast->get_version(attr_cast, &major, &minor); - DBG1(DBG_IMV, "operating system numeric version is %d.%d", - major, minor); - break; - } - case IETF_ATTR_OPERATIONAL_STATUS: - { - ietf_attr_op_status_t *attr_cast; - op_status_t op_status; - op_result_t op_result; - time_t last_boot; - - attr_cast = (ietf_attr_op_status_t*)attr; - op_status = attr_cast->get_status(attr_cast); - op_result = attr_cast->get_result(attr_cast); - last_boot = attr_cast->get_last_use(attr_cast); - DBG1(DBG_IMV, "operational status: %N, result: %N", - op_status_names, op_status, op_result_names, op_result); - DBG1(DBG_IMV, "last boot: %T", &last_boot, TRUE); - break; - } - case IETF_ATTR_FORWARDING_ENABLED: - { - ietf_attr_fwd_enabled_t *attr_cast; - os_fwd_status_t fwd_status; - - attr_cast = (ietf_attr_fwd_enabled_t*)attr; - fwd_status = attr_cast->get_status(attr_cast); - DBG1(DBG_IMV, "IPv4 forwarding status: %N", - os_fwd_status_names, fwd_status); - if (fwd_status == OS_FWD_ENABLED) - { - os_state->set_os_settings(os_state, - OS_SETTINGS_FWD_ENABLED); - } - break; - } - case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED: - { - ietf_attr_default_pwd_enabled_t *attr_cast; - bool default_pwd_status; - - attr_cast = (ietf_attr_default_pwd_enabled_t*)attr; - default_pwd_status = attr_cast->get_status(attr_cast); - DBG1(DBG_IMV, "factory default password: %sabled", - default_pwd_status ? "en":"dis"); - if (default_pwd_status) - { - os_state->set_os_settings(os_state, - OS_SETTINGS_DEFAULT_PWD_ENABLED); - } - break; - } - case IETF_ATTR_INSTALLED_PACKAGES: - { - ietf_attr_installed_packages_t *attr_cast; - enumerator_t *e; - status_t status; - - /* Received at least one Installed Packages attribute */ - os_state->set_package_request(os_state, FALSE); - - if (!os_db) - { - break; - } - attr_cast = (ietf_attr_installed_packages_t*)attr; - - e = attr_cast->create_enumerator(attr_cast); - status = os_db->check_packages(os_db, os_state, e); - e->destroy(e); - - if (status == FAILED) - { - state->set_recommendation(state, - TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, - TNC_IMV_EVALUATION_RESULT_ERROR); - assessment = TRUE; - } - break; - } - default: - break; - } - } - else if (type.vendor_id == PEN_ITA) - { - switch (type.type) - { - case ITA_ATTR_SETTINGS: - { - ita_attr_settings_t *attr_cast; - enumerator_t *e; - char *name; - chunk_t value; - - attr_cast = (ita_attr_settings_t*)attr; - e = attr_cast->create_enumerator(attr_cast); - while (e->enumerate(e, &name, &value)) - { - if (streq(name, non_market_apps_str) && - chunk_equals(value, chunk_from_chars('1'))) - { - os_state->set_os_settings(os_state, - OS_SETTINGS_NON_MARKET_APPS); - } - else if ((streq(name, android_id_str) || - streq(name, machine_id_str)) && os_db) - { - os_state->set_device_id(os_state, - os_db->get_device_id(os_db, value)); - } - DBG1(DBG_IMV, "setting '%s'\n %.*s", - name, value.len, value.ptr); - } - e->destroy(e); - break; - } - case ITA_ATTR_START_ANGEL: - os_state->set_angel_count(os_state, TRUE); - break; - case ITA_ATTR_STOP_ANGEL: - os_state->set_angel_count(os_state, FALSE); - break; - default: - break; - } - } - } - enumerator->destroy(enumerator); - - if (os_name.len && os_version.len) - { - os_type_t os_type; - ita_attr_get_settings_t *attr_cast; - - /* set the OS type, name and version */ - os_type = os_type_from_name(os_name); - os_state->set_info(os_state,os_type, os_name, os_version); +/* include generic TGC TNC IF-IMV API code below */ - /* requesting installed packages */ - os_state->set_package_request(os_state, TRUE); - attr = ietf_attr_attr_request_create(PEN_IETF, - IETF_ATTR_INSTALLED_PACKAGES); - out_msg->add_attribute(out_msg, attr); +#include <imv/imv_if.h> - /* requesting Android or Linux settings */ - attr = ita_attr_get_settings_create(); - attr_cast = (ita_attr_get_settings_t*)attr; - - if (os_type == OS_TYPE_ANDROID) - { - attr_cast->add(attr_cast, android_id_str); - attr_cast->add(attr_cast, non_market_apps_str); - } - else - { - attr_cast->add(attr_cast, machine_id_str); - attr_cast->add(attr_cast, "/proc/sys/kernel/tainted"); - } - out_msg->add_attribute(out_msg, attr); - } - - if (fatal_error || - (os_state->get_attribute_request(os_state) && - os_state->get_info(os_state, NULL, NULL, NULL) == NULL)) - { - state->set_recommendation(state, - TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, - TNC_IMV_EVALUATION_RESULT_ERROR); - assessment = TRUE; - } - - /* If all Installed Packages attributes were received, go to assessment */ - if (!assessment && - !os_state->get_package_request(os_state) && - !os_state->get_angel_count(os_state) && - os_state->get_info(os_state, NULL, NULL, NULL)) - { - int device_id, count, count_update, count_blacklist, count_ok; - u_int os_settings; - u_int32_t id_type; - chunk_t id_value; - - os_settings = os_state->get_os_settings(os_state); - os_state->get_count(os_state, &count, &count_update, &count_blacklist, - &count_ok); - DBG1(DBG_IMV, "processed %d packages: %d not updated, %d blacklisted, " - "%d ok, %d not found", count, count_update, count_blacklist, - count_ok, count - count_update - count_blacklist - count_ok); - - /* Store device information in database */ - device_id = os_state->get_device_id(os_state); - id_value = state->get_ar_id(state, &id_type); - if (os_db && device_id) - { - os_db->set_device_info(os_db, device_id, id_type, id_value, - os_state->get_info(os_state, NULL, NULL, NULL), - count, count_update, count_blacklist, os_settings); - } - - if (count_update || count_blacklist || os_settings) - { - state->set_recommendation(state, - TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, - TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR); - } - else - { - state->set_recommendation(state, - TNC_IMV_ACTION_RECOMMENDATION_ALLOW, - TNC_IMV_EVALUATION_RESULT_COMPLIANT); - } - assessment = TRUE; - } - - if (assessment) - { - result = out_msg->send_assessment(out_msg); - out_msg->destroy(out_msg); - if (result != TNC_RESULT_SUCCESS) - { - return result; - } - return imv_os->provide_recommendation(imv_os, state); - } - - /* send PA-TNC message with excl flag set */ - result = out_msg->send(out_msg, TRUE); - out_msg->destroy(out_msg); - - return result; - } - -/** - * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, - TNC_ConnectionID connection_id, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_MessageType msg_type) -{ - imv_state_t *state; - imv_msg_t *in_msg; - TNC_Result result; - - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - if (!imv_os->get_state(imv_os, connection_id, &state)) - { - return TNC_RESULT_FATAL; - } - in_msg = imv_msg_create_from_data(imv_os, state, connection_id, msg_type, - chunk_create(msg, msg_len)); - result = receive_message(state, in_msg); - in_msg->destroy(in_msg); - - return result; -} - -/** - * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_ReceiveMessageLong(TNC_IMVID imv_id, - TNC_ConnectionID connection_id, - TNC_UInt32 msg_flags, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_VendorID msg_vid, - TNC_MessageSubtype msg_subtype, - TNC_UInt32 src_imc_id, - TNC_UInt32 dst_imv_id) -{ - imv_state_t *state; - imv_msg_t *in_msg; - TNC_Result result; - - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - if (!imv_os->get_state(imv_os, connection_id, &state)) - { - return TNC_RESULT_FATAL; - } - in_msg = imv_msg_create_from_long_data(imv_os, state, connection_id, - src_imc_id, dst_imv_id, msg_vid, msg_subtype, - chunk_create(msg, msg_len)); - result =receive_message(state, in_msg); - in_msg->destroy(in_msg); - - return result; -} - -/** - * see section 3.8.7 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id, - TNC_ConnectionID connection_id) -{ - imv_state_t *state; - - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - if (!imv_os->get_state(imv_os, connection_id, &state)) - { - return TNC_RESULT_FATAL; - } - return imv_os->provide_recommendation(imv_os, state); -} - -/** - * see section 3.8.8 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, - TNC_ConnectionID connection_id) -{ - imv_state_t *state; - imv_os_state_t *os_state; - TNC_IMV_Action_Recommendation rec; - TNC_IMV_Evaluation_Result eval; - TNC_Result result = TNC_RESULT_SUCCESS; - - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - if (!imv_os->get_state(imv_os, connection_id, &state)) - { - return TNC_RESULT_FATAL; - } - os_state = (imv_os_state_t*)state; - - state->get_recommendation(state, &rec, &eval); - - /* - * Don't send an attribute request if an evaluation is available - * or if an attribute request has already been sent - */ - if (eval != TNC_IMV_EVALUATION_RESULT_DONT_KNOW || - os_state->get_attribute_request(os_state)) - { - return TNC_RESULT_SUCCESS; - } - - if (os_state->get_info(os_state, NULL, NULL, NULL) == NULL) - { - imv_msg_t *out_msg; - pa_tnc_attr_t *attr; - ietf_attr_attr_request_t *attr_cast; - - out_msg = imv_msg_create(imv_os, state, connection_id, imv_id, - TNC_IMCID_ANY, msg_types[0]); - attr = ietf_attr_attr_request_create(PEN_IETF, - IETF_ATTR_PRODUCT_INFORMATION); - attr_cast = (ietf_attr_attr_request_t*)attr; - attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_STRING_VERSION); - attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_NUMERIC_VERSION); - attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_OPERATIONAL_STATUS); - attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_FORWARDING_ENABLED); - attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED); - out_msg->add_attribute(out_msg, attr); - os_state->set_attribute_request(os_state, TRUE); - - /* send PA-TNC message with excl flag not set */ - result = out_msg->send(out_msg, FALSE); - out_msg->destroy(out_msg); - } - - return result; -} - -/** - * see section 3.8.9 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id) -{ - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - DESTROY_IF(os_db); - - imv_os->destroy(imv_os); - imv_os = NULL; - - return TNC_RESULT_SUCCESS; -} - -/** - * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.3 - */ -TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id, - TNC_TNCS_BindFunctionPointer bind_function) -{ - if (!imv_os) - { - DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name); - return TNC_RESULT_NOT_INITIALIZED; - } - return imv_os->bind_functions(imv_os, bind_function); -} |