2 * Copyright (C) 2012-2017 Andreas Steffen
4 * Copyright (C) secunet Security Networks AG
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "imv_os_state.h"
19 #include "imv/imv_lang_string.h"
20 #include "imv/imv_reason_string.h"
21 #include "imv/imv_remediation_string.h"
22 #include "imv/imv_os_info.h"
24 #include <tncif_policy.h>
26 #include <utils/debug.h>
27 #include <collections/linked_list.h>
29 typedef struct private_imv_os_state_t private_imv_os_state_t
;
30 typedef struct package_entry_t package_entry_t
;
31 typedef struct entry_t entry_t
;
32 typedef struct instruction_entry_t instruction_entry_t
;
35 * Private data of an imv_os_state_t object.
37 struct private_imv_os_state_t
{
40 * Public members of imv_os_state_t
42 imv_os_state_t
public;
47 TNC_ConnectionID connection_id
;
50 * TNCCS connection state
52 TNC_ConnectionState state
;
55 * Does the TNCCS connection support long message types?
60 * Does the TNCCS connection support exclusive delivery?
65 * Maximum PA-TNC message size for this TNCCS connection
70 * Flags set for completed actions
72 uint32_t action_flags
;
75 * IMV database session associated with TNCCS connection
77 imv_session_t
*session
;
80 * PA-TNC attribute segmentation contracts associated with TNCCS connection
82 seg_contract_manager_t
*contracts
;
85 * IMV action recommendation
87 TNC_IMV_Action_Recommendation rec
;
90 * IMV evaluation result
92 TNC_IMV_Evaluation_Result eval
;
95 * IMV OS handshake state
97 imv_os_handshake_state_t handshake_state
;
100 * List of blacklisted packages to be removed
102 linked_list_t
*remove_packages
;
105 h* List of vulnerable packages to be updated
107 linked_list_t
*update_packages
;
112 imv_reason_string_t
*reason_string
;
115 * IETF Remediation Instructions String
117 imv_remediation_string_t
*remediation_string
;
120 * Number of processed packages
125 * Number of vulnerable packages
130 * Number of blacklisted packages
135 * Number of whitelisted packages
145 * Number of installed packages still missing
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 "Unknown Source"
261 static imv_lang_string_t instr_unknown_source_title
[] = {
262 { "en", "Unknown Software Origin" },
263 { "de", "Unbekannte Softwareherkunft" },
264 { "pl", "Nieznane pochodzenie softwaru" },
268 static imv_lang_string_t instr_unknown_source_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, uint32_t max_msg_len
)
303 this->max_msg_len
= max_msg_len
;
306 METHOD(imv_state_t
, get_max_msg_len
, uint32_t,
307 private_imv_os_state_t
*this)
309 return this->max_msg_len
;
312 METHOD(imv_state_t
, set_action_flags
, void,
313 private_imv_os_state_t
*this, uint32_t flags
)
315 this->action_flags
|= flags
;
318 METHOD(imv_state_t
, get_action_flags
, uint32_t,
319 private_imv_os_state_t
*this)
321 return this->action_flags
;
324 METHOD(imv_state_t
, set_session
, void,
325 private_imv_os_state_t
*this, imv_session_t
*session
)
327 this->session
= session
;
330 METHOD(imv_state_t
, get_session
, imv_session_t
*,
331 private_imv_os_state_t
*this)
333 return this->session
;
336 METHOD(imv_state_t
, get_contracts
, seg_contract_manager_t
*,
337 private_imv_os_state_t
*this)
339 return this->contracts
;
342 METHOD(imv_state_t
, get_recommendation
, void,
343 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation
*rec
,
344 TNC_IMV_Evaluation_Result
*eval
)
350 METHOD(imv_state_t
, set_recommendation
, void,
351 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation rec
,
352 TNC_IMV_Evaluation_Result eval
)
358 METHOD(imv_state_t
, update_recommendation
, void,
359 private_imv_os_state_t
*this, TNC_IMV_Action_Recommendation rec
,
360 TNC_IMV_Evaluation_Result eval
)
362 this->rec
= tncif_policy_update_recommendation(this->rec
, rec
);
363 this->eval
= tncif_policy_update_evaluation(this->eval
, eval
);
366 METHOD(imv_state_t
, change_state
, TNC_ConnectionState
,
367 private_imv_os_state_t
*this, TNC_ConnectionState new_state
)
369 TNC_ConnectionState old_state
;
371 old_state
= this->state
;
372 this->state
= new_state
;
376 METHOD(imv_state_t
, get_reason_string
, bool,
377 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
378 chunk_t
*reason_string
, char **reason_language
)
380 if (!this->count_security
&& !this->count_blacklist
& !this->os_settings
)
384 *reason_language
= imv_lang_string_select_lang(language_enumerator
,
385 languages
, countof(languages
));
387 /* Instantiate a TNC Reason String object */
388 DESTROY_IF(this->reason_string
);
389 this->reason_string
= imv_reason_string_create(*reason_language
, "\n");
391 if (this->count_security
|| this->count_blacklist
)
393 this->reason_string
->add_reason(this->reason_string
, reason_packages
);
395 if (this->os_settings
)
397 this->reason_string
->add_reason(this->reason_string
, reason_settings
);
399 *reason_string
= this->reason_string
->get_encoding(this->reason_string
);
404 METHOD(imv_state_t
, get_remediation_instructions
, bool,
405 private_imv_os_state_t
*this, enumerator_t
*language_enumerator
,
406 chunk_t
*string
, char **lang_code
, char **uri
)
408 imv_os_info_t
*os_info
;
411 if (!this->count_security
&& !this->count_blacklist
& !this->os_settings
)
415 *lang_code
= imv_lang_string_select_lang(language_enumerator
,
416 languages
, countof(languages
));
418 /* Instantiate an IETF Remediation Instructions String object */
419 DESTROY_IF(this->remediation_string
);
422 os_info
= this->session
->get_os_info(this->session
);
423 as_xml
= os_info
->get_type(os_info
) == OS_TYPE_ANDROID
;
425 this->remediation_string
= imv_remediation_string_create(as_xml
, *lang_code
);
427 /* List of blacklisted packages to be removed, if any */
428 if (this->count_blacklist
)
430 this->remediation_string
->add_instruction(this->remediation_string
,
431 instr_remove_packages_title
,
432 instr_remove_packages_descr
,
433 instr_remove_packages_header
,
434 this->remove_packages
);
437 /* List of packages in need of an update, if any */
438 if (this->count_security
)
440 this->remediation_string
->add_instruction(this->remediation_string
,
441 instr_update_packages_title
,
442 instr_update_packages_descr
,
443 instr_update_packages_header
,
444 this->update_packages
);
447 /* Add instructions concerning improper OS settings */
448 if (this->os_settings
& OS_SETTINGS_FWD_ENABLED
)
450 this->remediation_string
->add_instruction(this->remediation_string
,
451 instr_fwd_enabled_title
,
452 instr_fwd_enabled_descr
, NULL
, NULL
);
454 if (this->os_settings
& OS_SETTINGS_DEFAULT_PWD_ENABLED
)
456 this->remediation_string
->add_instruction(this->remediation_string
,
457 instr_default_pwd_enabled_title
,
458 instr_default_pwd_enabled_descr
, NULL
, NULL
);
460 if (this->os_settings
& OS_SETTINGS_UNKNOWN_SOURCE
)
462 this->remediation_string
->add_instruction(this->remediation_string
,
463 instr_unknown_source_title
,
464 instr_unknown_source_descr
, NULL
, NULL
);
467 *string
= this->remediation_string
->get_encoding(this->remediation_string
);
468 *uri
= lib
->settings
->get_str(lib
->settings
,
469 "%s.plugins.imv-os.remediation_uri", NULL
, lib
->ns
);
474 METHOD(imv_state_t
, reset
, void,
475 private_imv_os_state_t
*this)
477 DESTROY_IF(this->reason_string
);
478 DESTROY_IF(this->remediation_string
);
479 this->reason_string
= NULL
;
480 this->remediation_string
= NULL
;
481 this->rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
;
482 this->eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
;
484 this->action_flags
= 0;
486 this->handshake_state
= IMV_OS_STATE_INIT
;
488 this->count_security
= 0;
489 this->count_blacklist
= 0;
491 this->os_settings
= 0;
494 this->update_packages
->destroy_function(this->update_packages
, free
);
495 this->remove_packages
->destroy_function(this->remove_packages
, free
);
496 this->update_packages
= linked_list_create();
497 this->remove_packages
= linked_list_create();
500 METHOD(imv_state_t
, destroy
, void,
501 private_imv_os_state_t
*this)
503 DESTROY_IF(this->session
);
504 DESTROY_IF(this->reason_string
);
505 DESTROY_IF(this->remediation_string
);
506 this->contracts
->destroy(this->contracts
);
507 this->update_packages
->destroy_function(this->update_packages
, free
);
508 this->remove_packages
->destroy_function(this->remove_packages
, free
);
512 METHOD(imv_os_state_t
, set_handshake_state
, void,
513 private_imv_os_state_t
*this, imv_os_handshake_state_t new_state
)
515 this->handshake_state
= new_state
;
518 METHOD(imv_os_state_t
, get_handshake_state
, imv_os_handshake_state_t
,
519 private_imv_os_state_t
*this)
521 return this->handshake_state
;
525 METHOD(imv_os_state_t
, set_count
, void,
526 private_imv_os_state_t
*this, int count
, int count_security
,
527 int count_blacklist
, int count_ok
)
529 this->count
+= count
;
530 this->count_security
+= count_security
;
531 this->count_blacklist
+= count_blacklist
;
532 this->count_ok
+= count_ok
;
535 METHOD(imv_os_state_t
, get_count
, void,
536 private_imv_os_state_t
*this, int *count
, int *count_security
,
537 int *count_blacklist
, int *count_ok
)
541 *count
= this->count
;
545 *count_security
= this->count_security
;
549 *count_blacklist
= this->count_blacklist
;
553 *count_ok
= this->count_ok
;
557 METHOD(imv_os_state_t
, set_os_settings
, void,
558 private_imv_os_state_t
*this, u_int settings
)
560 this->os_settings
|= settings
;
563 METHOD(imv_os_state_t
, get_os_settings
, u_int
,
564 private_imv_os_state_t
*this)
566 return this->os_settings
;
569 METHOD(imv_os_state_t
, set_missing
, void,
570 private_imv_os_state_t
*this, uint16_t missing
)
572 this->missing
= missing
;
575 METHOD(imv_os_state_t
, get_missing
, uint16_t,
576 private_imv_os_state_t
*this)
578 return this->missing
;
581 METHOD(imv_os_state_t
, add_bad_package
, void,
582 private_imv_os_state_t
*this, char *package
,
583 os_package_state_t package_state
)
585 package
= strdup(package
);
587 if (package_state
== OS_PACKAGE_STATE_BLACKLIST
)
589 this->remove_packages
->insert_last(this->remove_packages
, package
);
593 this->update_packages
->insert_last(this->update_packages
, package
);
598 * Described in header.
600 imv_state_t
*imv_os_state_create(TNC_ConnectionID connection_id
)
602 private_imv_os_state_t
*this;
607 .get_connection_id
= _get_connection_id
,
608 .has_long
= _has_long
,
609 .has_excl
= _has_excl
,
610 .set_flags
= _set_flags
,
611 .set_max_msg_len
= _set_max_msg_len
,
612 .get_max_msg_len
= _get_max_msg_len
,
613 .set_action_flags
= _set_action_flags
,
614 .get_action_flags
= _get_action_flags
,
615 .set_session
= _set_session
,
616 .get_session
= _get_session
,
617 .get_contracts
= _get_contracts
,
618 .change_state
= _change_state
,
619 .get_recommendation
= _get_recommendation
,
620 .set_recommendation
= _set_recommendation
,
621 .update_recommendation
= _update_recommendation
,
622 .get_reason_string
= _get_reason_string
,
623 .get_remediation_instructions
= _get_remediation_instructions
,
627 .set_handshake_state
= _set_handshake_state
,
628 .get_handshake_state
= _get_handshake_state
,
629 .set_count
= _set_count
,
630 .get_count
= _get_count
,
631 .set_os_settings
= _set_os_settings
,
632 .get_os_settings
= _get_os_settings
,
633 .set_missing
= _set_missing
,
634 .get_missing
= _get_missing
,
635 .add_bad_package
= _add_bad_package
,
637 .state
= TNC_CONNECTION_STATE_CREATE
,
638 .rec
= TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION
,
639 .eval
= TNC_IMV_EVALUATION_RESULT_DONT_KNOW
,
640 .connection_id
= connection_id
,
641 .contracts
= seg_contract_manager_create(),
642 .update_packages
= linked_list_create(),
643 .remove_packages
= linked_list_create(),
646 return &this->public.interface
;