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.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'", id
,
91 TNC_IMV_Action_Recommendation_names
, rec
,
92 TNC_IMV_Evaluation_Result_names
, eval
);
94 enumerator
= this->recs
->create_enumerator(this->recs
);
95 while (enumerator
->enumerate(enumerator
, &entry
))
100 entry
->have_recommendation
= TRUE
;
106 enumerator
->destroy(enumerator
);
107 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_FATAL
;
110 METHOD(recommendations_t
, have_recommendation
, bool,
111 private_tnc_imv_recommendations_t
*this, TNC_IMV_Action_Recommendation
*rec
,
112 TNC_IMV_Evaluation_Result
*eval
)
114 enumerator_t
*enumerator
;
115 recommendation_entry_t
*entry
;
116 recommendation_policy_t policy
;
117 TNC_IMV_Action_Recommendation final_rec
;
118 TNC_IMV_Evaluation_Result final_eval
;
119 bool first
= TRUE
, incomplete
= FALSE
;
121 *rec
= final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
122 *eval
= final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
124 if (this->recs
->get_count(this->recs
) == 0)
126 DBG1(DBG_TNC
, "there are no IMVs to make a recommendation");
129 policy
= charon
->imvs
->get_recommendation_policy(charon
->imvs
);
131 enumerator
= this->recs
->create_enumerator(this->recs
);
132 while (enumerator
->enumerate(enumerator
, &entry
))
134 if (!entry
->have_recommendation
)
141 final_rec
= entry
->rec
;
142 final_eval
= entry
->eval
;
148 case RECOMMENDATION_POLICY_DEFAULT
:
151 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
152 final_rec
= entry
->rec
;
154 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
155 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
)
157 final_rec
= entry
->rec
;
160 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
161 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
163 final_rec
= entry
->rec
;
166 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
171 case TNC_IMV_EVALUATION_RESULT_ERROR
:
172 final_eval
= entry
->eval
;
174 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
175 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
)
177 final_eval
= entry
->eval
;
180 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
181 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_ERROR
&&
182 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
)
184 final_eval
= entry
->eval
;
187 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
188 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
190 final_eval
= entry
->eval
;
193 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
198 case RECOMMENDATION_POLICY_ALL
:
199 if (entry
->rec
!= final_rec
)
201 final_rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
203 if (entry
->eval
!= final_eval
)
205 final_eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
209 case RECOMMENDATION_POLICY_ANY
:
212 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW
:
213 final_rec
= entry
->rec
;
215 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE
:
216 if (final_rec
!= TNC_IMV_ACTION_RECOMMENDATION_ALLOW
)
218 final_rec
= entry
->rec
;
221 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS
:
222 if (final_rec
== TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
)
224 final_rec
= entry
->rec
;
227 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
:
232 case TNC_IMV_EVALUATION_RESULT_COMPLIANT
:
233 final_eval
= entry
->eval
;
235 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
:
236 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
)
238 final_eval
= entry
->eval
;
241 case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR
:
242 if (final_eval
!= TNC_IMV_EVALUATION_RESULT_COMPLIANT
&&
243 final_eval
!= TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR
)
245 final_eval
= entry
->eval
;
248 case TNC_IMV_EVALUATION_RESULT_ERROR
:
249 if (final_eval
== TNC_IMV_EVALUATION_RESULT_DONT_KNOW
)
251 final_eval
= entry
->eval
;
254 case TNC_IMV_EVALUATION_RESULT_DONT_KNOW
:
259 enumerator
->destroy(enumerator
);
270 METHOD(recommendations_t
, get_preferred_language
, chunk_t
,
271 private_tnc_imv_recommendations_t
*this)
273 return this->preferred_language
;
276 METHOD(recommendations_t
, set_preferred_language
, void,
277 private_tnc_imv_recommendations_t
*this, chunk_t pref_lang
)
279 free(this->preferred_language
.ptr
);
280 this->preferred_language
= chunk_clone(pref_lang
);
283 METHOD(recommendations_t
, set_reason_string
, TNC_Result
,
284 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason
)
286 enumerator_t
*enumerator
;
287 recommendation_entry_t
*entry
;
290 DBG2(DBG_TNC
, "IMV %u is setting reason string to '%.*s'",
291 id
, reason
.len
, reason
.ptr
);
293 enumerator
= this->recs
->create_enumerator(this->recs
);
294 while (enumerator
->enumerate(enumerator
, &entry
))
299 free(entry
->reason
.ptr
);
300 entry
->reason
= chunk_clone(reason
);
304 enumerator
->destroy(enumerator
);
305 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
308 METHOD(recommendations_t
, set_reason_language
, TNC_Result
,
309 private_tnc_imv_recommendations_t
*this, TNC_IMVID id
, chunk_t reason_lang
)
311 enumerator_t
*enumerator
;
312 recommendation_entry_t
*entry
;
315 DBG2(DBG_TNC
, "IMV %u is setting reason language to '%.*s'",
316 id
, reason_lang
.len
, reason_lang
.ptr
);
318 enumerator
= this->recs
->create_enumerator(this->recs
);
319 while (enumerator
->enumerate(enumerator
, &entry
))
324 free(entry
->reason_language
.ptr
);
325 entry
->reason_language
= chunk_clone(reason_lang
);
329 enumerator
->destroy(enumerator
);
330 return found ? TNC_RESULT_SUCCESS
: TNC_RESULT_INVALID_PARAMETER
;
334 * Enumerate reason and reason_language, not recommendation entries
336 static bool reason_filter(void *null
, recommendation_entry_t
**entry
,
337 TNC_IMVID
*id
, void *i2
, chunk_t
*reason
, void *i3
,
338 chunk_t
*reason_language
)
340 if ((*entry
)->reason
.len
)
343 *reason
= (*entry
)->reason
;
344 *reason_language
= (*entry
)->reason_language
;
353 METHOD(recommendations_t
, create_reason_enumerator
, enumerator_t
*,
354 private_tnc_imv_recommendations_t
*this)
356 return enumerator_create_filter(this->recs
->create_enumerator(this->recs
),
357 (void*)reason_filter
, NULL
, NULL
);
360 METHOD(recommendations_t
, destroy
, void,
361 private_tnc_imv_recommendations_t
*this)
363 recommendation_entry_t
*entry
;
365 while (this->recs
->remove_last(this->recs
, (void**)&entry
) == SUCCESS
)
367 free(entry
->reason
.ptr
);
368 free(entry
->reason_language
.ptr
);
371 this->recs
->destroy(this->recs
);
372 free(this->preferred_language
.ptr
);
377 * Described in header.
379 recommendations_t
* tnc_imv_recommendations_create(linked_list_t
*imv_list
)
381 private_tnc_imv_recommendations_t
*this;
382 recommendation_entry_t
*entry
;
383 enumerator_t
*enumerator
;
388 .provide_recommendation
= _provide_recommendation
,
389 .have_recommendation
= _have_recommendation
,
390 .get_preferred_language
= _get_preferred_language
,
391 .set_preferred_language
= _set_preferred_language
,
392 .set_reason_string
= _set_reason_string
,
393 .set_reason_language
= _set_reason_language
,
394 .create_reason_enumerator
= _create_reason_enumerator
,
397 .recs
= linked_list_create(),
400 enumerator
= imv_list
->create_enumerator(imv_list
);
401 while (enumerator
->enumerate(enumerator
, &imv
))
403 entry
= malloc_thing(recommendation_entry_t
);
404 entry
->id
= imv
->get_id(imv
);
405 entry
->have_recommendation
= FALSE
;
406 entry
->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
407 entry
->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
408 entry
->reason
= chunk_empty
;
409 entry
->reason_language
= chunk_empty
;
410 this->recs
->insert_last(this->recs
, entry
);
412 enumerator
->destroy(enumerator
);
414 return &this->public;