diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index d99ac1518..79fc21177 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -12,6 +12,7 @@ libimcv_la_SOURCES = \ ietf/ietf_attr.h ietf/ietf_attr.c \ ietf/ietf_attr_assess_result.h ietf/ietf_attr_assess_result.c \ ietf/ietf_attr_attr_request.h ietf/ietf_attr_attr_request.c \ + ietf/ietf_attr_fwd_enabled.h ietf/ietf_attr_fwd_enabled.c \ ietf/ietf_attr_installed_packages.h ietf/ietf_attr_installed_packages.c \ ietf/ietf_attr_pa_tnc_error.h ietf/ietf_attr_pa_tnc_error.c \ ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \ diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c index 02eb76073..19eac6f46 100644 --- a/src/libimcv/ietf/ietf_attr.c +++ b/src/libimcv/ietf/ietf_attr.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-2012 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -15,6 +16,7 @@ #include "ietf_attr.h" #include "ietf/ietf_attr_assess_result.h" #include "ietf/ietf_attr_attr_request.h" +#include "ietf/ietf_attr_fwd_enabled.h" #include "ietf/ietf_attr_installed_packages.h" #include "ietf/ietf_attr_pa_tnc_error.h" #include "ietf/ietf_attr_port_filter.h" @@ -59,11 +61,12 @@ pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value) return ietf_attr_pa_tnc_error_create_from_data(value); case IETF_ATTR_ASSESSMENT_RESULT: return ietf_attr_assess_result_create_from_data(value); + case IETF_ATTR_FORWARDING_ENABLED: + return ietf_attr_fwd_enabled_create_from_data(value); case IETF_ATTR_TESTING: case IETF_ATTR_NUMERIC_VERSION: case IETF_ATTR_OPERATIONAL_STATUS: case IETF_ATTR_REMEDIATION_INSTRUCTIONS: - case IETF_ATTR_FORWARDING_ENABLED: case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED: case IETF_ATTR_RESERVED: default: diff --git a/src/libimcv/ietf/ietf_attr_fwd_enabled.c b/src/libimcv/ietf/ietf_attr_fwd_enabled.c new file mode 100644 index 000000000..c7deea07c --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "ietf_attr_fwd_enabled.h" + +#include +#include +#include +#include + +typedef struct private_ietf_attr_fwd_enabled_t private_ietf_attr_fwd_enabled_t; + +/** + * PA-TNC Forwarding Enabled type (see section 4.2.11 of RFC 5792) + * + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Forwarding Enabled | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define FORWARDING_ENABLED_SIZE 4 + +/** + * Private data of an ietf_attr_fwd_enabled_t object. + */ +struct private_ietf_attr_fwd_enabled_t { + + /** + * Public members of ietf_attr_fwd_enabled_t + */ + ietf_attr_fwd_enabled_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Forwarding Enabled status + */ + os_fwd_status_t fwd_status; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_fwd_enabled_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_fwd_enabled_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(FORWARDING_ENABLED_SIZE); + writer->write_uint32(writer, this->fwd_status); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_fwd_enabled_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t fwd_status; + + *offset = 0; + + if (this->value.len != FORWARDING_ENABLED_SIZE) + { + DBG1(DBG_TNC, "incorrect size for IETF forwarding enabled attribute"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32(reader, &fwd_status); + reader->destroy(reader); + + if (fwd_status > OS_FWD_UNKNOWN) + { + DBG1(DBG_TNC, "IETF forwarding enabled field has unknown value %u", + fwd_status); + return FAILED; + } + this->fwd_status = fwd_status; + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_fwd_enabled_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_fwd_enabled_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_fwd_enabled_t, get_status, os_fwd_status_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->fwd_status; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status) +{ + private_ietf_attr_fwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FORWARDING_ENABLED }, + .fwd_status = fwd_status, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_fwd_enabled_create_from_data(chunk_t data) +{ + private_ietf_attr_fwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FORWARDING_ENABLED }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_fwd_enabled.h b/src/libimcv/ietf/ietf_attr_fwd_enabled.h new file mode 100644 index 000000000..1701d75c0 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup ietf_attr_fwd_enabled ietf_attr_fwd_enabled + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_FWD_ENABLED_H_ +#define IETF_ATTR_FWD_ENABLED_H_ + +typedef struct ietf_attr_fwd_enabled_t ietf_attr_fwd_enabled_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "os_info/os_info.h" + +/** + * Class implementing the IETF PA-TNC Product Information attribute. + * + */ +struct ietf_attr_fwd_enabled_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Forwarding Enabled status + * + * @return Forwarding Enabled status + */ + os_fwd_status_t (*get_status)(ietf_attr_fwd_enabled_t *this); + +}; + +/** + * Creates an ietf_attr_fwd_enabled_t object + * + * @param fwd_status Forwarding Enabled status + */ +pa_tnc_attr_t* ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status); + +/** + * Creates an ietf_attr_fwd_enabled_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_fwd_enabled_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_FWD_ENABLED_H_ @}*/ diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c index 4dbcee55f..25d64676e 100644 --- a/src/libimcv/os_info/os_info.c +++ b/src/libimcv/os_info/os_info.c @@ -16,13 +16,18 @@ #include "os_info.h" #include +#include #include #include - typedef struct private_os_info_t private_os_info_t; +ENUM(os_fwd_status_names, OS_FWD_DISABLED, OS_FWD_UNKNOWN, + "disabled", + "enabled", + "unknown" +); /** * Private data of an os_info_t object. @@ -59,6 +64,47 @@ METHOD(os_info_t, get_version, chunk_t, return this->version; } +METHOD(os_info_t, get_fwd_status, os_fwd_status_t, + private_os_info_t *this) +{ + const char ip_forward[] = "/proc/sys/net/ipv4/ip_forward"; + char buf[2]; + FILE *file; + + os_fwd_status_t fwd_status = OS_FWD_UNKNOWN; + + file = fopen(ip_forward, "r"); + if (file) + { + if (fread(buf, 1, 1, file) == 1) + { + switch (buf[0]) + { + case '0': + fwd_status = OS_FWD_DISABLED; + break; + case '1': + fwd_status = OS_FWD_ENABLED; + break; + default: + DBG1(DBG_IMC, "\"%s\" returns invalid value ", ip_forward); + break; + } + } + else + { + DBG1(DBG_IMC, "could not read from \"%s\"", ip_forward); + } + } + else + { + DBG1(DBG_IMC, "failed to open \"%s\"", ip_forward); + } + fclose(file); + + return fwd_status; +} + METHOD(os_info_t, create_package_enumerator, enumerator_t*, private_os_info_t *this) { @@ -298,6 +344,7 @@ os_info_t *os_info_create(void) .public = { .get_name = _get_name, .get_version = _get_version, + .get_fwd_status = _get_fwd_status, .create_package_enumerator = _create_package_enumerator, .destroy = _destroy, }, diff --git a/src/libimcv/os_info/os_info.h b/src/libimcv/os_info/os_info.h index 78d0509f4..104426397 100644 --- a/src/libimcv/os_info/os_info.h +++ b/src/libimcv/os_info/os_info.h @@ -22,9 +22,21 @@ #define OS_INFO_H_ typedef struct os_info_t os_info_t; +typedef enum os_fwd_status_t os_fwd_status_t; #include +/** + * Defines the IPv4 forwarding status + */ +enum os_fwd_status_t { + OS_FWD_DISABLED = 0, + OS_FWD_ENABLED = 1, + OS_FWD_UNKNOWN = 2 +}; + +extern enum_name_t *os_fwd_status_names; + /** * Interface for the Operating System (OS) information module */ @@ -44,6 +56,13 @@ struct os_info_t { */ chunk_t (*get_version)(os_info_t *this); + /** + * Get the OS IPv4 forwarding status + * + * @return IP forwarding status + */ + os_fwd_status_t (*get_fwd_status)(os_info_t *this); + /** * Enumerates over all installed packages * diff --git a/src/libimcv/plugins/imc_os/imc_os.c b/src/libimcv/plugins/imc_os/imc_os.c index a397dfa5f..771605ac5 100644 --- a/src/libimcv/plugins/imc_os/imc_os.c +++ b/src/libimcv/plugins/imc_os/imc_os.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,8 +32,6 @@ #include #include -#include - /* IMC definitions */ static const char imc_name[] = "OS"; @@ -139,6 +138,21 @@ static void add_string_version(linked_list_t *attr_list) attr_list->insert_last(attr_list, attr); } +/** + * Add IETF Forwarding Enabled attribute to the send queue + */ +static void add_fwd_enabled(linked_list_t *attr_list) +{ + pa_tnc_attr_t *attr; + os_fwd_status_t fwd_status; + + fwd_status = os->get_fwd_status(os); + DBG1(DBG_IMC, "IPv4 forwarding status: %N", + os_fwd_status_names, fwd_status); + attr = ietf_attr_fwd_enabled_create(fwd_status); + attr_list->insert_last(attr_list, attr); +} + /** * Add an IETF Installed Packages attribute to the send queue */ @@ -180,6 +194,7 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id, attr_list = linked_list_create(); add_product_info(attr_list); add_string_version(attr_list); + add_fwd_enabled(attr_list); result = imc_os->send_message(imc_os, connection_id, FALSE, 0, TNC_IMVID_ANY, attr_list); attr_list->destroy(attr_list); @@ -267,6 +282,9 @@ static TNC_Result receive_message(TNC_IMCID imc_id, case IETF_ATTR_STRING_VERSION: add_string_version(attr_list); break; + case IETF_ATTR_FORWARDING_ENABLED: + add_fwd_enabled(attr_list); + break; case IETF_ATTR_INSTALLED_PACKAGES: add_installed_packages(attr_list); break; diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index 52dcff024..3d2c00df3 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -19,10 +19,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -178,6 +180,17 @@ static TNC_Result receive_message(TNC_IMVID imv_id, } 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); + break; + } case IETF_ATTR_INSTALLED_PACKAGES: { ietf_attr_installed_packages_t *attr_cast; @@ -339,6 +352,7 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, 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_FORWARDING_ENABLED); attr_list->insert_last(attr_list, attr); result = imv_os->send_message(imv_os, connection_id, FALSE, imv_id, TNC_IMCID_ANY, attr_list);