2 * Copyright (C) 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
16 #include "imv_os_state.h"
17 #include "imv/imv_lang_string.h"
18 #include "imv/imv_reason_string.h"
19 #include "imv/imv_remediation_string.h"
21 #include <utils/debug.h>
22 #include <collections/linked_list.h>
24 typedef struct private_imv_os_state_t private_imv_os_state_t
;
25 typedef struct package_entry_t package_entry_t
;
26 typedef struct entry_t entry_t
;
27 typedef struct instruction_entry_t instruction_entry_t
;
30 * Private data of an imv_os_state_t object.
32 struct private_imv_os_state_t
{
35 * Public members of imv_os_state_t
37 imv_os_state_t
public;
42 TNC_ConnectionID connection_id
;
45 * TNCCS connection state
47 TNC_ConnectionState state
;
50 * Does the TNCCS connection support long message types?
55 * Does the TNCCS connection support exclusive delivery?
60 * Maximum PA-TNC message size for this TNCCS connection
62 u_int32_t max_msg_len
;
65 * IMV action recommendation
67 TNC_IMV_Action_Recommendation rec
;
70 * IMV evaluation result
72 TNC_IMV_Evaluation_Result eval
;
75 * OS Product Information (concatenation of OS Name and Version)
95 * List of blacklisted packages to be removed
97 linked_list_t
*remove_packages
;
100 * List of vulnerable packages to be updated
102 linked_list_t
*update_packages
;
107 imv_reason_string_t
*reason_string
;
110 * IETF Remediation Instructions String
112 imv_remediation_string_t
*remediation_string
;
115 * Number of processed packages
120 * Number of not updated packages
125 * Number of blacklisted packages
130 * Number of whitelisted packages
135 * OS Installed Package request sent - mandatory response expected
137 bool package_request
;
152 * Supported languages
154 static char* languages
[] = { "en", "de", "pl" };
157 * Reason strings for "OS settings"
159 static imv_lang_string_t reason_settings
[] = {
160 { "en", "Improper OS settings were detected" },
161 { "de", "Unzulässige OS Einstellungen wurden festgestellt" },
162 { "pl", "Stwierdzono niewłaściwe ustawienia OS" },
167 * Reason strings for "installed software packages"
169 static imv_lang_string_t reason_packages
[] = {
170 { "en", "Vulnerable or blacklisted software packages were found" },
171 { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" },
172 { "pl", "Znaleziono pakiety podatne na atak lub będące na czarnej liście" },
177 * Instruction strings for "Software Security Updates"
179 static imv_lang_string_t instr_update_packages_title
[] = {
180 { "en", "Software Security Updates" },
181 { "de", "Software Sicherheitsupdates" },
182 { "pl", "aktualizacja softwaru zabezpieczającego" },
186 static imv_lang_string_t instr_update_packages_descr
[] = {
187 { "en", "Packages with security vulnerabilities were found" },
188 { "de", "Softwarepakete mit Sicherheitsschwachstellen wurden gefunden" },
189 { "pl", "Znaleziono pakiety podatne na atak" },
193 static imv_lang_string_t instr_update_packages_header
[] = {
194 { "en", "Please update the following software packages:" },
195 { "de", "Bitte updaten Sie die folgenden Softwarepakete:" },
196 { "pl", "Proszę zaktualizować następujące pakiety:" },
201 * Instruction strings for "Blacklisted Software Packages"
203 static imv_lang_string_t instr_remove_packages_title
[] = {
204 { "en", "Blacklisted Software Packages" },
205 { "de", "Gesperrte Softwarepakete" },
206 { "pl", "Pakiety będące na czarnej liście" },
210 static imv_lang_string_t instr_remove_packages_descr
[] = {
211 { "en", "Dangerous software packages were found" },
212 { "de", "Gefährliche Softwarepakete wurden gefunden" },
213 { "pl", "Znaleziono niebezpieczne pakiety" },
217 static imv_lang_string_t instr_remove_packages_header
[] = {
218 { "en", "Please remove the following software packages:" },
219 { "de", "Bitte entfernen Sie die folgenden Softwarepakete:" },
220 { "pl", "Proszę usunąć następujące pakiety:" },
225 * Instruction strings for "Forwarding Enabled"
227 static imv_lang_string_t instr_fwd_enabled_title
[] = {
228 { "en", "IP Packet Forwarding" },
229 { "de", "Weiterleitung von IP Paketen" },
230 { "pl", "Przekazywanie pakietów IP" },
234 static imv_lang_string_t instr_fwd_enabled_descr
[] = {
235 { "en", "Please disable the forwarding of IP packets" },
236 { "de", "Bitte deaktivieren Sie das Forwarding von IP Paketen" },
237 { "pl", "Proszę zdezaktywować przekazywanie pakietów IP" },
242 * Instruction strings for "Default Password Enabled"
244 static imv_lang_string_t instr_default_pwd_enabled_title
[] = {
245 { "en", "Default Password" },
246 { "de", "Default Passwort" },
247 { "pl", "Hasło domyślne" },
251 static imv_lang_string_t instr_default_pwd_enabled_descr
[] = {
252 { "en", "Please change the default password" },
253 { "de", "Bitte ändern Sie das Default Passwort" },
254 { "pl", "Proszę zmienić domyślne hasło" },
259 * Instruction strings for "Install Non-Market Apps"
261 static imv_lang_string_t instr_non_market_apps_title
[] = {
262 { "en", "Unknown Software Origin" },
263 { "de", "Unbekannte Softwareherkunft" },
264 { "pl", "Nieznane pochodzenie softwaru" },
268 static imv_lang_string_t instr_non_market_apps_descr
[] = {
269 { "en", "Do not allow the installation of apps from unknown sources" },
270 { "de", "Erlauben Sie nicht die Installation von Apps aus unbekannten Quellen" },
271 { "pl", "Proszę nie dopuszczać do instalacji Apps z nieznanych źródeł" },
275 METHOD(imv_state_t
, get_connection_id
, TNC_ConnectionID
,
276 private_imv_os_state_t
*this)
278 return this->connection_id
;
281 METHOD(imv_state_t
, has_long
, bool,
282 private_imv_os_state_t
*this)
284 return this->has_long
;
287 METHOD(imv_state_t
, has_excl
, bool,
288 private_imv_os_state_t
*this)
290 return this->has_excl
;
293 METHOD(imv_state_t
, set_flags
, void,
294 private_imv_os_state_t
*this, bool has_long
, bool has_excl
)
296 this->has_long
= has_long
;
297 this->has_excl
= has_excl
;
300 METHOD(imv_state_t
, set_max_msg_len
, void,
301 private_imv_os_state_t
*this, u_int32_t max_msg_len
)
303 this->max_msg_len
= max_msg_len
;
306 METHOD(imv_state_t
, get_max_msg_len
, u_int32_t
,
307 private_imv_os_state_t
*this)
309 return this->max_msg_len
;
312 METHOD(imv_state_t
, change_state
, void,
313 private_imv_os_state_t
*this, TNC_ConnectionState new_state
)
315 this->state
= new_state
;
318 METHOD(imv_state_t
, get_recommendation
, void,
319 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation
*rec
,
320 TNC_IMV_Evaluation_Result
*eval
)
326 METHOD(imv_state_t
, set_recommendation
, void,
327 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation rec
,
328 TNC_IMV_Evaluation_Result eval
)
334 METHOD(imv_state_t
, get_reason_string
, bool,
335 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
336 chunk_t
*reason_string
, char **reason_language
)
338 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
342 *reason_language
= imv_lang_string_select_lang(language_enumerator
,
343 languages
, countof(languages
));
345 /* Instantiate a TNC Reason String object */
346 DESTROY_IF(this->reason_string
);
347 this->reason_string
= imv_reason_string_create(*reason_language
);
349 if (this->count_update
|| this->count_blacklist
)
351 this->reason_string
->add_reason(this->reason_string
, reason_packages
);
353 if (this->os_settings
)
355 this->reason_string
->add_reason(this->reason_string
, reason_settings
);
357 *reason_string
= this->reason_string
->get_encoding(this->reason_string
);
362 METHOD(imv_state_t
, get_remediation_instructions
, bool,
363 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
364 chunk_t
*string
, char **lang_code
, char **uri
)
366 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
370 *lang_code
= imv_lang_string_select_lang(language_enumerator
,
371 languages
, countof(languages
));
373 /* Instantiate an IETF Remediation Instructions String object */
374 DESTROY_IF(this->remediation_string
);
375 this->remediation_string
= imv_remediation_string_create(
376 this->type
== OS_TYPE_ANDROID
, *lang_code
);
378 /* List of blacklisted packages to be removed, if any */
379 if (this->count_blacklist
)
381 this->remediation_string
->add_instruction(this->remediation_string
,
382 instr_remove_packages_title
,
383 instr_remove_packages_descr
,
384 instr_remove_packages_header
,
385 this->remove_packages
);
388 /* List of packages in need of an update, if any */
389 if (this->count_update
)
391 this->remediation_string
->add_instruction(this->remediation_string
,
392 instr_update_packages_title
,
393 instr_update_packages_descr
,
394 instr_update_packages_header
,
395 this->update_packages
);
398 /* Add instructions concerning improper OS settings */
399 if (this->os_settings
& OS_SETTINGS_FWD_ENABLED
)
401 this->remediation_string
->add_instruction(this->remediation_string
,
402 instr_fwd_enabled_title
,
403 instr_fwd_enabled_descr
, NULL
, NULL
);
405 if (this->os_settings
& OS_SETTINGS_DEFAULT_PWD_ENABLED
)
407 this->remediation_string
->add_instruction(this->remediation_string
,
408 instr_default_pwd_enabled_title
,
409 instr_default_pwd_enabled_descr
, NULL
, NULL
);
411 if (this->os_settings
& OS_SETTINGS_NON_MARKET_APPS
)
413 this->remediation_string
->add_instruction(this->remediation_string
,
414 instr_non_market_apps_title
,
415 instr_non_market_apps_descr
, NULL
, NULL
);
418 *string
= this->remediation_string
->get_encoding(this->remediation_string
);
419 *uri
= lib
->settings
->get_str(lib
->settings
,
420 "libimcv.plugins.imv-os.remediation_uri", NULL
);
425 METHOD(imv_state_t
, destroy
, void,
426 private_imv_os_state_t
*this)
428 DESTROY_IF(this->reason_string
);
429 DESTROY_IF(this->remediation_string
);
430 this->update_packages
->destroy_function(this->update_packages
, free
);
431 this->remove_packages
->destroy_function(this->remove_packages
, free
);
433 free(this->name
.ptr
);
434 free(this->version
.ptr
);
438 METHOD(imv_os_state_t
, set_info
, void,
439 private_imv_os_state_t
*this, os_type_t type
, chunk_t name
, chunk_t version
)
441 int len
= name
.len
+ 1 + version
.len
+ 1;
443 /* OS info is a concatenation of OS name and OS version */
445 this->info
= malloc(len
);
446 snprintf(this->info
, len
, "%.*s %.*s", name
.len
, name
.ptr
,
447 version
.len
, version
.ptr
);
449 this->name
= chunk_clone(name
);
450 this->version
= chunk_clone(version
);
453 METHOD(imv_os_state_t
, get_info
, char*,
454 private_imv_os_state_t
*this, os_type_t
*type
, chunk_t
*name
,
467 *version
= this->version
;
472 METHOD(imv_os_state_t
, set_count
, void,
473 private_imv_os_state_t
*this, int count
, int count_update
,
474 int count_blacklist
, int count_ok
)
476 this->count
+= count
;
477 this->count_update
+= count_update
;
478 this->count_blacklist
+= count_blacklist
;
479 this->count_ok
+= count_ok
;
482 METHOD(imv_os_state_t
, get_count
, void,
483 private_imv_os_state_t
*this, int *count
, int *count_update
,
484 int *count_blacklist
, int *count_ok
)
488 *count
= this->count
;
492 *count_update
= this->count_update
;
496 *count_blacklist
= this->count_blacklist
;
500 *count_ok
= this->count_ok
;
504 METHOD(imv_os_state_t
, set_package_request
, void,
505 private_imv_os_state_t
*this, bool set
)
507 this->package_request
= set
;
510 METHOD(imv_os_state_t
, get_package_request
, bool,
511 private_imv_os_state_t
*this)
513 return this->package_request
;
516 METHOD(imv_os_state_t
, set_os_settings
, void,
517 private_imv_os_state_t
*this, u_int settings
)
519 this->os_settings
|= settings
;
522 METHOD(imv_os_state_t
, get_os_settings
, u_int
,
523 private_imv_os_state_t
*this)
525 return this->os_settings
;
528 METHOD(imv_os_state_t
, set_angel_count
, void,
529 private_imv_os_state_t
*this, bool start
)
531 this->angel_count
+= start ?
1 : -1;
534 METHOD(imv_os_state_t
, get_angel_count
, int,
535 private_imv_os_state_t
*this)
537 return this->angel_count
;
540 METHOD(imv_os_state_t
, add_bad_package
, void,
541 private_imv_os_state_t
*this, char *package
,
542 os_package_state_t package_state
)
544 package
= strdup(package
);
546 if (package_state
== OS_PACKAGE_STATE_BLACKLIST
)
548 this->remove_packages
->insert_last(this->remove_packages
, package
);
552 this->update_packages
->insert_last(this->update_packages
, package
);
557 * Described in header.
559 imv_state_t
*imv_os_state_create(TNC_ConnectionID connection_id
)
561 private_imv_os_state_t
*this;
566 .get_connection_id
= _get_connection_id
,
567 .has_long
= _has_long
,
568 .has_excl
= _has_excl
,
569 .set_flags
= _set_flags
,
570 .set_max_msg_len
= _set_max_msg_len
,
571 .get_max_msg_len
= _get_max_msg_len
,
572 .change_state
= _change_state
,
573 .get_recommendation
= _get_recommendation
,
574 .set_recommendation
= _set_recommendation
,
575 .get_reason_string
= _get_reason_string
,
576 .get_remediation_instructions
= _get_remediation_instructions
,
579 .set_info
= _set_info
,
580 .get_info
= _get_info
,
581 .set_count
= _set_count
,
582 .get_count
= _get_count
,
583 .set_package_request
= _set_package_request
,
584 .get_package_request
= _get_package_request
,
585 .set_os_settings
= _set_os_settings
,
586 .get_os_settings
= _get_os_settings
,
587 .set_angel_count
= _set_angel_count
,
588 .get_angel_count
= _get_angel_count
,
589 .add_bad_package
= _add_bad_package
,
591 .state
= TNC_CONNECTION_STATE_CREATE
,
592 .rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
,
593 .eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
,
594 .connection_id
= connection_id
,
595 .update_packages
= linked_list_create(),
596 .remove_packages
= linked_list_create(),
599 return &this->public.interface
;