#include <generic/generic_attr_string.h>
#include <ietf/ietf_attr.h>
#include <ietf/ietf_attr_attr_request.h>
+#include "ietf/ietf_attr_fwd_enabled.h"
#include <pwg/pwg_attr.h>
#include <pwg/pwg_attr_vendor_smi_code.h>
static imc_agent_t *imc_hcd;
static imc_os_info_t *os;
+typedef struct section_subtype_t section_subtype_t;
+
+struct section_subtype_t {
+ char *section;
+ pa_subtype_pwg_t subtype;
+};
+
+static section_subtype_t section_subtypes[] = {
+ { "system", PA_SUBTYPE_PWG_HCD_SYSTEM },
+ { "console", PA_SUBTYPE_PWG_HCD_CONSOLE },
+ { "marker", PA_SUBTYPE_PWG_HCD_MARKER },
+ { "finisher", PA_SUBTYPE_PWG_HCD_FINISHER },
+ { "interface", PA_SUBTYPE_PWG_HCD_INTERFACE },
+ { "scanner" , PA_SUBTYPE_PWG_HCD_SCANNER }
+};
+
typedef struct quadruple_t quadruple_t;
struct quadruple_t {
pa_tnc_attr_t *attr;
bool status;
- status = lib->settings->get_bool(lib->settings,
- "%s.plugins.imc-hcd.subtypes.system.default_password_enabled",
- FALSE, lib->ns);
+ status = os->get_default_pwd_status(os);
DBG2(DBG_IMC, " %N: %s", pwg_attr_names, PWG_HCD_DEFAULT_PWD_ENABLED,
status ? "yes" : "no");
attr = generic_attr_bool_create(status,
static void add_forwarding_enabled(imc_msg_t *msg)
{
pa_tnc_attr_t *attr;
- bool status;
+ os_fwd_status_t fwd_status;
- status = lib->settings->get_bool(lib->settings,
- "%s.plugins.imc-hcd.subtypes.system.forwarding_enabled",
- FALSE, lib->ns);
- DBG2(DBG_IMC, " %N: %s", pwg_attr_names, PWG_HCD_FORWARDING_ENABLED,
- status ? "yes" : "no");
- attr = generic_attr_bool_create(status,
+ fwd_status = os->get_fwd_status(os);
+ DBG2(DBG_IMC, " %N: %N", pwg_attr_names, PWG_HCD_FORWARDING_ENABLED,
+ os_fwd_status_names, fwd_status);
+ attr = ietf_attr_fwd_enabled_create(fwd_status,
pen_type_create(PEN_PWG, PWG_HCD_FORWARDING_ENABLED));
msg->add_attribute(msg, attr);
}
while (enumerator->enumerate(enumerator, §ion) &&
result == TNC_RESULT_SUCCESS)
{
- if (streq(section, "system"))
- {
- subtype = PA_SUBTYPE_PWG_HCD_SYSTEM;
- }
- else if (streq(section, "console"))
- {
- subtype = PA_SUBTYPE_PWG_HCD_CONSOLE;
- }
- else if (streq(section, "marker"))
- {
- subtype = PA_SUBTYPE_PWG_HCD_MARKER;
- }
- else if (streq(section, "finisher"))
- {
- subtype = PA_SUBTYPE_PWG_HCD_FINISHER;
- }
- else if (streq(section, "interface"))
- {
- subtype = PA_SUBTYPE_PWG_HCD_INTERFACE;
- }
- else if (streq(section, "scanner"))
+ subtype = PA_SUBTYPE_PWG_HCD_UNKNOWN;
+
+ for (i = 0; i < countof(section_subtypes); i++)
{
- subtype = PA_SUBTYPE_PWG_HCD_SCANNER;
+ if (streq(section, section_subtypes[i].section))
+ {
+ subtype = section_subtypes[i].subtype;
+ break;
+ }
}
- else
+ if (subtype == PA_SUBTYPE_PWG_HCD_UNKNOWN)
{
DBG1(DBG_IMC, "HCD subtype '%s' not supported", section);
continue;
}
DBG2(DBG_IMC, "retrieving attributes for PA subtype %N/%N",
pen_names, PEN_PWG, pa_subtype_pwg_names, subtype);
+
msg_type = pen_type_create(PEN_PWG, subtype);
out_msg = imc_msg_create(imc_hcd, state, connection_id, imc_id,
TNC_IMVID_ANY, msg_type);
imc_msg_t *out_msg;
enumerator_t *enumerator;
pa_tnc_attr_t *attr;
- pen_type_t type;
+ pen_type_t type, msg_type;
TNC_Result result;
+ char *section = NULL;
+ int i;
bool fatal_error = FALSE, pushed_info;
/* generate an outgoing PA-TNC message - we might need it */
out_msg->destroy(out_msg);
return result;
}
+ msg_type = in_msg->get_msg_type(in_msg);
+
+ for (i = 0; i < countof(section_subtypes); i++)
+ {
+ if (msg_type.type == section_subtypes[i].subtype)
+ {
+ section = section_subtypes[i].section;
+ break;
+ }
+ }
pushed_info = lib->settings->get_bool(lib->settings,
"%s.plugins.imc-hcd.push_info", FALSE, lib->ns);
switch (entry->type)
{
case PWG_HCD_ATTRS_NATURAL_LANG:
- add_attrs_natural_lang(out_msg, "system");
+ add_attrs_natural_lang(out_msg, section);
break;
case PWG_HCD_DEFAULT_PWD_ENABLED:
add_default_pwd_enabled(out_msg);
switch (entry->type)
{
case PWG_HCD_FIRMWARE_NAME:
- add_quadruple(out_msg, "system", &quadruples[0]);
+ add_quadruple(out_msg, section, &quadruples[0]);
break;
case PWG_HCD_RESIDENT_APP_NAME:
- add_quadruple(out_msg, "system", &quadruples[1]);
+ add_quadruple(out_msg, section, &quadruples[1]);
break;
case PWG_HCD_USER_APP_NAME:
- add_quadruple(out_msg, "system", &quadruples[2]);
+ add_quadruple(out_msg, section, &quadruples[2]);
break;
default:
break;
#include <generic/generic_attr_string.h>
#include <ietf/ietf_attr.h>
#include <ietf/ietf_attr_attr_request.h>
+#include <ietf/ietf_attr_fwd_enabled.h>
#include <pwg/pwg_attr.h>
#include <pwg/pwg_attr_vendor_smi_code.h>
#include "tcg/seg/tcg_seg_attr_max_size.h"
#define HCD_MAX_ATTR_SIZE 10000000
typedef struct private_imv_hcd_agent_t private_imv_hcd_agent_t;
-typedef enum imv_hcd_attr_t imv_hcd_attr_t;
/* Subscribed PA-TNC message subtypes */
static pen_type_t msg_types[] = {
{ PEN_PWG, PA_SUBTYPE_PWG_HCD_SCANNER }
};
-/**
- * Flag set when corresponding attribute has been received
- */
-enum imv_hcd_attr_t {
- IMV_HCD_ATTR_NONE = 0,
- IMV_HCD_ATTR_NATURAL_LANG = (1<<0),
- IMV_HCD_ATTR_DEFAULT_PWD_ENABLED = (1<<1),
- IMV_HCD_ATTR_FIREWALL_SETTING = (1<<2),
- IMV_HCD_ATTR_FIRMWARE_NAME = (1<<3),
- IMV_HCD_ATTR_FORWARDING_ENABLED = (1<<4),
- IMV_HCD_ATTR_MACHINE_TYPE_MODEL = (1<<5),
- IMV_HCD_ATTR_PSTN_FAX_ENABLED = (1<<6),
- IMV_HCD_ATTR_RESIDENT_APP_NAME = (1<<7),
- IMV_HCD_ATTR_TIME_SOURCE = (1<<8),
- IMV_HCD_ATTR_USER_APP_ENABLED = (1<<9),
- IMV_HCD_ATTR_USER_APP_PERSIST_ENABLED = (1<<10),
- IMV_HCD_ATTR_USER_APP_NAME = (1<<11),
- IMV_HCD_ATTR_VENDOR_NAME = (1<<12),
- IMV_HCD_ATTR_VENDOR_SMI_CODE = (1<<13),
- IMV_HCD_ATTR_MUST = (1<<14)-1
-};
-
static imv_hcd_attr_t attr_type_to_flag(pwg_attr_t attr_type)
{
switch (attr_type)
{
- case PWG_HCD_ATTRS_NATURAL_LANG:
- return IMV_HCD_ATTR_NATURAL_LANG;
case PWG_HCD_DEFAULT_PWD_ENABLED:
return IMV_HCD_ATTR_DEFAULT_PWD_ENABLED;
case PWG_HCD_FIREWALL_SETTING:
return IMV_HCD_ATTR_FIREWALL_SETTING;
- case PWG_HCD_FIRMWARE_NAME:
- return IMV_HCD_ATTR_FIRMWARE_NAME;
case PWG_HCD_FORWARDING_ENABLED:
return IMV_HCD_ATTR_FORWARDING_ENABLED;
case PWG_HCD_MACHINE_TYPE_MODEL:
return IMV_HCD_ATTR_MACHINE_TYPE_MODEL;
case PWG_HCD_PSTN_FAX_ENABLED:
return IMV_HCD_ATTR_PSTN_FAX_ENABLED;
- case PWG_HCD_RESIDENT_APP_NAME:
- return IMV_HCD_ATTR_RESIDENT_APP_NAME;
case PWG_HCD_TIME_SOURCE:
return IMV_HCD_ATTR_TIME_SOURCE;
case PWG_HCD_USER_APP_ENABLED:
return IMV_HCD_ATTR_USER_APP_ENABLED;
case PWG_HCD_USER_APP_PERSIST_ENABLED:
return IMV_HCD_ATTR_USER_APP_PERSIST_ENABLED;
- case PWG_HCD_USER_APP_NAME:
- return IMV_HCD_ATTR_USER_APP_NAME;
case PWG_HCD_VENDOR_NAME:
return IMV_HCD_ATTR_VENDOR_NAME;
case PWG_HCD_VENDOR_SMI_CODE:
return IMV_HCD_ATTR_VENDOR_SMI_CODE;
+ case PWG_HCD_CERTIFICATION_STATE:
+ return IMV_HCD_ATTR_CERTIFICATION_STATE;
+ case PWG_HCD_CONFIGURATION_STATE:
+ return IMV_HCD_ATTR_CONFIGURATION_STATE;
+ case PWG_HCD_ATTRS_NATURAL_LANG:
+ return IMV_HCD_ATTR_NATURAL_LANG;
+ case PWG_HCD_FIRMWARE_NAME:
+ return IMV_HCD_ATTR_FIRMWARE_NAME;
+ case PWG_HCD_RESIDENT_APP_NAME:
+ return IMV_HCD_ATTR_RESIDENT_APP_NAME;
+ case PWG_HCD_USER_APP_NAME:
+ return IMV_HCD_ATTR_USER_APP_NAME;
default:
return IMV_HCD_ATTR_NONE;
}
imv_msg_t *out_msg;
imv_hcd_state_t *hcd_state;
pa_tnc_attr_t *attr;
- pen_type_t type;
+ enum_name_t *pa_subtype_names;
+ pen_type_t type, msg_type;
TNC_Result result;
bool fatal_error = FALSE, assessment = FALSE;
enumerator_t *enumerator;
out_msg->destroy(out_msg);
return result;
}
+ msg_type = in_msg->get_msg_type(in_msg);
+ pa_subtype_names = get_pa_subtype_names(msg_type.vendor_id);
+ DBG2(DBG_IMV, "received attributes for PA subtype %N/%N",
+ pen_names, msg_type.vendor_id, pa_subtype_names, msg_type.type);
+
+ /* set current subtype */
+ if (msg_type.vendor_id == PEN_IETF)
+ {
+ hcd_state->set_subtype(hcd_state, PA_SUBTYPE_PWG_HCD_SYSTEM);
+ }
+ else
+ {
+ hcd_state->set_subtype(hcd_state, msg_type.type);
+ }
/* analyze PA-TNC attributes */
enumerator = in_msg->create_attribute_enumerator(in_msg);
{
type = attr->get_type(attr);
- if (type.vendor_id == PEN_PWG)
+ if (type.vendor_id == PEN_IETF)
+ {
+ switch (type.type)
+ {
+ 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);
+ DBG2(DBG_IMV, " %N: %N", ietf_attr_names, type.type,
+ os_fwd_status_names, fwd_status);
+ state->set_action_flags(state,
+ IMV_HCD_ATTR_FORWARDING_ENABLED);
+ break;
+ }
+ case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
+ {
+ generic_attr_bool_t *attr_cast;
+ bool status;
+
+ attr_cast = (generic_attr_bool_t*)attr;
+ status = attr_cast->get_status(attr_cast);
+ DBG2(DBG_IMV, " %N: %s", ietf_attr_names, type.type,
+ status ? "yes" : "no");
+ state->set_action_flags(state,
+ IMV_HCD_ATTR_DEFAULT_PWD_ENABLED);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if (type.vendor_id == PEN_PWG)
{
state->set_action_flags(state, attr_type_to_flag(type.type));
chunk_t value;
value = attr->get_value(attr);
- DBG2(DBG_IMV, "%N: %.*s", pwg_attr_names, type.type,
+ DBG2(DBG_IMV, " %N: %.*s", pwg_attr_names, type.type,
value.len, value.ptr);
break;
}
chunk_t value;
value = attr->get_value(attr);
- DBG2(DBG_IMV, "%N: %#B", pwg_attr_names, type.type, &value);
+ DBG2(DBG_IMV, " %N: %#B", pwg_attr_names, type.type, &value);
break;
}
case PWG_HCD_CERTIFICATION_STATE:
chunk_t value;
value = attr->get_value(attr);
- DBG2(DBG_IMV, "%N: %B", pwg_attr_names, type.type, &value);
+ DBG2(DBG_IMV, " %N: %B", pwg_attr_names, type.type, &value);
break;
}
case PWG_HCD_DEFAULT_PWD_ENABLED:
- case PWG_HCD_FORWARDING_ENABLED:
case PWG_HCD_PSTN_FAX_ENABLED:
case PWG_HCD_USER_APP_ENABLED:
case PWG_HCD_USER_APP_PERSIST_ENABLED:
attr_cast = (generic_attr_bool_t*)attr;
status = attr_cast->get_status(attr_cast);
- DBG2(DBG_IMV, "%N: %s", pwg_attr_names, type.type,
+ DBG2(DBG_IMV, " %N: %s", pwg_attr_names, type.type,
status ? "yes" : "no");
if (type.type == PWG_HCD_USER_APP_ENABLED && !status)
{
/* do not request user applications */
- state->set_action_flags(state,
- IMV_HCD_ATTR_USER_APP_NAME);
+ hcd_state->set_user_app_disabled(hcd_state);
}
break;
}
+ case PWG_HCD_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);
+ DBG2(DBG_IMV, " %N: %N", pwg_attr_names, type.type,
+ os_fwd_status_names, fwd_status);
+ break;
+ }
+
case PWG_HCD_VENDOR_SMI_CODE:
{
pwg_attr_vendor_smi_code_t *attr_cast;
attr_cast = (pwg_attr_vendor_smi_code_t*)attr;
smi_code = attr_cast->get_vendor_smi_code(attr_cast);
- DBG2(DBG_IMV, "%N: 0x%06x (%u)", pwg_attr_names, type.type,
+ DBG2(DBG_IMV, " %N: 0x%06x (%u)", pwg_attr_names, type.type,
smi_code, smi_code);
break;
}
{
attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_VENDOR_SMI_CODE);
}
- attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CERTIFICATION_STATE);
- attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CONFIGURATION_STATE);
-
+ if (!(received & IMV_HCD_ATTR_CERTIFICATION_STATE))
+ {
+ attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CERTIFICATION_STATE);
+ }
+ if (!(received & IMV_HCD_ATTR_CONFIGURATION_STATE))
+ {
+ attr_cast->add(attr_cast, PEN_PWG, PWG_HCD_CONFIGURATION_STATE);
+ }
return attr;
}
pa_tnc_attr_t *attr;
TNC_IMVID imv_id;
TNC_Result result = TNC_RESULT_SUCCESS;
- uint32_t received;
if (!this->agent->get_state(this->agent, id, &state))
{
}
hcd_state = (imv_hcd_state_t*)state;
handshake_state = hcd_state->get_handshake_state(hcd_state);
- received = state->get_action_flags(state);
imv_id = this->agent->get_id(this->agent);
if (handshake_state == IMV_HCD_STATE_END)
return TNC_RESULT_SUCCESS;
}
- /* create an empty out message - we might need it */
- out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
- msg_types[0]);
-
if (handshake_state == IMV_HCD_STATE_INIT)
{
size_t max_attr_size = HCD_MAX_ATTR_SIZE;
seg_contract_t *contract;
seg_contract_manager_t *contracts;
char buf[BUF_LEN];
+ uint32_t received;
+ int i;
/* Determine maximum PA-TNC attribute segment size */
max_seg_size = state->get_max_msg_len(state)
- TCG_SEG_ATTR_SEG_ENV_HEADER
- PA_TNC_ATTR_HEADER_SIZE
- TCG_SEG_ATTR_MAX_SIZE_SIZE;
-
- /* Announce support of PA-TNC segmentation to IMC */
- contract = seg_contract_create(msg_types[0], max_attr_size,
- max_seg_size, TRUE, imv_id, FALSE);
- contract->get_info_string(contract, buf, BUF_LEN, TRUE);
- DBG2(DBG_IMV, "%s", buf);
contracts = state->get_contracts(state);
- contracts->add_contract(contracts, contract);
- attr = tcg_seg_attr_max_size_create(max_attr_size, max_seg_size, TRUE);
- out_msg->add_attribute(out_msg, attr);
- if ((received & IMV_HCD_ATTR_MUST) != IMV_HCD_ATTR_MUST)
+ for (i = 1; i < countof(msg_types); i++)
{
- /* create attribute request for missing mandatory attributes */
- out_msg->add_attribute(out_msg, build_attr_request(received));
+ out_msg = imv_msg_create(this->agent, state, id, imv_id,
+ TNC_IMCID_ANY, msg_types[i]);
+
+ /* Announce support of PA-TNC segmentation to IMC */
+ contract = seg_contract_create(msg_types[i], max_attr_size,
+ max_seg_size, TRUE, imv_id, FALSE);
+ contract->get_info_string(contract, buf, BUF_LEN, TRUE);
+ DBG2(DBG_IMV, "%s", buf);
+ contracts->add_contract(contracts, contract);
+ attr = tcg_seg_attr_max_size_create(max_attr_size, max_seg_size,
+ TRUE);
+ out_msg->add_attribute(out_msg, attr);
+
+ hcd_state->set_subtype(hcd_state, msg_types[i].type);
+ received = state->get_action_flags(state);
+
+ if ((received & IMV_HCD_ATTR_MUST) != IMV_HCD_ATTR_MUST)
+ {
+ /* create attribute request for missing mandatory attributes */
+ out_msg->add_attribute(out_msg, build_attr_request(received));
+ }
+ result = out_msg->send(out_msg, FALSE);
+ out_msg->destroy(out_msg);
+
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ break;
+ }
}
hcd_state->set_handshake_state(hcd_state, IMV_HCD_STATE_ATTR_REQ);
}
- /* send non-empty PA-TNC message with excl flag not set */
- if (out_msg->get_attribute_count(out_msg))
- {
- result = out_msg->send(out_msg, FALSE);
- }
- out_msg->destroy(out_msg);
-
return result;
}
#include <utils/debug.h>
typedef struct private_imv_hcd_state_t private_imv_hcd_state_t;
+typedef struct subtype_action_flags_t subtype_action_flags_t;
+
+struct subtype_action_flags_t {
+ pa_subtype_pwg_t subtype;
+ uint32_t action_flags;
+};
/**
* Private data of an imv_hcd_state_t object.
uint32_t max_msg_len;
/**
- * Flags set for completed actions
+ * Current flags set for completed actions
*/
- uint32_t action_flags;
+ uint32_t *action_flags;
+
+ /**
+ * Action flags for all PA subtypes
+ */
+ subtype_action_flags_t subtype_action_flags[6];
/**
* IMV database session associated with TNCCS connection
METHOD(imv_state_t, set_action_flags, void,
private_imv_hcd_state_t *this, uint32_t flags)
{
- this->action_flags |= flags;
+ *this->action_flags |= flags;
}
METHOD(imv_state_t, get_action_flags, uint32_t,
private_imv_hcd_state_t *this)
{
- return this->action_flags;
+ return *this->action_flags;
}
METHOD(imv_state_t, set_session, void,
return this->handshake_state;
}
+METHOD(imv_hcd_state_t, set_subtype, void,
+ private_imv_hcd_state_t *this, pa_subtype_pwg_t subtype)
+{
+ int i;
+
+ for (i = 0; i < countof(this->subtype_action_flags); i++)
+ {
+ if (subtype == this->subtype_action_flags[i].subtype)
+ {
+ this->action_flags = &this->subtype_action_flags[i].action_flags;
+ break;
+ }
+ }
+}
+
+METHOD(imv_hcd_state_t, set_user_app_disabled, void,
+ private_imv_hcd_state_t *this)
+{
+ int i;
+
+ for (i = 0; i < countof(this->subtype_action_flags); i++)
+ {
+ this->subtype_action_flags[i].action_flags |= IMV_HCD_ATTR_USER_APP_NAME;
+ }
+}
+
/**
* Described in header.
*/
},
.set_handshake_state = _set_handshake_state,
.get_handshake_state = _get_handshake_state,
+ .set_subtype = _set_subtype,
+ .set_user_app_disabled = _set_user_app_disabled,
},
.state = TNC_CONNECTION_STATE_CREATE,
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
.connection_id = connection_id,
.contracts = seg_contract_manager_create(),
+ .subtype_action_flags = {
+ { PA_SUBTYPE_PWG_HCD_SYSTEM, IMV_HCD_ATTR_NONE },
+ { PA_SUBTYPE_PWG_HCD_CONSOLE, IMV_HCD_ATTR_SYSTEM_ONLY },
+ { PA_SUBTYPE_PWG_HCD_MARKER, IMV_HCD_ATTR_SYSTEM_ONLY },
+ { PA_SUBTYPE_PWG_HCD_FINISHER, IMV_HCD_ATTR_SYSTEM_ONLY },
+ { PA_SUBTYPE_PWG_HCD_INTERFACE, IMV_HCD_ATTR_SYSTEM_ONLY },
+ { PA_SUBTYPE_PWG_HCD_SCANNER, IMV_HCD_ATTR_SYSTEM_ONLY },
+ }
);
+ this->action_flags = &this->subtype_action_flags[0].action_flags;
+
return &this->public.interface;
}