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 * Primary database key of device ID
120 * Number of processed packages
125 * Number of not updated packages
130 * Number of blacklisted packages
135 * Number of whitelisted packages
140 * OS Installed Package request sent - mandatory response expected
142 bool package_request
;
157 * Supported languages
159 static char* languages
[] = { "en", "de", "pl" };
162 * Reason strings for "OS settings"
164 static imv_lang_string_t reason_settings
[] = {
165 { "en", "Improper OS settings were detected" },
166 { "de", "Unzulässige OS Einstellungen wurden festgestellt" },
167 { "pl", "Stwierdzono niewłaściwe ustawienia OS" },
172 * Reason strings for "installed software packages"
174 static imv_lang_string_t reason_packages
[] = {
175 { "en", "Vulnerable or blacklisted software packages were found" },
176 { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" },
177 { "pl", "Znaleziono pakiety podatne na atak lub będące na czarnej liście" },
182 * Instruction strings for "Software Security Updates"
184 static imv_lang_string_t instr_update_packages_title
[] = {
185 { "en", "Software Security Updates" },
186 { "de", "Software Sicherheitsupdates" },
187 { "pl", "Aktualizacja softwaru zabezpieczającego" },
191 static imv_lang_string_t instr_update_packages_descr
[] = {
192 { "en", "Packages with security vulnerabilities were found" },
193 { "de", "Softwarepakete mit Sicherheitsschwachstellen wurden gefunden" },
194 { "pl", "Znaleziono pakiety podatne na atak" },
198 static imv_lang_string_t instr_update_packages_header
[] = {
199 { "en", "Please update the following software packages:" },
200 { "de", "Bitte updaten Sie die folgenden Softwarepakete:" },
201 { "pl", "Proszę zaktualizować następujące pakiety:" },
206 * Instruction strings for "Blacklisted Software Packages"
208 static imv_lang_string_t instr_remove_packages_title
[] = {
209 { "en", "Blacklisted Software Packages" },
210 { "de", "Gesperrte Softwarepakete" },
211 { "pl", "Pakiety będące na czarnej liście" },
215 static imv_lang_string_t instr_remove_packages_descr
[] = {
216 { "en", "Dangerous software packages were found" },
217 { "de", "Gefährliche Softwarepakete wurden gefunden" },
218 { "pl", "Znaleziono niebezpieczne pakiety" },
222 static imv_lang_string_t instr_remove_packages_header
[] = {
223 { "en", "Please remove the following software packages:" },
224 { "de", "Bitte entfernen Sie die folgenden Softwarepakete:" },
225 { "pl", "Proszę usunąć następujące pakiety:" },
230 * Instruction strings for "Forwarding Enabled"
232 static imv_lang_string_t instr_fwd_enabled_title
[] = {
233 { "en", "IP Packet Forwarding" },
234 { "de", "Weiterleitung von IP Paketen" },
235 { "pl", "Przekazywanie pakietów IP" },
239 static imv_lang_string_t instr_fwd_enabled_descr
[] = {
240 { "en", "Please disable the forwarding of IP packets" },
241 { "de", "Bitte deaktivieren Sie das Forwarding von IP Paketen" },
242 { "pl", "Proszę zdezaktywować przekazywanie pakietów IP" },
247 * Instruction strings for "Default Password Enabled"
249 static imv_lang_string_t instr_default_pwd_enabled_title
[] = {
250 { "en", "Default Password" },
251 { "de", "Default Passwort" },
252 { "pl", "Hasło domyślne" },
256 static imv_lang_string_t instr_default_pwd_enabled_descr
[] = {
257 { "en", "Please change the default password" },
258 { "de", "Bitte ändern Sie das Default Passwort" },
259 { "pl", "Proszę zmienić domyślne hasło" },
264 * Instruction strings for "Install Non-Market Apps"
266 static imv_lang_string_t instr_non_market_apps_title
[] = {
267 { "en", "Unknown Software Origin" },
268 { "de", "Unbekannte Softwareherkunft" },
269 { "pl", "Nieznane pochodzenie softwaru" },
273 static imv_lang_string_t instr_non_market_apps_descr
[] = {
274 { "en", "Do not allow the installation of apps from unknown sources" },
275 { "de", "Erlauben Sie nicht die Installation von Apps aus unbekannten Quellen" },
276 { "pl", "Proszę nie dopuszczać do instalacji Apps z nieznanych źródeł" },
280 METHOD(imv_state_t
, get_connection_id
, TNC_ConnectionID
,
281 private_imv_os_state_t
*this)
283 return this->connection_id
;
286 METHOD(imv_state_t
, has_long
, bool,
287 private_imv_os_state_t
*this)
289 return this->has_long
;
292 METHOD(imv_state_t
, has_excl
, bool,
293 private_imv_os_state_t
*this)
295 return this->has_excl
;
298 METHOD(imv_state_t
, set_flags
, void,
299 private_imv_os_state_t
*this, bool has_long
, bool has_excl
)
301 this->has_long
= has_long
;
302 this->has_excl
= has_excl
;
305 METHOD(imv_state_t
, set_max_msg_len
, void,
306 private_imv_os_state_t
*this, u_int32_t max_msg_len
)
308 this->max_msg_len
= max_msg_len
;
311 METHOD(imv_state_t
, get_max_msg_len
, u_int32_t
,
312 private_imv_os_state_t
*this)
314 return this->max_msg_len
;
317 METHOD(imv_state_t
, change_state
, void,
318 private_imv_os_state_t
*this, TNC_ConnectionState new_state
)
320 this->state
= new_state
;
323 METHOD(imv_state_t
, get_recommendation
, void,
324 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation
*rec
,
325 TNC_IMV_Evaluation_Result
*eval
)
331 METHOD(imv_state_t
, set_recommendation
, void,
332 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation rec
,
333 TNC_IMV_Evaluation_Result eval
)
339 METHOD(imv_state_t
, get_reason_string
, bool,
340 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
341 chunk_t
*reason_string
, char **reason_language
)
343 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
347 *reason_language
= imv_lang_string_select_lang(language_enumerator
,
348 languages
, countof(languages
));
350 /* Instantiate a TNC Reason String object */
351 DESTROY_IF(this->reason_string
);
352 this->reason_string
= imv_reason_string_create(*reason_language
);
354 if (this->count_update
|| this->count_blacklist
)
356 this->reason_string
->add_reason(this->reason_string
, reason_packages
);
358 if (this->os_settings
)
360 this->reason_string
->add_reason(this->reason_string
, reason_settings
);
362 *reason_string
= this->reason_string
->get_encoding(this->reason_string
);
367 METHOD(imv_state_t
, get_remediation_instructions
, bool,
368 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
369 chunk_t
*string
, char **lang_code
, char **uri
)
371 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
375 *lang_code
= imv_lang_string_select_lang(language_enumerator
,
376 languages
, countof(languages
));
378 /* Instantiate an IETF Remediation Instructions String object */
379 DESTROY_IF(this->remediation_string
);
380 this->remediation_string
= imv_remediation_string_create(
381 this->type
== OS_TYPE_ANDROID
, *lang_code
);
383 /* List of blacklisted packages to be removed, if any */
384 if (this->count_blacklist
)
386 this->remediation_string
->add_instruction(this->remediation_string
,
387 instr_remove_packages_title
,
388 instr_remove_packages_descr
,
389 instr_remove_packages_header
,
390 this->remove_packages
);
393 /* List of packages in need of an update, if any */
394 if (this->count_update
)
396 this->remediation_string
->add_instruction(this->remediation_string
,
397 instr_update_packages_title
,
398 instr_update_packages_descr
,
399 instr_update_packages_header
,
400 this->update_packages
);
403 /* Add instructions concerning improper OS settings */
404 if (this->os_settings
& OS_SETTINGS_FWD_ENABLED
)
406 this->remediation_string
->add_instruction(this->remediation_string
,
407 instr_fwd_enabled_title
,
408 instr_fwd_enabled_descr
, NULL
, NULL
);
410 if (this->os_settings
& OS_SETTINGS_DEFAULT_PWD_ENABLED
)
412 this->remediation_string
->add_instruction(this->remediation_string
,
413 instr_default_pwd_enabled_title
,
414 instr_default_pwd_enabled_descr
, NULL
, NULL
);
416 if (this->os_settings
& OS_SETTINGS_NON_MARKET_APPS
)
418 this->remediation_string
->add_instruction(this->remediation_string
,
419 instr_non_market_apps_title
,
420 instr_non_market_apps_descr
, NULL
, NULL
);
423 *string
= this->remediation_string
->get_encoding(this->remediation_string
);
424 *uri
= lib
->settings
->get_str(lib
->settings
,
425 "libimcv.plugins.imv-os.remediation_uri", NULL
);
430 METHOD(imv_state_t
, destroy
, void,
431 private_imv_os_state_t
*this)
433 DESTROY_IF(this->reason_string
);
434 DESTROY_IF(this->remediation_string
);
435 this->update_packages
->destroy_function(this->update_packages
, free
);
436 this->remove_packages
->destroy_function(this->remove_packages
, free
);
438 free(this->name
.ptr
);
439 free(this->version
.ptr
);
443 METHOD(imv_os_state_t
, set_info
, void,
444 private_imv_os_state_t
*this, os_type_t type
, chunk_t name
, chunk_t version
)
446 int len
= name
.len
+ 1 + version
.len
+ 1;
448 /* OS info is a concatenation of OS name and OS version */
450 this->info
= malloc(len
);
451 snprintf(this->info
, len
, "%.*s %.*s", name
.len
, name
.ptr
,
452 version
.len
, version
.ptr
);
454 this->name
= chunk_clone(name
);
455 this->version
= chunk_clone(version
);
458 METHOD(imv_os_state_t
, get_info
, char*,
459 private_imv_os_state_t
*this, os_type_t
*type
, chunk_t
*name
,
472 *version
= this->version
;
477 METHOD(imv_os_state_t
, set_count
, void,
478 private_imv_os_state_t
*this, int count
, int count_update
,
479 int count_blacklist
, int count_ok
)
481 this->count
+= count
;
482 this->count_update
+= count_update
;
483 this->count_blacklist
+= count_blacklist
;
484 this->count_ok
+= count_ok
;
487 METHOD(imv_os_state_t
, get_count
, void,
488 private_imv_os_state_t
*this, int *count
, int *count_update
,
489 int *count_blacklist
, int *count_ok
)
493 *count
= this->count
;
497 *count_update
= this->count_update
;
501 *count_blacklist
= this->count_blacklist
;
505 *count_ok
= this->count_ok
;
509 METHOD(imv_os_state_t
, set_package_request
, void,
510 private_imv_os_state_t
*this, bool set
)
512 this->package_request
= set
;
515 METHOD(imv_os_state_t
, get_package_request
, bool,
516 private_imv_os_state_t
*this)
518 return this->package_request
;
521 METHOD(imv_os_state_t
, set_device_id
, void,
522 private_imv_os_state_t
*this, int id
)
524 this->device_id
= id
;
527 METHOD(imv_os_state_t
, get_device_id
, int,
528 private_imv_os_state_t
*this)
530 return this->device_id
;
533 METHOD(imv_os_state_t
, set_os_settings
, void,
534 private_imv_os_state_t
*this, u_int settings
)
536 this->os_settings
|= settings
;
539 METHOD(imv_os_state_t
, get_os_settings
, u_int
,
540 private_imv_os_state_t
*this)
542 return this->os_settings
;
545 METHOD(imv_os_state_t
, set_angel_count
, void,
546 private_imv_os_state_t
*this, bool start
)
548 this->angel_count
+= start ?
1 : -1;
551 METHOD(imv_os_state_t
, get_angel_count
, int,
552 private_imv_os_state_t
*this)
554 return this->angel_count
;
557 METHOD(imv_os_state_t
, add_bad_package
, void,
558 private_imv_os_state_t
*this, char *package
,
559 os_package_state_t package_state
)
561 package
= strdup(package
);
563 if (package_state
== OS_PACKAGE_STATE_BLACKLIST
)
565 this->remove_packages
->insert_last(this->remove_packages
, package
);
569 this->update_packages
->insert_last(this->update_packages
, package
);
574 * Described in header.
576 imv_state_t
*imv_os_state_create(TNC_ConnectionID connection_id
)
578 private_imv_os_state_t
*this;
583 .get_connection_id
= _get_connection_id
,
584 .has_long
= _has_long
,
585 .has_excl
= _has_excl
,
586 .set_flags
= _set_flags
,
587 .set_max_msg_len
= _set_max_msg_len
,
588 .get_max_msg_len
= _get_max_msg_len
,
589 .change_state
= _change_state
,
590 .get_recommendation
= _get_recommendation
,
591 .set_recommendation
= _set_recommendation
,
592 .get_reason_string
= _get_reason_string
,
593 .get_remediation_instructions
= _get_remediation_instructions
,
596 .set_info
= _set_info
,
597 .get_info
= _get_info
,
598 .set_count
= _set_count
,
599 .get_count
= _get_count
,
600 .set_package_request
= _set_package_request
,
601 .get_package_request
= _get_package_request
,
602 .set_device_id
= _set_device_id
,
603 .get_device_id
= _get_device_id
,
604 .set_os_settings
= _set_os_settings
,
605 .get_os_settings
= _get_os_settings
,
606 .set_angel_count
= _set_angel_count
,
607 .get_angel_count
= _get_angel_count
,
608 .add_bad_package
= _add_bad_package
,
610 .state
= TNC_CONNECTION_STATE_CREATE
,
611 .rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
,
612 .eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
,
613 .connection_id
= connection_id
,
614 .update_packages
= linked_list_create(),
615 .remove_packages
= linked_list_create(),
618 return &this->public.interface
;