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 <tnc/tncifimv_names.h>
18 #include <tnc/imv/imv.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 * Received a recommendation message from this IMV?
37 bool have_recommendation
;
40 * Action Recommendation provided by IMV instance
42 TNC_IMV_Action_Recommendation rec
;
45 * Evaluation Result provided by IMV instance
47 TNC_IMV_Evaluation_Result eval
;
50 * Reason string provided by IMV instance
55 * Reason language provided by IMV instance
57 chunk_t reason_language
;
61 * Private data of a recommendations_t object.
63 struct private_tnc_imv_recommendations_t
{
66 * Public members of recommendations_t.
68 recommendations_t
public;
71 * list of recommendations and evaluations provided by IMVs
76 * Preferred language for remediation messages
78 chunk_t preferred_language
;
81 METHOD(recommendations_t
, provide_recommendation
, TNC_Result
,
82 private_tnc_imv_recommendations_t
* this, TNC_IMVID id
,
83 TNC_IMV_Action_Recommendation rec
,
84 TNC_IMV_Evaluation_Result eval
)
86 enumerator_t
*enumerator
;
87 recommendation_entry_t
*entry
;
90 DBG2(DBG_TNC
, "IMV %u provides recommendation '%N' and evaluation '%N'",
91 id
, action_recommendation_names
, rec
, evaluation_result_names
, eval
);
93 enumerator
= this->recs
->create_enumerator(this->recs
);
94 while (enumerator
->enumerate(enumerator
, &entry
))
99 entry
->have_recommendation
= TRUE
;
105 enumerator
->destroy(enumerator
);
106 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_FATAL
;
109 METHOD(recommendations_t
, have_recommendation
, bool,
110 private_tnc_imv_recommendations_t
*this, TNC_IMV_Action_Recommendation
*rec
,
111 TNC_IMV_Evaluation_Result
*eval
)
113 enumerator_t
*enumerator
;
114 recommendation_entry_t
*entry
;
115 recommendation_policy_t policy
;
116 TNC_IMV_Action_Recommendation final_rec
;
117 TNC_IMV_Evaluation_Result final_eval
;
118 bool first
= TRUE
, incomplete
= FALSE
;
120 *rec
= final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
121 *eval
= final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
123 if (this->recs
->get_count(this->recs
) == 0)
125 DBG1(DBG_TNC
, "there are no IMVs to make a recommendation");
128 policy
= charon
->imvs
->get_recommendation_policy(charon
->imvs
);
130 enumerator
= this->recs
->create_enumerator(this->recs
);
131 while (enumerator
->enumerate(enumerator
, &entry
))
133 if (!entry
->have_recommendation
)
140 final_rec
= entry
->rec
;
141 final_eval
= entry
->eval
;
147 case RECOMMENDATION_POLICY_DEFAULT
:
150 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
151 final_rec
= entry
->rec
;
153 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
154 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
)
156 final_rec
= entry
->rec
;
159 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
160 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
162 final_rec
= entry
->rec
;
165 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
170 case TNC_IMV_EVALUATION_RESULT_ERROR
:
171 final_eval
= entry
->eval
;
173 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
174 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
)
176 final_eval
= entry
->eval
;
179 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
180 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
&&
181 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
)
183 final_eval
= entry
->eval
;
186 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
187 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
189 final_eval
= entry
->eval
;
192 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
197 case RECOMMENDATION_POLICY_ALL
:
198 if (entry
->rec
!= final_rec
)
200 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
202 if (entry
->eval
!= final_eval
)
204 final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
208 case RECOMMENDATION_POLICY_ANY
:
211 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
212 final_rec
= entry
->rec
;
214 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
215 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
217 final_rec
= entry
->rec
;
220 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
221 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
223 final_rec
= entry
->rec
;
226 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
231 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
232 final_eval
= entry
->eval
;
234 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
235 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
237 final_eval
= entry
->eval
;
240 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
241 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
&&
242 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
)
244 final_eval
= entry
->eval
;
247 case TNC_IMV_EVALUATION_RESULT_ERROR
:
248 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
250 final_eval
= entry
->eval
;
253 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
258 enumerator
->destroy(enumerator
);
269 METHOD(recommendations_t
, get_preferred_language
, chunk_t
,
270 private_tnc_imv_recommendations_t
*this)
272 return this->preferred_language
;
275 METHOD(recommendations_t
, set_preferred_language
, void,
276 private_tnc_imv_recommendations_t
*this, chunk_t pref_lang
)
278 free(this->preferred_language
.ptr
);
279 this->preferred_language
= chunk_clone(pref_lang
);
282 METHOD(recommendations_t
, set_reason_string
, TNC_Result
,
283 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason
)
285 enumerator_t
*enumerator
;
286 recommendation_entry_t
*entry
;
289 DBG2(DBG_TNC
, "IMV %u is setting reason string to '%.*s'",
290 id
, reason
.len
, reason
.ptr
);
292 enumerator
= this->recs
->create_enumerator(this->recs
);
293 while (enumerator
->enumerate(enumerator
, &entry
))
298 free(entry
->reason
.ptr
);
299 entry
->reason
= chunk_clone(reason
);
303 enumerator
->destroy(enumerator
);
304 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
307 METHOD(recommendations_t
, set_reason_language
, TNC_Result
,
308 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason_lang
)
310 enumerator_t
*enumerator
;
311 recommendation_entry_t
*entry
;
314 DBG2(DBG_TNC
, "IMV %u is setting reason language to '%.*s'",
315 id
, reason_lang
.len
, reason_lang
.ptr
);
317 enumerator
= this->recs
->create_enumerator(this->recs
);
318 while (enumerator
->enumerate(enumerator
, &entry
))
323 free(entry
->reason_language
.ptr
);
324 entry
->reason_language
= chunk_clone(reason_lang
);
328 enumerator
->destroy(enumerator
);
329 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
332 METHOD(recommendations_t
, destroy
, void,
333 private_tnc_imv_recommendations_t
*this)
335 recommendation_entry_t
*entry
;
337 while (this->recs
->remove_last(this->recs
, (void**)&entry
) == SUCCESS
)
339 free(entry
->reason
.ptr
);
340 free(entry
->reason_language
.ptr
);
343 this->recs
->destroy(this->recs
);
344 free(this->preferred_language
.ptr
);
349 * Described in header.
351 recommendations_t
* tnc_imv_recommendations_create(linked_list_t
*imv_list
)
353 private_tnc_imv_recommendations_t
*this;
354 recommendation_entry_t
*entry
;
355 enumerator_t
*enumerator
;
360 .provide_recommendation
= _provide_recommendation
,
361 .have_recommendation
= _have_recommendation
,
362 .get_preferred_language
= _get_preferred_language
,
363 .set_preferred_language
= _set_preferred_language
,
364 .set_reason_string
= _set_reason_string
,
365 .set_reason_language
= _set_reason_language
,
369 .recs
= linked_list_create(),
372 enumerator
= imv_list
->create_enumerator(imv_list
);
373 while (enumerator
->enumerate(enumerator
, &imv
))
375 entry
= malloc_thing(recommendation_entry_t
);
376 entry
->id
= imv
->get_id(imv
);
377 entry
->have_recommendation
= FALSE
;
378 entry
->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
379 entry
->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
380 entry
->reason
= chunk_empty
;
381 entry
->reason_language
= chunk_empty
;
382 this->recs
->insert_last(this->recs
, entry
);
384 enumerator
->destroy(enumerator
);
386 return &this->public;