implemented have_recommendation() based on a choice of 3 policies
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 15 Nov 2010 16:38:31 +0000 (17:38 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 15 Nov 2010 17:25:58 +0000 (18:25 +0100)
src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/tnc/imv/imv_manager.h
src/libcharon/tnc/imv/imv_recommendations.c
src/libcharon/tnc/imv/imv_recommendations.h

index 3b96358..d8bb607 100644 (file)
@@ -100,6 +100,12 @@ METHOD(imv_manager_t, remove_, imv_t*,
        return NULL;
 }
 
+METHOD(imv_manager_t, get_recommendation_policy, recommendation_policy_t,
+       private_tnc_imv_manager_t *this)
+{
+       return this->policy;
+}
+
 METHOD(imv_manager_t, create_recommendations, recommendations_t*,
        private_tnc_imv_manager_t *this)
 {
@@ -266,6 +272,7 @@ imv_manager_t* tnc_imv_manager_create(void)
                .public = {
                        .add = _add,
                        .remove = _remove_, /* avoid name conflict with stdio.h */
+                       .get_recommendation_policy = _get_recommendation_policy,
                        .create_recommendations = _create_recommendations,
                        .enforce_recommendation = _enforce_recommendation,
                        .notify_connection_change = _notify_connection_change,
@@ -280,8 +287,8 @@ imv_manager_t* tnc_imv_manager_create(void)
        );
        policy = enum_from_name(recommendation_policy_names,
                                lib->settings->get_str(lib->settings,
-                                       "charon.plugins.tnc-imv.recommendation_policy", "any"));
-       this->policy = (policy != -1) ? policy : RECOMMENDATION_POLICY_NONE;
+                                       "charon.plugins.tnc-imv.recommendation_policy", "default"));
+       this->policy = (policy != -1) ? policy : RECOMMENDATION_POLICY_DEFAULT;
        DBG1(DBG_TNC, "TNC recommendation policy is '%N'",
                                   recommendation_policy_names, this->policy);
 
index 5a2d0de..846c1ce 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <debug.h>
-#include <utils/linked_list.h>
+#include <daemon.h>
 #include <threading/mutex.h>
 #include <tnc/tncifimv_names.h>
 #include <tnc/imv/imv_recommendations.h>
@@ -89,12 +89,140 @@ METHOD(recommendations_t, have_recommendation, bool,
        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)
 {
index 4c654e9..afd105c 100644 (file)
@@ -19,6 +19,7 @@
 #include <daemon.h>
 #include <threading/mutex.h>
 #include <tnc/tncif.h>
+#include <tnc/tncifimv_names.h>
 #include <tnc/tnccs/tnccs.h>
 
 typedef struct private_tnccs_20_t private_tnccs_20_t;
@@ -179,6 +180,9 @@ METHOD(tls_t, is_complete, bool,
 
        if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
        {
+               DBG2(DBG_TNC, "Final recommendation '%N' and evaluation '%N'",
+                        action_recommendation_names, rec, evaluation_result_names, eval);
+
                return charon->imvs->enforce_recommendation(charon->imvs, rec);
        }
        else
index a1951fe..b5c581a 100644 (file)
@@ -50,6 +50,13 @@ struct imv_manager_t {
        imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id);
 
        /**
+        * Get the configured recommendation policy
+        *
+        * @return                                      configured recommendation policy
+        */
+       recommendation_policy_t (*get_recommendation_policy)(imv_manager_t *this);
+
+       /**
         * Create an empty set of IMV recommendations and evaluations
         *
         * @return                                      instance of a recommendations_t list
index 99c92c7..9daaca1 100644 (file)
@@ -15,9 +15,9 @@
 
 #include "imv_recommendations.h"
 
-ENUM(recommendation_policy_names, RECOMMENDATION_POLICY_NONE,
+ENUM(recommendation_policy_names, RECOMMENDATION_POLICY_DEFAULT,
                                                                  RECOMMENDATION_POLICY_ALL,
-       "none",
+       "default",
        "any",
        "all"
 );
index c0fe01b..82c5ae8 100644 (file)
@@ -27,7 +27,7 @@
 typedef enum recommendation_policy_t recommendation_policy_t;
 
 enum recommendation_policy_t {
-       RECOMMENDATION_POLICY_NONE,
+       RECOMMENDATION_POLICY_DEFAULT,
        RECOMMENDATION_POLICY_ANY,
        RECOMMENDATION_POLICY_ALL
 };