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 * Attribute request sent - mandatory response expected
142 bool attribute_request
;
145 * OS Installed Package request sent - mandatory response expected
147 bool package_request
;
162 * Supported languages
164 static char* languages
[] = { "en", "de", "pl" };
167 * Reason strings for "OS settings"
169 static imv_lang_string_t reason_settings
[] = {
170 { "en", "Improper OS settings were detected" },
171 { "de", "Unzulässige OS Einstellungen wurden festgestellt" },
172 { "pl", "Stwierdzono niewłaściwe ustawienia OS" },
177 * Reason strings for "installed software packages"
179 static imv_lang_string_t reason_packages
[] = {
180 { "en", "Vulnerable or blacklisted software packages were found" },
181 { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" },
182 { "pl", "Znaleziono pakiety podatne na atak lub będące na czarnej liście" },
187 * Instruction strings for "Software Security Updates"
189 static imv_lang_string_t instr_update_packages_title
[] = {
190 { "en", "Software Security Updates" },
191 { "de", "Software Sicherheitsupdates" },
192 { "pl", "Aktualizacja softwaru zabezpieczającego" },
196 static imv_lang_string_t instr_update_packages_descr
[] = {
197 { "en", "Packages with security vulnerabilities were found" },
198 { "de", "Softwarepakete mit Sicherheitsschwachstellen wurden gefunden" },
199 { "pl", "Znaleziono pakiety podatne na atak" },
203 static imv_lang_string_t instr_update_packages_header
[] = {
204 { "en", "Please update the following software packages:" },
205 { "de", "Bitte updaten Sie die folgenden Softwarepakete:" },
206 { "pl", "Proszę zaktualizować następujące pakiety:" },
211 * Instruction strings for "Blacklisted Software Packages"
213 static imv_lang_string_t instr_remove_packages_title
[] = {
214 { "en", "Blacklisted Software Packages" },
215 { "de", "Gesperrte Softwarepakete" },
216 { "pl", "Pakiety będące na czarnej liście" },
220 static imv_lang_string_t instr_remove_packages_descr
[] = {
221 { "en", "Dangerous software packages were found" },
222 { "de", "Gefährliche Softwarepakete wurden gefunden" },
223 { "pl", "Znaleziono niebezpieczne pakiety" },
227 static imv_lang_string_t instr_remove_packages_header
[] = {
228 { "en", "Please remove the following software packages:" },
229 { "de", "Bitte entfernen Sie die folgenden Softwarepakete:" },
230 { "pl", "Proszę usunąć następujące pakiety:" },
235 * Instruction strings for "Forwarding Enabled"
237 static imv_lang_string_t instr_fwd_enabled_title
[] = {
238 { "en", "IP Packet Forwarding" },
239 { "de", "Weiterleitung von IP Paketen" },
240 { "pl", "Przekazywanie pakietów IP" },
244 static imv_lang_string_t instr_fwd_enabled_descr
[] = {
245 { "en", "Please disable the forwarding of IP packets" },
246 { "de", "Bitte deaktivieren Sie das Forwarding von IP Paketen" },
247 { "pl", "Proszę zdezaktywować przekazywanie pakietów IP" },
252 * Instruction strings for "Default Password Enabled"
254 static imv_lang_string_t instr_default_pwd_enabled_title
[] = {
255 { "en", "Default Password" },
256 { "de", "Default Passwort" },
257 { "pl", "Hasło domyślne" },
261 static imv_lang_string_t instr_default_pwd_enabled_descr
[] = {
262 { "en", "Please change the default password" },
263 { "de", "Bitte ändern Sie das Default Passwort" },
264 { "pl", "Proszę zmienić domyślne hasło" },
269 * Instruction strings for "Install Non-Market Apps"
271 static imv_lang_string_t instr_non_market_apps_title
[] = {
272 { "en", "Unknown Software Origin" },
273 { "de", "Unbekannte Softwareherkunft" },
274 { "pl", "Nieznane pochodzenie softwaru" },
278 static imv_lang_string_t instr_non_market_apps_descr
[] = {
279 { "en", "Do not allow the installation of apps from unknown sources" },
280 { "de", "Erlauben Sie nicht die Installation von Apps aus unbekannten Quellen" },
281 { "pl", "Proszę nie dopuszczać do instalacji Apps z nieznanych źródeł" },
285 METHOD(imv_state_t
, get_connection_id
, TNC_ConnectionID
,
286 private_imv_os_state_t
*this)
288 return this->connection_id
;
291 METHOD(imv_state_t
, has_long
, bool,
292 private_imv_os_state_t
*this)
294 return this->has_long
;
297 METHOD(imv_state_t
, has_excl
, bool,
298 private_imv_os_state_t
*this)
300 return this->has_excl
;
303 METHOD(imv_state_t
, set_flags
, void,
304 private_imv_os_state_t
*this, bool has_long
, bool has_excl
)
306 this->has_long
= has_long
;
307 this->has_excl
= has_excl
;
310 METHOD(imv_state_t
, set_max_msg_len
, void,
311 private_imv_os_state_t
*this, u_int32_t max_msg_len
)
313 this->max_msg_len
= max_msg_len
;
316 METHOD(imv_state_t
, get_max_msg_len
, u_int32_t
,
317 private_imv_os_state_t
*this)
319 return this->max_msg_len
;
322 METHOD(imv_state_t
, change_state
, void,
323 private_imv_os_state_t
*this, TNC_ConnectionState new_state
)
325 this->state
= new_state
;
328 METHOD(imv_state_t
, get_recommendation
, void,
329 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation
*rec
,
330 TNC_IMV_Evaluation_Result
*eval
)
336 METHOD(imv_state_t
, set_recommendation
, void,
337 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation rec
,
338 TNC_IMV_Evaluation_Result eval
)
344 METHOD(imv_state_t
, get_reason_string
, bool,
345 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
346 chunk_t
*reason_string
, char **reason_language
)
348 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
352 *reason_language
= imv_lang_string_select_lang(language_enumerator
,
353 languages
, countof(languages
));
355 /* Instantiate a TNC Reason String object */
356 DESTROY_IF(this->reason_string
);
357 this->reason_string
= imv_reason_string_create(*reason_language
);
359 if (this->count_update
|| this->count_blacklist
)
361 this->reason_string
->add_reason(this->reason_string
, reason_packages
);
363 if (this->os_settings
)
365 this->reason_string
->add_reason(this->reason_string
, reason_settings
);
367 *reason_string
= this->reason_string
->get_encoding(this->reason_string
);
372 METHOD(imv_state_t
, get_remediation_instructions
, bool,
373 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
374 chunk_t
*string
, char **lang_code
, char **uri
)
376 if (!this->count_update
&& !this->count_blacklist
& !this->os_settings
)
380 *lang_code
= imv_lang_string_select_lang(language_enumerator
,
381 languages
, countof(languages
));
383 /* Instantiate an IETF Remediation Instructions String object */
384 DESTROY_IF(this->remediation_string
);
385 this->remediation_string
= imv_remediation_string_create(
386 this->type
== OS_TYPE_ANDROID
, *lang_code
);
388 /* List of blacklisted packages to be removed, if any */
389 if (this->count_blacklist
)
391 this->remediation_string
->add_instruction(this->remediation_string
,
392 instr_remove_packages_title
,
393 instr_remove_packages_descr
,
394 instr_remove_packages_header
,
395 this->remove_packages
);
398 /* List of packages in need of an update, if any */
399 if (this->count_update
)
401 this->remediation_string
->add_instruction(this->remediation_string
,
402 instr_update_packages_title
,
403 instr_update_packages_descr
,
404 instr_update_packages_header
,
405 this->update_packages
);
408 /* Add instructions concerning improper OS settings */
409 if (this->os_settings
& OS_SETTINGS_FWD_ENABLED
)
411 this->remediation_string
->add_instruction(this->remediation_string
,
412 instr_fwd_enabled_title
,
413 instr_fwd_enabled_descr
, NULL
, NULL
);
415 if (this->os_settings
& OS_SETTINGS_DEFAULT_PWD_ENABLED
)
417 this->remediation_string
->add_instruction(this->remediation_string
,
418 instr_default_pwd_enabled_title
,
419 instr_default_pwd_enabled_descr
, NULL
, NULL
);
421 if (this->os_settings
& OS_SETTINGS_NON_MARKET_APPS
)
423 this->remediation_string
->add_instruction(this->remediation_string
,
424 instr_non_market_apps_title
,
425 instr_non_market_apps_descr
, NULL
, NULL
);
428 *string
= this->remediation_string
->get_encoding(this->remediation_string
);
429 *uri
= lib
->settings
->get_str(lib
->settings
,
430 "libimcv.plugins.imv-os.remediation_uri", NULL
);
435 METHOD(imv_state_t
, destroy
, void,
436 private_imv_os_state_t
*this)
438 DESTROY_IF(this->reason_string
);
439 DESTROY_IF(this->remediation_string
);
440 this->update_packages
->destroy_function(this->update_packages
, free
);
441 this->remove_packages
->destroy_function(this->remove_packages
, free
);
443 free(this->name
.ptr
);
444 free(this->version
.ptr
);
448 METHOD(imv_os_state_t
, set_info
, void,
449 private_imv_os_state_t
*this, os_type_t type
, chunk_t name
, chunk_t version
)
451 int len
= name
.len
+ 1 + version
.len
+ 1;
453 /* OS info is a concatenation of OS name and OS version */
455 this->info
= malloc(len
);
456 snprintf(this->info
, len
, "%.*s %.*s", (int)name
.len
, name
.ptr
,
457 (int)version
.len
, version
.ptr
);
459 this->name
= chunk_clone(name
);
460 this->version
= chunk_clone(version
);
463 METHOD(imv_os_state_t
, get_info
, char*,
464 private_imv_os_state_t
*this, os_type_t
*type
, chunk_t
*name
,
477 *version
= this->version
;
482 METHOD(imv_os_state_t
, set_count
, void,
483 private_imv_os_state_t
*this, int count
, int count_update
,
484 int count_blacklist
, int count_ok
)
486 this->count
+= count
;
487 this->count_update
+= count_update
;
488 this->count_blacklist
+= count_blacklist
;
489 this->count_ok
+= count_ok
;
492 METHOD(imv_os_state_t
, get_count
, void,
493 private_imv_os_state_t
*this, int *count
, int *count_update
,
494 int *count_blacklist
, int *count_ok
)
498 *count
= this->count
;
502 *count_update
= this->count_update
;
506 *count_blacklist
= this->count_blacklist
;
510 *count_ok
= this->count_ok
;
514 METHOD(imv_os_state_t
, set_attribute_request
, void,
515 private_imv_os_state_t
*this, bool set
)
517 this->attribute_request
= set
;
520 METHOD(imv_os_state_t
, get_attribute_request
, bool,
521 private_imv_os_state_t
*this)
523 return this->attribute_request
;
526 METHOD(imv_os_state_t
, set_package_request
, void,
527 private_imv_os_state_t
*this, bool set
)
529 this->package_request
= set
;
532 METHOD(imv_os_state_t
, get_package_request
, bool,
533 private_imv_os_state_t
*this)
535 return this->package_request
;
538 METHOD(imv_os_state_t
, set_device_id
, void,
539 private_imv_os_state_t
*this, int id
)
541 this->device_id
= id
;
544 METHOD(imv_os_state_t
, get_device_id
, int,
545 private_imv_os_state_t
*this)
547 return this->device_id
;
550 METHOD(imv_os_state_t
, set_os_settings
, void,
551 private_imv_os_state_t
*this, u_int settings
)
553 this->os_settings
|= settings
;
556 METHOD(imv_os_state_t
, get_os_settings
, u_int
,
557 private_imv_os_state_t
*this)
559 return this->os_settings
;
562 METHOD(imv_os_state_t
, set_angel_count
, void,
563 private_imv_os_state_t
*this, bool start
)
565 this->angel_count
+= start ?
1 : -1;
568 METHOD(imv_os_state_t
, get_angel_count
, int,
569 private_imv_os_state_t
*this)
571 return this->angel_count
;
574 METHOD(imv_os_state_t
, add_bad_package
, void,
575 private_imv_os_state_t
*this, char *package
,
576 os_package_state_t package_state
)
578 package
= strdup(package
);
580 if (package_state
== OS_PACKAGE_STATE_BLACKLIST
)
582 this->remove_packages
->insert_last(this->remove_packages
, package
);
586 this->update_packages
->insert_last(this->update_packages
, package
);
591 * Described in header.
593 imv_state_t
*imv_os_state_create(TNC_ConnectionID connection_id
)
595 private_imv_os_state_t
*this;
600 .get_connection_id
= _get_connection_id
,
601 .has_long
= _has_long
,
602 .has_excl
= _has_excl
,
603 .set_flags
= _set_flags
,
604 .set_max_msg_len
= _set_max_msg_len
,
605 .get_max_msg_len
= _get_max_msg_len
,
606 .change_state
= _change_state
,
607 .get_recommendation
= _get_recommendation
,
608 .set_recommendation
= _set_recommendation
,
609 .get_reason_string
= _get_reason_string
,
610 .get_remediation_instructions
= _get_remediation_instructions
,
613 .set_info
= _set_info
,
614 .get_info
= _get_info
,
615 .set_count
= _set_count
,
616 .get_count
= _get_count
,
617 .set_attribute_request
= _set_attribute_request
,
618 .get_attribute_request
= _get_attribute_request
,
619 .set_package_request
= _set_package_request
,
620 .get_package_request
= _get_package_request
,
621 .set_device_id
= _set_device_id
,
622 .get_device_id
= _get_device_id
,
623 .set_os_settings
= _set_os_settings
,
624 .get_os_settings
= _get_os_settings
,
625 .set_angel_count
= _set_angel_count
,
626 .get_angel_count
= _get_angel_count
,
627 .add_bad_package
= _add_bad_package
,
629 .state
= TNC_CONNECTION_STATE_CREATE
,
630 .rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
,
631 .eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
,
632 .connection_id
= connection_id
,
633 .update_packages
= linked_list_create(),
634 .remove_packages
= linked_list_create(),
637 return &this->public.interface
;