]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libimcv/plugins/imv_os/imv_os_state.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libimcv / plugins / imv_os / imv_os_state.c
1 /*
2 * Copyright (C) 2012-2017 Andreas Steffen
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
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>.
10 *
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
14 * for more details.
15 */
16
17 #include "imv_os_state.h"
18
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"
23
24 #include <tncif_policy.h>
25
26 #include <utils/debug.h>
27 #include <collections/linked_list.h>
28
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;
33
34 /**
35 * Private data of an imv_os_state_t object.
36 */
37 struct private_imv_os_state_t {
38
39 /**
40 * Public members of imv_os_state_t
41 */
42 imv_os_state_t public;
43
44 /**
45 * TNCCS connection ID
46 */
47 TNC_ConnectionID connection_id;
48
49 /**
50 * TNCCS connection state
51 */
52 TNC_ConnectionState state;
53
54 /**
55 * Does the TNCCS connection support long message types?
56 */
57 bool has_long;
58
59 /**
60 * Does the TNCCS connection support exclusive delivery?
61 */
62 bool has_excl;
63
64 /**
65 * Maximum PA-TNC message size for this TNCCS connection
66 */
67 uint32_t max_msg_len;
68
69 /**
70 * Flags set for completed actions
71 */
72 uint32_t action_flags;
73
74 /**
75 * IMV database session associated with TNCCS connection
76 */
77 imv_session_t *session;
78
79 /**
80 * PA-TNC attribute segmentation contracts associated with TNCCS connection
81 */
82 seg_contract_manager_t *contracts;
83
84 /**
85 * IMV action recommendation
86 */
87 TNC_IMV_Action_Recommendation rec;
88
89 /**
90 * IMV evaluation result
91 */
92 TNC_IMV_Evaluation_Result eval;
93
94 /**
95 * IMV OS handshake state
96 */
97 imv_os_handshake_state_t handshake_state;
98
99 /**
100 * List of blacklisted packages to be removed
101 */
102 linked_list_t *remove_packages;
103
104 /**
105 h* List of vulnerable packages to be updated
106 */
107 linked_list_t *update_packages;
108
109 /**
110 * TNC Reason String
111 */
112 imv_reason_string_t *reason_string;
113
114 /**
115 * IETF Remediation Instructions String
116 */
117 imv_remediation_string_t *remediation_string;
118
119 /**
120 * Number of processed packages
121 */
122 int count;
123
124 /**
125 * Number of vulnerable packages
126 */
127 int count_security;
128
129 /**
130 * Number of blacklisted packages
131 */
132 int count_blacklist;
133
134 /**
135 * Number of whitelisted packages
136 */
137 int count_ok;
138
139 /**
140 * OS Settings
141 */
142 u_int os_settings;
143
144 /**
145 * Number of installed packages still missing
146 */
147 uint16_t missing;
148
149 };
150
151 /**
152 * Supported languages
153 */
154 static char* languages[] = { "en", "de", "pl" };
155
156 /**
157 * Reason strings for "OS settings"
158 */
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" },
163 { NULL, NULL }
164 };
165
166 /**
167 * Reason strings for "installed software packages"
168 */
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" },
173 { NULL, NULL }
174 };
175
176 /**
177 * Instruction strings for "Software Security Updates"
178 */
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" },
183 { NULL, NULL }
184 };
185
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" },
190 { NULL, NULL }
191 };
192
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:" },
197 { NULL, NULL }
198 };
199
200 /**
201 * Instruction strings for "Blacklisted Software Packages"
202 */
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" },
207 { NULL, NULL }
208 };
209
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" },
214 { NULL, NULL }
215 };
216
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:" },
221 { NULL, NULL }
222 };
223
224 ;/**
225 * Instruction strings for "Forwarding Enabled"
226 */
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" },
231 { NULL, NULL }
232 };
233
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" },
238 { NULL, NULL }
239 };
240
241 /**
242 * Instruction strings for "Default Password Enabled"
243 */
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" },
248 { NULL, NULL }
249 };
250
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" },
255 { NULL, NULL }
256 };
257
258 /**
259 * Instruction strings for "Unknown Source"
260 */
261 static imv_lang_string_t instr_unknown_source_title[] = {
262 { "en", "Unknown Software Origin" },
263 { "de", "Unbekannte Softwareherkunft" },
264 { "pl", "Nieznane pochodzenie softwaru" },
265 { NULL, NULL }
266 };
267
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ł" },
272 { NULL, NULL }
273 };
274
275 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
276 private_imv_os_state_t *this)
277 {
278 return this->connection_id;
279 }
280
281 METHOD(imv_state_t, has_long, bool,
282 private_imv_os_state_t *this)
283 {
284 return this->has_long;
285 }
286
287 METHOD(imv_state_t, has_excl, bool,
288 private_imv_os_state_t *this)
289 {
290 return this->has_excl;
291 }
292
293 METHOD(imv_state_t, set_flags, void,
294 private_imv_os_state_t *this, bool has_long, bool has_excl)
295 {
296 this->has_long = has_long;
297 this->has_excl = has_excl;
298 }
299
300 METHOD(imv_state_t, set_max_msg_len, void,
301 private_imv_os_state_t *this, uint32_t max_msg_len)
302 {
303 this->max_msg_len = max_msg_len;
304 }
305
306 METHOD(imv_state_t, get_max_msg_len, uint32_t,
307 private_imv_os_state_t *this)
308 {
309 return this->max_msg_len;
310 }
311
312 METHOD(imv_state_t, set_action_flags, void,
313 private_imv_os_state_t *this, uint32_t flags)
314 {
315 this->action_flags |= flags;
316 }
317
318 METHOD(imv_state_t, get_action_flags, uint32_t,
319 private_imv_os_state_t *this)
320 {
321 return this->action_flags;
322 }
323
324 METHOD(imv_state_t, set_session, void,
325 private_imv_os_state_t *this, imv_session_t *session)
326 {
327 this->session = session;
328 }
329
330 METHOD(imv_state_t, get_session, imv_session_t*,
331 private_imv_os_state_t *this)
332 {
333 return this->session;
334 }
335
336 METHOD(imv_state_t, get_contracts, seg_contract_manager_t*,
337 private_imv_os_state_t *this)
338 {
339 return this->contracts;
340 }
341
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)
345 {
346 *rec = this->rec;
347 *eval = this->eval;
348 }
349
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)
353 {
354 this->rec = rec;
355 this->eval = eval;
356 }
357
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)
361 {
362 this->rec = tncif_policy_update_recommendation(this->rec, rec);
363 this->eval = tncif_policy_update_evaluation(this->eval, eval);
364 }
365
366 METHOD(imv_state_t, change_state, TNC_ConnectionState,
367 private_imv_os_state_t *this, TNC_ConnectionState new_state)
368 {
369 TNC_ConnectionState old_state;
370
371 old_state = this->state;
372 this->state = new_state;
373 return old_state;
374 }
375
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)
379 {
380 if (!this->count_security && !this->count_blacklist & !this->os_settings)
381 {
382 return FALSE;
383 }
384 *reason_language = imv_lang_string_select_lang(language_enumerator,
385 languages, countof(languages));
386
387 /* Instantiate a TNC Reason String object */
388 DESTROY_IF(this->reason_string);
389 this->reason_string = imv_reason_string_create(*reason_language, "\n");
390
391 if (this->count_security || this->count_blacklist)
392 {
393 this->reason_string->add_reason(this->reason_string, reason_packages);
394 }
395 if (this->os_settings)
396 {
397 this->reason_string->add_reason(this->reason_string, reason_settings);
398 }
399 *reason_string = this->reason_string->get_encoding(this->reason_string);
400
401 return TRUE;
402 }
403
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)
407 {
408 imv_os_info_t *os_info;
409 bool as_xml = FALSE;
410
411 if (!this->count_security && !this->count_blacklist & !this->os_settings)
412 {
413 return FALSE;
414 }
415 *lang_code = imv_lang_string_select_lang(language_enumerator,
416 languages, countof(languages));
417
418 /* Instantiate an IETF Remediation Instructions String object */
419 DESTROY_IF(this->remediation_string);
420 if (this->session)
421 {
422 os_info = this->session->get_os_info(this->session);
423 as_xml = os_info->get_type(os_info) == OS_TYPE_ANDROID;
424 }
425 this->remediation_string = imv_remediation_string_create(as_xml, *lang_code);
426
427 /* List of blacklisted packages to be removed, if any */
428 if (this->count_blacklist)
429 {
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);
435 }
436
437 /* List of packages in need of an update, if any */
438 if (this->count_security)
439 {
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);
445 }
446
447 /* Add instructions concerning improper OS settings */
448 if (this->os_settings & OS_SETTINGS_FWD_ENABLED)
449 {
450 this->remediation_string->add_instruction(this->remediation_string,
451 instr_fwd_enabled_title,
452 instr_fwd_enabled_descr, NULL, NULL);
453 }
454 if (this->os_settings & OS_SETTINGS_DEFAULT_PWD_ENABLED)
455 {
456 this->remediation_string->add_instruction(this->remediation_string,
457 instr_default_pwd_enabled_title,
458 instr_default_pwd_enabled_descr, NULL, NULL);
459 }
460 if (this->os_settings & OS_SETTINGS_UNKNOWN_SOURCE)
461 {
462 this->remediation_string->add_instruction(this->remediation_string,
463 instr_unknown_source_title,
464 instr_unknown_source_descr, NULL, NULL);
465 }
466
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);
470
471 return TRUE;
472 }
473
474 METHOD(imv_state_t, reset, void,
475 private_imv_os_state_t *this)
476 {
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;
483
484 this->action_flags = 0;
485
486 this->handshake_state = IMV_OS_STATE_INIT;
487 this->count = 0;
488 this->count_security = 0;
489 this->count_blacklist = 0;
490 this->count_ok = 0;
491 this->os_settings = 0;
492 this->missing = 0;
493
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();
498 }
499
500 METHOD(imv_state_t, destroy, void,
501 private_imv_os_state_t *this)
502 {
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);
509 free(this);
510 }
511
512 METHOD(imv_os_state_t, set_handshake_state, void,
513 private_imv_os_state_t *this, imv_os_handshake_state_t new_state)
514 {
515 this->handshake_state = new_state;
516 }
517
518 METHOD(imv_os_state_t, get_handshake_state, imv_os_handshake_state_t,
519 private_imv_os_state_t *this)
520 {
521 return this->handshake_state;
522 }
523
524
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)
528 {
529 this->count += count;
530 this->count_security += count_security;
531 this->count_blacklist += count_blacklist;
532 this->count_ok += count_ok;
533 }
534
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)
538 {
539 if (count)
540 {
541 *count = this->count;
542 }
543 if (count_security)
544 {
545 *count_security = this->count_security;
546 }
547 if (count_blacklist)
548 {
549 *count_blacklist = this->count_blacklist;
550 }
551 if (count_ok)
552 {
553 *count_ok = this->count_ok;
554 }
555 }
556
557 METHOD(imv_os_state_t, set_os_settings, void,
558 private_imv_os_state_t *this, u_int settings)
559 {
560 this->os_settings |= settings;
561 }
562
563 METHOD(imv_os_state_t, get_os_settings, u_int,
564 private_imv_os_state_t *this)
565 {
566 return this->os_settings;
567 }
568
569 METHOD(imv_os_state_t, set_missing, void,
570 private_imv_os_state_t *this, uint16_t missing)
571 {
572 this->missing = missing;
573 }
574
575 METHOD(imv_os_state_t, get_missing, uint16_t,
576 private_imv_os_state_t *this)
577 {
578 return this->missing;
579 }
580
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)
584 {
585 package = strdup(package);
586
587 if (package_state == OS_PACKAGE_STATE_BLACKLIST)
588 {
589 this->remove_packages->insert_last(this->remove_packages, package);
590 }
591 else
592 {
593 this->update_packages->insert_last(this->update_packages, package);
594 }
595 }
596
597 /**
598 * Described in header.
599 */
600 imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
601 {
602 private_imv_os_state_t *this;
603
604 INIT(this,
605 .public = {
606 .interface = {
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,
624 .reset = _reset,
625 .destroy = _destroy,
626 },
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,
636 },
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(),
644 );
645
646 return &this->public.interface;
647 }
648
649