}
else
{
- pos = this->lang_pos + len;
len = this->lang_len;
+ pos = this->lang_pos + len;
this->lang_pos = NULL;
this->lang_len = 0;
}
/* 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;
#include "ietf/ietf_attr.h"
#include "ietf/ietf_attr_assess_result.h"
+#include "ietf/ietf_attr_remediation_instr.h"
#include <tncif_names.h>
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",
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);
}
*
* @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
#include <ietf/ietf_attr.h>
#include <ietf/ietf_attr_attr_request.h>
#include <ietf/ietf_attr_port_filter.h>
+#include <ietf/ietf_attr_remediation_instr.h>
#include <tncif_pa_subtypes.h>
}
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);
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)
{
.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,
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;
* 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,
{
return FALSE;
}
+
/* set the default language */
*reason_language = reasons[0].lang;
*reason_string = reasons[0].string;
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;
}
private_imv_scanner_state_t *this)
{
free(this->violating_ports);
- free(this->reason_string);
+ free(this->instructions);
free(this);
}
.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,
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)
{
.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,
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)
{
.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,