diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index 7cec116d5..65438fc97 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -585,8 +585,8 @@ static bool language_enumerator_enumerate(language_enumerator_t *this, ...) } else { - pos = this->lang_pos + len; len = this->lang_len; + pos = this->lang_pos + len; this->lang_pos = NULL; this->lang_len = 0; } @@ -619,18 +619,17 @@ METHOD(imv_agent_t, create_language_enumerator, enumerator_t*, /* Create a language enumerator instance */ e = malloc_thing(language_enumerator_t); + e->public.enumerate = (void*)language_enumerator_enumerate; + e->public.destroy = (void*)language_enumerator_destroy; - if (!this->get_attribute || + if (!this->get_attribute || !this->get_attribute(this->id, state->get_connection_id(state), TNC_ATTRIBUTEID_PREFERRED_LANGUAGE, BUF_LEN, e->lang_buf, &e->lang_len) == TNC_RESULT_SUCCESS || e->lang_len >= BUF_LEN) { - free(e); - return NULL; + e->lang_len = 0; } - e->public.enumerate = (void*)language_enumerator_enumerate; - e->public.destroy = (void*)language_enumerator_destroy; e->lang_buf[e->lang_len] = '\0'; e->lang_pos = e->lang_buf; diff --git a/src/libimcv/imv/imv_msg.c b/src/libimcv/imv/imv_msg.c index 2c23cadd1..d7fd4362d 100644 --- a/src/libimcv/imv/imv_msg.c +++ b/src/libimcv/imv/imv_msg.c @@ -17,6 +17,7 @@ #include "ietf/ietf_attr.h" #include "ietf/ietf_attr_assess_result.h" +#include "ietf/ietf_attr_remediation_instr.h" #include @@ -190,6 +191,8 @@ METHOD(imv_msg_t, send_assessment, TNC_Result, TNC_IMV_Action_Recommendation rec; TNC_IMV_Evaluation_Result eval; pa_tnc_attr_t *attr; + char *string, *lang_code; + enumerator_t *e; /* Send an IETF Assessment Result attribute if enabled */ if (lib->settings->get_bool(lib->settings, "libimcv.assessment_result", @@ -199,6 +202,21 @@ METHOD(imv_msg_t, send_assessment, TNC_Result, attr = ietf_attr_assess_result_create(eval); add_attribute(this, attr); + if (eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT) + { + e = this->agent->create_language_enumerator(this->agent, + this->state); + if (this->state->get_remediation_instructions(this->state, + e, &string, &lang_code)) + { + attr = ietf_attr_remediation_instr_create_from_string( + chunk_create(string, strlen(string)), + chunk_create(lang_code, strlen(lang_code))); + add_attribute(this, attr); + } + e->destroy(e); + } + /* send PA-TNC message with the excl flag set */ return send_(this, TRUE); } diff --git a/src/libimcv/imv/imv_state.h b/src/libimcv/imv/imv_state.h index 2fd5959b4..a81fdfa34 100644 --- a/src/libimcv/imv/imv_state.h +++ b/src/libimcv/imv/imv_state.h @@ -111,12 +111,24 @@ struct imv_state_t { * * @param language_enumerator language enumerator * @param reason_string reason string - * @param language code language of the returned reason string + * @param reason_language language of the returned reason string * @return TRUE if a reason string was found */ bool (*get_reason_string)(imv_state_t *this, enumerator_t *language_enumerator, - char **reason_string, char **language_code); + char **reason_string, char **reason_language); + + /** + * Get remediation instructions based on the preferred language + * + * @param language_enumerator language enumerator + * @param string remediation instruction string + * @param lang_code language of the remediation instructions + * @return TRUE if remediation instructions were found + */ + bool (*get_remediation_instructions)(imv_state_t *this, + enumerator_t *language_enumerator, + char **string, char **lang_code); /** * Destroys an imv_state_t object diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner.c b/src/libimcv/plugins/imc_scanner/imc_scanner.c index f233f22b0..36ff2dd44 100644 --- a/src/libimcv/plugins/imc_scanner/imc_scanner.c +++ b/src/libimcv/plugins/imc_scanner/imc_scanner.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -339,6 +340,39 @@ static TNC_Result receive_message(imc_msg_t *in_msg) } e->destroy(e); } + else if (attr_type.type == IETF_ATTR_REMEDIATION_INSTRUCTIONS) + { + ietf_attr_remediation_instr_t *attr_cast; + pen_type_t parameters_type; + chunk_t parameters, string, lang_code; + + attr_cast = (ietf_attr_remediation_instr_t*)attr; + parameters_type = attr_cast->get_parameters_type(attr_cast); + parameters = attr_cast->get_parameters(attr_cast); + + if (parameters_type.vendor_id == PEN_IETF) + { + switch (parameters_type.type) + { + case IETF_REMEDIATION_PARAMETERS_URI: + DBG1(DBG_IMC, "remediation uri: '%.*s'", + parameters.len, parameters.ptr); + break; + case IETF_REMEDIATION_PARAMETERS_STRING: + string = attr_cast->get_string(attr_cast, &lang_code); + DBG1(DBG_IMC, "remediation string: '%.*s' [%.*s]", + string.len, string.ptr, + lang_code.len, lang_code.ptr); + break; + default: + DBG1(DBG_IMC, "remediation parameters %B", ¶meters); + } + } + else + { + DBG1(DBG_IMC, "remediation parameters %B", ¶meters); + } + } } enumerator->destroy(enumerator); diff --git a/src/libimcv/plugins/imv_os/imv_os_state.c b/src/libimcv/plugins/imv_os/imv_os_state.c index 4981024e5..fec49fe8d 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.c +++ b/src/libimcv/plugins/imv_os/imv_os_state.c @@ -197,6 +197,13 @@ METHOD(imv_state_t, get_reason_string, bool, return FALSE; } +METHOD(imv_state_t, get_remediation_instructions, bool, + private_imv_os_state_t *this, enumerator_t *language_enumerator, + char **string, char **lang_code) +{ + return FALSE; +} + METHOD(imv_state_t, destroy, void, private_imv_os_state_t *this) { @@ -309,6 +316,7 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id) .get_recommendation = _get_recommendation, .set_recommendation = _set_recommendation, .get_reason_string = _get_reason_string, + .get_remediation_instructions = _get_remediation_instructions, .destroy = _destroy, }, .set_info = _set_info, diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c index 362fb6e66..44f07533b 100644 --- a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c +++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c @@ -71,9 +71,9 @@ struct private_imv_scanner_state_t { char *violating_ports; /** - * Local copy of the reason string + * Local copy of the remediation instruction string */ - char *reason_string; + char *instructions; }; typedef struct entry_t entry_t; @@ -90,10 +90,20 @@ struct entry_t { * Table of multi-lingual reason string entries */ static entry_t reasons[] = { - { "en", "The following ports are open:" }, - { "de", "Die folgenden Ports sind offen:" }, - { "fr", "Les ports suivants sont ouverts:" }, - { "pl", "Następujące porty sa otwarte:" } + { "en", "Open server ports were detected" }, + { "de", "Offene Serverports wurden festgestellt" }, + { "fr", "Il y a des ports du serveur ouverts" }, + { "pl", "Są otwarte porty serwera" } +}; + +/** + * Table of multi-lingual remediation instruction string entries + */ +static entry_t instructions [] = { + { "en", "Please close the following server ports:" }, + { "de", "Bitte schliessen Sie die folgenden Serverports:" }, + { "fr", "Fermez les ports du serveur suivants s'il vous plait:" }, + { "pl", "Proszę zamknąć następujące porty serwera:" } }; METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, @@ -167,6 +177,7 @@ METHOD(imv_state_t, get_reason_string, bool, { return FALSE; } + /* set the default language */ *reason_language = reasons[0].lang; *reason_string = reasons[0].string; @@ -188,10 +199,48 @@ METHOD(imv_state_t, get_reason_string, bool, break; } } - this->reason_string = malloc(strlen(*reason_string) + - strlen(this->violating_ports + 1)); - sprintf(this->reason_string, "%s%s", *reason_string, this->violating_ports); - *reason_string = this->reason_string; + + return TRUE; +} + +METHOD(imv_state_t, get_remediation_instructions, bool, + private_imv_scanner_state_t *this, enumerator_t *language_enumerator, + char **string, char **lang_code) +{ + bool match = FALSE; + char *lang; + int i; + + if (!this->violating_ports) + { + return FALSE; + } + + /* set the default language */ + *lang_code = instructions[0].lang; + *string = instructions[0].string; + + while (language_enumerator->enumerate(language_enumerator, &lang)) + { + for (i = 0; i < countof(instructions); i++) + { + if (streq(lang, instructions[i].lang)) + { + match = TRUE; + *lang_code = instructions[i].lang; + *string = instructions[i].string; + break; + } + } + if (match) + { + break; + } + } + this->instructions = malloc(strlen(*string) + + strlen(this->violating_ports) + 1); + sprintf(this->instructions, "%s%s", *string, this->violating_ports); + *string = this->instructions; return TRUE; } @@ -200,7 +249,7 @@ METHOD(imv_state_t, destroy, void, private_imv_scanner_state_t *this) { free(this->violating_ports); - free(this->reason_string); + free(this->instructions); free(this); } @@ -230,6 +279,7 @@ imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id) .get_recommendation = _get_recommendation, .set_recommendation = _set_recommendation, .get_reason_string = _get_reason_string, + .get_remediation_instructions = _get_remediation_instructions, .destroy = _destroy, }, .set_violating_ports = _set_violating_ports, diff --git a/src/libimcv/plugins/imv_test/imv_test_state.c b/src/libimcv/plugins/imv_test/imv_test_state.c index 1db6bb513..adfe862f2 100644 --- a/src/libimcv/plugins/imv_test/imv_test_state.c +++ b/src/libimcv/plugins/imv_test/imv_test_state.c @@ -195,6 +195,13 @@ METHOD(imv_state_t, get_reason_string, bool, return TRUE; } +METHOD(imv_state_t, get_remediation_instructions, bool, + private_imv_test_state_t *this, enumerator_t *language_enumerator, + char **string, char **lang_code) +{ + +} + METHOD(imv_state_t, destroy, void, private_imv_test_state_t *this) { @@ -287,6 +294,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id) .get_recommendation = _get_recommendation, .set_recommendation = _set_recommendation, .get_reason_string = _get_reason_string, + .get_remediation_instructions = _get_remediation_instructions, .destroy = _destroy, }, .add_imc = _add_imc, diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c index c1d83511d..b9adbc0a1 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_state.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c @@ -242,6 +242,13 @@ METHOD(imv_state_t, get_reason_string, bool, return TRUE; } +METHOD(imv_state_t, get_remediation_instructions, bool, + private_imv_attestation_state_t *this, enumerator_t *language_enumerator, + char **string, char **lang_code) +{ + return FALSE; +} + METHOD(imv_state_t, destroy, void, private_imv_attestation_state_t *this) { @@ -439,6 +446,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id) .get_recommendation = _get_recommendation, .set_recommendation = _set_recommendation, .get_reason_string = _get_reason_string, + .get_remediation_instructions = _get_remediation_instructions, .destroy = _destroy, }, .get_handshake_state = _get_handshake_state,