*/
#include <debug.h>
-#include <utils/linked_list.h>
-#include <threading/mutex.h>
+#include <daemon.h>
#include <tnc/tncifimv_names.h>
+#include <tnc/imv/imv.h>
#include <tnc/imv/imv_recommendations.h>
typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t;
private_tnc_imv_recommendations_t *this, TNC_IMV_Action_Recommendation *rec,
TNC_IMV_Evaluation_Result *eval)
{
- /* TODO */
- *rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
- *eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+ recommendation_policy_t policy;
+ TNC_IMV_Action_Recommendation final_rec;
+ TNC_IMV_Evaluation_Result final_eval;
+ bool first = TRUE, incomplete = FALSE;
+
+ *rec = final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+ *eval = final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+
+ if (this->recs->get_count(this->recs) == 0)
+ {
+ DBG1(DBG_TNC, "there are no IMVs to make a recommendation");
+ return TRUE;
+ }
+ policy = charon->imvs->get_recommendation_policy(charon->imvs);
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION ||
+ entry->eval == TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
+ {
+ incomplete = TRUE;
+ break;
+ }
+ if (first)
+ {
+ final_rec = entry->rec;
+ final_eval = entry->eval;
+ first = FALSE;
+ }
+ switch (policy)
+ {
+ case RECOMMENDATION_POLICY_DEFAULT:
+ /* Consolidate action recommendations */
+ if (entry->rec == TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
+ }
+ else if (entry->rec == TNC_IMV_ACTION_RECOMMENDATION_ISOLATE &&
+ final_rec != TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
+ }
+ else
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
+ }
+
+ /* Consolidate evaluation results */
+ if (entry->eval == TNC_IMV_EVALUATION_RESULT_ERROR)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_ERROR;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_ERROR)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_ERROR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_COMPLIANT)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
+ }
+ break;
+ case RECOMMENDATION_POLICY_ALL:
+ /* Consolidate action recommendations */
+ if (entry->rec != final_rec)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+ }
+
+ /* Consolidate evaluation results */
+ if (entry->eval != final_eval)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+ }
+ break;
+ case RECOMMENDATION_POLICY_ANY:
+ /* Consolidate action recommendations */
+ if (entry->rec == TNC_IMV_ACTION_RECOMMENDATION_ALLOW)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
+ }
+ else if (entry->rec == TNC_IMV_ACTION_RECOMMENDATION_ISOLATE &&
+ final_rec != TNC_IMV_ACTION_RECOMMENDATION_ALLOW)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
+ }
+ else
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
+ }
+
+ /* Consolidate evaluation results */
+ if (entry->eval == TNC_IMV_EVALUATION_RESULT_COMPLIANT)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR;
+ }
+ else if (entry->eval == TNC_IMV_EVALUATION_RESULT_ERROR)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_ERROR;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (incomplete)
+ {
+ return FALSE;
+ }
+ *rec = final_rec;
+ *eval = final_eval;
return TRUE;
}
+
METHOD(recommendations_t, destroy, void,
private_tnc_imv_recommendations_t *this)
{
private_tnc_imv_recommendations_t *this;
recommendation_entry_t *entry;
enumerator_t *enumerator;
- TNC_IMVID id;
+ imv_t *imv;
INIT(this,
.public = {
);
enumerator = imv_list->create_enumerator(imv_list);
- while (enumerator->enumerate(enumerator, &id))
+ while (enumerator->enumerate(enumerator, &imv))
{
entry = malloc_thing(recommendation_entry_t);
- entry->id = id;
+ entry->id = imv->get_id(imv);
entry->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
entry->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
this->recs->insert_last(this->recs, entry);