2 * Copyright (C) 2010-2012 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include <tncif_names.h>
20 #include <tnc/imv/imv.h>
21 #include <tnc/imv/imv_manager.h>
22 #include <tnc/imv/imv_recommendations.h>
24 #include <utils/debug.h>
25 #include <collections/linked_list.h>
27 typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t
;
28 typedef struct recommendation_entry_t recommendation_entry_t
;
31 * Recommendation entry
33 struct recommendation_entry_t
{
41 * Received a recommendation message from this IMV?
43 bool have_recommendation
;
46 * Action Recommendation provided by IMV instance
48 TNC_IMV_Action_Recommendation rec
;
51 * Evaluation Result provided by IMV instance
53 TNC_IMV_Evaluation_Result eval
;
56 * Reason string provided by IMV instance
61 * Reason language provided by IMV instance
63 chunk_t reason_language
;
67 * Private data of a recommendations_t object.
69 struct private_tnc_imv_recommendations_t
{
72 * Public members of recommendations_t.
74 recommendations_t
public;
77 * list of recommendations and evaluations provided by IMVs
82 * Preferred language for remediation messages
84 chunk_t preferred_language
;
87 METHOD(recommendations_t
, provide_recommendation
, TNC_Result
,
88 private_tnc_imv_recommendations_t
* this, TNC_IMVID id
,
89 TNC_IMV_Action_Recommendation rec
,
90 TNC_IMV_Evaluation_Result eval
)
92 enumerator_t
*enumerator
;
93 recommendation_entry_t
*entry
;
96 DBG2(DBG_TNC
, "IMV %u provides recommendation '%N' and evaluation '%N'", id
,
97 TNC_IMV_Action_Recommendation_names
, rec
,
98 TNC_IMV_Evaluation_Result_names
, eval
);
100 enumerator
= this->recs
->create_enumerator(this->recs
);
101 while (enumerator
->enumerate(enumerator
, &entry
))
106 entry
->have_recommendation
= TRUE
;
112 enumerator
->destroy(enumerator
);
113 return found
? TNC_RESULT_SUCCESS
: TNC_RESULT_FATAL
;
116 METHOD(recommendations_t
, have_recommendation
, bool,
117 private_tnc_imv_recommendations_t
*this, TNC_IMV_Action_Recommendation
*rec
,
118 TNC_IMV_Evaluation_Result
*eval
)
120 enumerator_t
*enumerator
;
121 recommendation_entry_t
*entry
;
122 recommendation_policy_t policy
;
123 TNC_IMV_Action_Recommendation final_rec
;
124 TNC_IMV_Evaluation_Result final_eval
;
125 bool first
= TRUE
, incomplete
= FALSE
;
127 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
128 final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
135 if (this->recs
->get_count(this->recs
) == 0)
137 DBG1(DBG_TNC
, "there are no IMVs to make a recommendation");
140 policy
= tnc
->imvs
->get_recommendation_policy(tnc
->imvs
);
142 enumerator
= this->recs
->create_enumerator(this->recs
);
143 while (enumerator
->enumerate(enumerator
, &entry
))
145 if (!entry
->have_recommendation
)
152 final_rec
= entry
->rec
;
153 final_eval
= entry
->eval
;
159 case RECOMMENDATION_POLICY_DEFAULT
:
162 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
163 final_rec
= entry
->rec
;
165 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
166 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
)
168 final_rec
= entry
->rec
;
171 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
172 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
174 final_rec
= entry
->rec
;
177 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
182 case TNC_IMV_EVALUATION_RESULT_ERROR
:
183 final_eval
= entry
->eval
;
185 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
186 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
)
188 final_eval
= entry
->eval
;
191 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
192 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
&&
193 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
)
195 final_eval
= entry
->eval
;
198 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
199 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
201 final_eval
= entry
->eval
;
204 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
209 case RECOMMENDATION_POLICY_ALL
:
210 if (entry
->rec
!= final_rec
)
212 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
214 if (entry
->eval
!= final_eval
)
216 final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
220 case RECOMMENDATION_POLICY_ANY
:
223 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
224 final_rec
= entry
->rec
;
226 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
227 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
229 final_rec
= entry
->rec
;
232 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
233 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
235 final_rec
= entry
->rec
;
238 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
243 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
244 final_eval
= entry
->eval
;
246 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
247 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
249 final_eval
= entry
->eval
;
252 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
253 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
&&
254 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
)
256 final_eval
= entry
->eval
;
259 case TNC_IMV_EVALUATION_RESULT_ERROR
:
260 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
262 final_eval
= entry
->eval
;
265 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
270 enumerator
->destroy(enumerator
);
284 METHOD(recommendations_t
, clear_recommendation
, void,
285 private_tnc_imv_recommendations_t
*this)
287 enumerator_t
*enumerator
;
288 recommendation_entry_t
*entry
;
290 enumerator
= this->recs
->create_enumerator(this->recs
);
291 while (enumerator
->enumerate(enumerator
, &entry
))
293 entry
->have_recommendation
= FALSE
;
294 entry
->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
295 entry
->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
296 chunk_clear(&entry
->reason
);
297 chunk_clear(&entry
->reason_language
);
299 enumerator
->destroy(enumerator
);
302 METHOD(recommendations_t
, get_preferred_language
, chunk_t
,
303 private_tnc_imv_recommendations_t
*this)
305 return this->preferred_language
;
308 METHOD(recommendations_t
, set_preferred_language
, void,
309 private_tnc_imv_recommendations_t
*this, chunk_t pref_lang
)
311 free(this->preferred_language
.ptr
);
312 this->preferred_language
= chunk_clone(pref_lang
);
315 METHOD(recommendations_t
, set_reason_string
, TNC_Result
,
316 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason
)
318 enumerator_t
*enumerator
;
319 recommendation_entry_t
*entry
;
322 DBG2(DBG_TNC
, "IMV %u is setting reason string to '%.*s'",
323 id
, (int)reason
.len
, reason
.ptr
);
325 enumerator
= this->recs
->create_enumerator(this->recs
);
326 while (enumerator
->enumerate(enumerator
, &entry
))
331 free(entry
->reason
.ptr
);
332 entry
->reason
= chunk_clone(reason
);
336 enumerator
->destroy(enumerator
);
337 return found
? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
340 METHOD(recommendations_t
, set_reason_language
, TNC_Result
,
341 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason_lang
)
343 enumerator_t
*enumerator
;
344 recommendation_entry_t
*entry
;
347 DBG2(DBG_TNC
, "IMV %u is setting reason language to '%.*s'",
348 id
, (int)reason_lang
.len
, reason_lang
.ptr
);
350 enumerator
= this->recs
->create_enumerator(this->recs
);
351 while (enumerator
->enumerate(enumerator
, &entry
))
356 free(entry
->reason_language
.ptr
);
357 entry
->reason_language
= chunk_clone(reason_lang
);
361 enumerator
->destroy(enumerator
);
362 return found
? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
366 * Enumerate reason and reason_language, not recommendation entries
368 static bool reason_filter(void *null
, recommendation_entry_t
**entry
,
369 TNC_IMVID
*id
, void *i2
, chunk_t
*reason
, void *i3
,
370 chunk_t
*reason_language
)
372 if ((*entry
)->reason
.len
)
375 *reason
= (*entry
)->reason
;
376 *reason_language
= (*entry
)->reason_language
;
385 METHOD(recommendations_t
, create_reason_enumerator
, enumerator_t
*,
386 private_tnc_imv_recommendations_t
*this)
388 return enumerator_create_filter(this->recs
->create_enumerator(this->recs
),
389 (void*)reason_filter
, NULL
, NULL
);
392 METHOD(recommendations_t
, destroy
, void,
393 private_tnc_imv_recommendations_t
*this)
395 recommendation_entry_t
*entry
;
397 while (this->recs
->remove_last(this->recs
, (void**)&entry
) == SUCCESS
)
399 free(entry
->reason
.ptr
);
400 free(entry
->reason_language
.ptr
);
403 this->recs
->destroy(this->recs
);
404 free(this->preferred_language
.ptr
);
409 * Described in header.
411 recommendations_t
* tnc_imv_recommendations_create(linked_list_t
*imv_list
)
413 private_tnc_imv_recommendations_t
*this;
414 recommendation_entry_t
*entry
;
415 enumerator_t
*enumerator
;
420 .provide_recommendation
= _provide_recommendation
,
421 .have_recommendation
= _have_recommendation
,
422 .clear_recommendation
= _clear_recommendation
,
423 .get_preferred_language
= _get_preferred_language
,
424 .set_preferred_language
= _set_preferred_language
,
425 .set_reason_string
= _set_reason_string
,
426 .set_reason_language
= _set_reason_language
,
427 .create_reason_enumerator
= _create_reason_enumerator
,
430 .recs
= linked_list_create(),
433 enumerator
= imv_list
->create_enumerator(imv_list
);
434 while (enumerator
->enumerate(enumerator
, &imv
))
436 entry
= malloc_thing(recommendation_entry_t
);
437 entry
->id
= imv
->get_id(imv
);
438 entry
->have_recommendation
= FALSE
;
439 entry
->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
440 entry
->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
441 entry
->reason
= chunk_empty
;
442 entry
->reason_language
= chunk_empty
;
443 this->recs
->insert_last(this->recs
, entry
);
445 enumerator
->destroy(enumerator
);
447 return &this->public;