2 * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include <threading/mutex.h>
18 #include <tnc/tncifimv_names.h>
19 #include <tnc/imv/imv_recommendations.h>
21 typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t
;
22 typedef struct recommendation_entry_t recommendation_entry_t
;
25 * Recommendation entry
27 struct recommendation_entry_t
{
35 * Action Recommendation provided by IMV instance
37 TNC_IMV_Action_Recommendation rec
;
40 * Evaluation Result provided by IMV instance
42 TNC_IMV_Evaluation_Result eval
;
46 * Private data of a recommendations_t object.
48 struct private_tnc_imv_recommendations_t
{
51 * Public members of recommendations_t.
53 recommendations_t
public;
56 * list of recommendations and evaluations provided by IMVs
61 METHOD(recommendations_t
, provide_recommendation
, TNC_Result
,
62 private_tnc_imv_recommendations_t
* this, TNC_IMVID id
,
63 TNC_IMV_Action_Recommendation rec
,
64 TNC_IMV_Evaluation_Result eval
)
66 enumerator_t
*enumerator
;
67 recommendation_entry_t
*entry
;
70 DBG2(DBG_TNC
, "IMV %u provides recommendation '%N' and evaluation '%N'",
71 id
, action_recommendation_names
, rec
, evaluation_result_names
, eval
);
73 enumerator
= this->recs
->create_enumerator(this->recs
);
74 while (enumerator
->enumerate(enumerator
, &entry
))
84 enumerator
->destroy(enumerator
);
85 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_FATAL
;
88 METHOD(recommendations_t
, have_recommendation
, bool,
89 private_tnc_imv_recommendations_t
*this, TNC_IMV_Action_Recommendation
*rec
,
90 TNC_IMV_Evaluation_Result
*eval
)
92 enumerator_t
*enumerator
;
93 recommendation_entry_t
*entry
;
94 recommendation_policy_t policy
;
95 TNC_IMV_Action_Recommendation final_rec
;
96 TNC_IMV_Evaluation_Result final_eval
;
97 bool first
= TRUE
, incomplete
= FALSE
;
99 *rec
= final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
100 *eval
= final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
102 if (this->recs
->get_count(this->recs
) == 0)
104 DBG1(DBG_TNC
, "there are no IMVs to make a recommendation");
107 policy
= charon
->imvs
->get_recommendation_policy(charon
->imvs
);
109 enumerator
= this->recs
->create_enumerator(this->recs
);
110 while (enumerator
->enumerate(enumerator
, &entry
))
112 if (entry
->rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
||
113 entry
->eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
120 final_rec
= entry
->rec
;
121 final_eval
= entry
->eval
;
126 case RECOMMENDATION_POLICY_DEFAULT
:
127 /* Consolidate action recommendations */
128 if (entry
->rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
)
130 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
;
132 else if (entry
->rec
== TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
&&
133 final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
)
135 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
;
139 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
;
142 /* Consolidate evaluation results */
143 if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_ERROR
)
145 final_eval
= TNC_IMV_EVALUATION_RESULT_ERROR
;
147 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
&&
148 final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
)
150 final_eval
= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
;
152 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
&&
153 final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
&&
154 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
)
156 final_eval
= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
;
158 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
160 final_eval
= TNC_IMV_EVALUATION_RESULT_COMPLIANT
;
163 case RECOMMENDATION_POLICY_ALL
:
164 /* Consolidate action recommendations */
165 if (entry
->rec
!= final_rec
)
167 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
170 /* Consolidate evaluation results */
171 if (entry
->eval
!= final_eval
)
173 final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
176 case RECOMMENDATION_POLICY_ANY
:
177 /* Consolidate action recommendations */
178 if (entry
->rec
== TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
180 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
;
182 else if (entry
->rec
== TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
&&
183 final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
185 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
;
189 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
;
192 /* Consolidate evaluation results */
193 if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
195 final_eval
= TNC_IMV_EVALUATION_RESULT_COMPLIANT
;
197 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
&&
198 final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
200 final_eval
= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
;
202 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
&&
203 final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
&&
204 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
)
206 final_eval
= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
;
208 else if (entry
->eval
== TNC_IMV_EVALUATION_RESULT_ERROR
)
210 final_eval
= TNC_IMV_EVALUATION_RESULT_ERROR
;
214 enumerator
->destroy(enumerator
);
226 METHOD(recommendations_t
, destroy
, void,
227 private_tnc_imv_recommendations_t
*this)
229 this->recs
->destroy_function(this->recs
, free
);
234 * Described in header.
236 recommendations_t
* tnc_imv_recommendations_create(linked_list_t
*imv_list
)
238 private_tnc_imv_recommendations_t
*this;
239 recommendation_entry_t
*entry
;
240 enumerator_t
*enumerator
;
245 .provide_recommendation
= _provide_recommendation
,
246 .have_recommendation
= _have_recommendation
,
249 .recs
= linked_list_create(),
252 enumerator
= imv_list
->create_enumerator(imv_list
);
253 while (enumerator
->enumerate(enumerator
, &id
))
255 entry
= malloc_thing(recommendation_entry_t
);
257 entry
->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
258 entry
->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
259 this->recs
->insert_last(this->recs
, entry
);
261 enumerator
->destroy(enumerator
);
263 return &this->public;