diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libimcv/os_info/os_info.c | 6 | ||||
-rw-r--r-- | src/libimcv/os_info/os_info.h | 12 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os.c | 13 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os_database.c | 29 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os_state.c | 163 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os_state.h | 26 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/pacman.c | 2 | ||||
-rw-r--r-- | src/libpts/plugins/imv_attestation/attest.c | 10 | ||||
-rw-r--r-- | src/libpts/plugins/imv_attestation/attest_db.c | 19 | ||||
-rw-r--r-- | src/libpts/plugins/imv_attestation/attest_db.h | 6 |
10 files changed, 206 insertions, 80 deletions
diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c index 9716e2c9e..098cb1e83 100644 --- a/src/libimcv/os_info/os_info.c +++ b/src/libimcv/os_info/os_info.c @@ -42,6 +42,12 @@ ENUM(os_fwd_status_names, OS_FWD_DISABLED, OS_FWD_UNKNOWN, "unknown" ); +ENUM(os_package_state_names, OS_PACKAGE_STATE_UPDATE, OS_PACKAGE_STATE_BLACKLIST, + "", + " [s]", + " [b]" +); + /** * Private data of an os_info_t object. * diff --git a/src/libimcv/os_info/os_info.h b/src/libimcv/os_info/os_info.h index 6946b1ed7..f47460709 100644 --- a/src/libimcv/os_info/os_info.h +++ b/src/libimcv/os_info/os_info.h @@ -24,6 +24,7 @@ typedef struct os_info_t os_info_t; typedef enum os_type_t os_type_t; typedef enum os_fwd_status_t os_fwd_status_t; +typedef enum os_package_state_t os_package_state_t; #include <library.h> @@ -45,6 +46,17 @@ enum os_type_t { extern enum_name_t *os_type_names; /** + * Defines the security state of a package stored in the database + */ +enum os_package_state_t { + OS_PACKAGE_STATE_UPDATE = 0, /* latest update */ + OS_PACKAGE_STATE_SECURITY = 1, /* latest security fix */ + OS_PACKAGE_STATE_BLACKLIST = 2 /* blacklisted package */ +}; + +extern enum_name_t *os_package_state_names; + +/** * Defines the IPv4 forwarding status */ enum os_fwd_status_t { diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index c1af31f42..0091e3e1c 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -150,7 +150,6 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) chunk_t os_name = chunk_empty; chunk_t os_version = chunk_empty; bool fatal_error = FALSE, assessment = FALSE; - int count, count_bad, count_ok; os_state = (imv_os_state_t*)state; @@ -391,11 +390,15 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) !os_state->get_package_request(os_state) && !os_state->get_angel_count(os_state)) { - os_state->get_count(os_state, &count, &count_bad, &count_ok); - DBG1(DBG_IMV, "processed %d packages: %d bad, %d ok, %d not found", - count, count_bad, count_ok, count - count_bad - count_ok); + int count, count_update, count_blacklist, count_ok; - if (count_bad) + os_state->get_count(os_state, &count, &count_update, &count_blacklist, + &count_ok); + DBG1(DBG_IMV, "processed %d packages: %d not updated, %d blacklisted, " + "%d ok, %d not found", count, count_update, count_blacklist, + count_ok, count - count_update - count_blacklist - count_ok); + + if (count_update || count_blacklist) { state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, diff --git a/src/libimcv/plugins/imv_os/imv_os_database.c b/src/libimcv/plugins/imv_os/imv_os_database.c index 00480624a..4ca8eb5b8 100644 --- a/src/libimcv/plugins/imv_os/imv_os_database.c +++ b/src/libimcv/plugins/imv_os/imv_os_database.c @@ -46,8 +46,9 @@ METHOD(imv_os_database_t, check_packages, status_t, chunk_t os_name, os_version, name, version; os_type_t os_type; size_t os_version_len; - int pid, gid, security; - int count = 0, count_ok = 0, count_no_match = 0; + os_package_state_t package_state; + int pid, gid; + int count = 0, count_ok = 0, count_no_match = 0, count_blacklist = 0; enumerator_t *e; status_t status = SUCCESS; bool found, match; @@ -139,10 +140,10 @@ METHOD(imv_os_database_t, check_packages, status_t, found = FALSE; match = FALSE; - while (e->enumerate(e, &cur_release, &security)) + while (e->enumerate(e, &cur_release, &package_state)) { found = TRUE; - if (streq(release, cur_release)) + if (streq(release, cur_release) || streq("*", cur_release)) { match = TRUE; break; @@ -154,15 +155,25 @@ METHOD(imv_os_database_t, check_packages, status_t, { if (match) { - DBG2(DBG_IMV, "package '%s' (%s)%s is ok", package, release, - security ? " [s]" : ""); - count_ok++; + if (package_state == OS_PACKAGE_STATE_BLACKLIST) + { + DBG2(DBG_IMV, "package '%s' (%s) is blacklisted", + package, release); + count_blacklist++; + state->add_bad_package(state, package, package_state); + } + else + { + DBG2(DBG_IMV, "package '%s' (%s)%N is ok", package, release, + os_package_state_names, package_state); + count_ok++; + } } else { DBG1(DBG_IMV, "package '%s' (%s) no match", package, release); count_no_match++; - state->add_bad_package(state, package); + state->add_bad_package(state, package, package_state); } } else @@ -173,7 +184,7 @@ METHOD(imv_os_database_t, check_packages, status_t, free(release); } free(product); - state->set_count(state, count, count_no_match, count_ok); + state->set_count(state, count, count_no_match, count_blacklist, count_ok); return status; } diff --git a/src/libimcv/plugins/imv_os/imv_os_state.c b/src/libimcv/plugins/imv_os/imv_os_state.c index 8bb944fea..318b43352 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.c +++ b/src/libimcv/plugins/imv_os/imv_os_state.c @@ -19,6 +19,9 @@ #include <collections/linked_list.h> typedef struct private_imv_os_state_t private_imv_os_state_t; +typedef struct package_entry_t package_entry_t; +typedef struct reason_entry_t reason_entry_t; +typedef struct instruction_entry_t instruction_entry_t; /** * Private data of an imv_os_state_t object. @@ -101,9 +104,14 @@ struct private_imv_os_state_t { int count; /** - * Number of blacklisted or not updated packages + * Number of not updated packages */ - int count_bad; + int count_update; + + /** + * Number of blacklisted packages + */ + int count_blacklist; /** * Number of whitelisted packages @@ -122,12 +130,27 @@ struct private_imv_os_state_t { }; -typedef struct entry_t entry_t; +/** + * Store a bad package entry + */ +struct package_entry_t { + char *name; + os_package_state_t state; +}; + +/** + * Free a bad package entry + */ +static void free_package_entry(package_entry_t *this) +{ + free(this->name); + free(this); +} /** * Define an internal reason string entry */ -struct entry_t { +struct reason_entry_t { char *lang; char *string; }; @@ -135,18 +158,30 @@ struct entry_t { /** * Table of multi-lingual reason string entries */ -static entry_t reasons[] = { +static reason_entry_t reasons[] = { { "en", "Vulnerable or blacklisted software packages were found" }, { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" }, }; /** - * Table of multi-lingual remediation instruction string entries + * Define a remediation instruction string entry + */ +struct instruction_entry_t { + char *lang; + char *update_string; + char *removal_string; +}; + +/** + * Tables of multi-lingual remediation instruction string entries */ -static entry_t instructions [] = { - { "en", "Please update the following software packages:\n" }, - { "de", "Bitte updaten Sie die folgenden Softwarepakete\n" }, - { "pl", "Proszę zaktualizować następujące pakiety:\n" } +static instruction_entry_t instructions [] = { + { "en", "Please update the following software packages:\n", + "Please remove the following software packages:\n" }, + { "de", "Bitte updaten Sie die folgenden Softwarepakete\n", + "Bitte entfernen Sie die folgenden Softwarepakete\n" }, + { "pl", "Proszę zaktualizować następujące pakiety:\n", + "Proszę usunąć następujące pakiety:\n" } }; METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, @@ -216,7 +251,7 @@ METHOD(imv_state_t, get_reason_string, bool, char *lang; int i; - if (!this->count_bad) + if (!this->count_update && !this->count_blacklist) { return FALSE; } @@ -254,17 +289,14 @@ METHOD(imv_state_t, get_remediation_instructions, bool, bool match = FALSE; char *lang, *package, *pos; enumerator_t *enumerator; - int i, len; + package_entry_t *entry; + int i, i_chosen = 0, len = 0; - if (!this->count_bad) + if (!this->count_update && !this->count_blacklist) { return FALSE; } - /* set the default language */ - *lang_code = instructions[0].lang; - *string = instructions[0].string; - while (language_enumerator->enumerate(language_enumerator, &lang)) { for (i = 0; i < countof(instructions); i++) @@ -272,8 +304,7 @@ METHOD(imv_state_t, get_remediation_instructions, bool, if (streq(lang, instructions[i].lang)) { match = TRUE; - *lang_code = instructions[i].lang; - *string = instructions[i].string; + i_chosen = i; break; } } @@ -282,31 +313,67 @@ METHOD(imv_state_t, get_remediation_instructions, bool, break; } } + *lang_code = instructions[i_chosen].lang; /* Compute the size of the remediation string */ - len = strlen(*string); + if (this->count_update) + { + len += strlen(instructions[i_chosen].update_string); + } + if (this->count_blacklist) + { + len += strlen(instructions[i_chosen].removal_string); + } enumerator = this->bad_packages->create_enumerator(this->bad_packages); - while (enumerator->enumerate(enumerator, &package)) + while (enumerator->enumerate(enumerator, &entry)) { - len += strlen(package) + 1; + len += strlen(entry->name) + 1; } enumerator->destroy(enumerator); + /* Allocate memory for the remediation instructions */ pos = this->instructions = malloc(len + 1); - strcpy(pos, *string); - pos += strlen(*string); - enumerator = this->bad_packages->create_enumerator(this->bad_packages); - while (enumerator->enumerate(enumerator, &package)) + /* List of blacklisted packages, if any */ + if (this->count_blacklist) { - strcpy(pos, package); - pos += strlen(package); - *pos++ = '\n'; + strcpy(pos, instructions[i_chosen].removal_string); + pos += strlen(instructions[i_chosen].removal_string); + + enumerator = this->bad_packages->create_enumerator(this->bad_packages); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->state == OS_PACKAGE_STATE_BLACKLIST) + { + strcpy(pos, entry->name); + pos += strlen(entry->name); + *pos++ = '\n'; + } + } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - *pos = '\0'; + /* List of packages in need of an update, if any */ + if (this->count_update) + { + strcpy(pos, instructions[i_chosen].update_string); + pos += strlen(instructions[i_chosen].update_string); + + enumerator = this->bad_packages->create_enumerator(this->bad_packages); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->state != OS_PACKAGE_STATE_BLACKLIST) + { + strcpy(pos, entry->name); + pos += strlen(entry->name); + *pos++ = '\n'; + } + } + enumerator->destroy(enumerator); + } + + *pos = '\0'; *string = this->instructions; *uri = lib->settings->get_str(lib->settings, "libimcv.plugins.imv-os.remediation_uri", NULL); @@ -317,7 +384,8 @@ METHOD(imv_state_t, get_remediation_instructions, bool, METHOD(imv_state_t, destroy, void, private_imv_os_state_t *this) { - this->bad_packages->destroy_function(this->bad_packages, free); + this->bad_packages->destroy_function(this->bad_packages, + (void*)free_package_entry); free(this->instructions); free(this->info); free(this->name.ptr); @@ -360,23 +428,30 @@ METHOD(imv_os_state_t, get_info, char*, } METHOD(imv_os_state_t, set_count, void, - private_imv_os_state_t *this, int count, int count_bad, int count_ok) + private_imv_os_state_t *this, int count, int count_update, + int count_blacklist, int count_ok) { - this->count += count; - this->count_bad += count_bad; - this->count_ok += count_ok; + this->count += count; + this->count_update += count_update; + this->count_blacklist += count_blacklist; + this->count_ok += count_ok; } METHOD(imv_os_state_t, get_count, void, - private_imv_os_state_t *this, int *count, int *count_bad, int *count_ok) + private_imv_os_state_t *this, int *count, int *count_update, + int *count_blacklist, int *count_ok) { if (count) { *count = this->count; } - if (count_bad) + if (count_update) { - *count_bad = this->count_bad; + *count_update = this->count_update; + } + if (count_blacklist) + { + *count_blacklist = this->count_blacklist; } if (count_ok) { @@ -409,9 +484,15 @@ METHOD(imv_os_state_t, get_angel_count, int, } METHOD(imv_os_state_t, add_bad_package, void, - private_imv_os_state_t *this, char *package) + private_imv_os_state_t *this, char *package, + os_package_state_t package_state) { - this->bad_packages->insert_last(this->bad_packages, strdup(package)); + package_entry_t *entry; + + entry = malloc_thing(package_entry_t); + entry->name = strdup(package); + entry->state = package_state; + this->bad_packages->insert_last(this->bad_packages, entry); } /** diff --git a/src/libimcv/plugins/imv_os/imv_os_state.h b/src/libimcv/plugins/imv_os/imv_os_state.h index 3c9d21dac..760df7835 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.h +++ b/src/libimcv/plugins/imv_os/imv_os_state.h @@ -62,22 +62,24 @@ struct imv_os_state_t { /** * Set [or with multiple attributes increment] package counters * - * @param count Number of processed packages - * @param count_bad Number of blacklisted or not updated packages - * @param count_ok Number of whitelisted packages + * @param count Number of processed packages + * @param count_update Number of not updated packages + * @param count_blacklist Number of blacklisted packages + * @param count_ok Number of whitelisted packages */ - void (*set_count)(imv_os_state_t *this, int count, int count_bad, - int count_ok); + void (*set_count)(imv_os_state_t *this, int count, int count_update, + int count_blacklist, int count_ok); /** * Set [or with multiple attributes increment] package counters * - * @param count Number of processed packages - * @param count_bad Number of blacklisted or not updated packages - * @param count_ok Number of whitelisted packages + * @param count Number of processed packages + * @param count_update Number of not updated packages + * @param count_blacklist Number of blacklisted packages + * @param count_ok Number of whitelisted packages */ - void (*get_count)(imv_os_state_t *this, int *count, int *count_bad, - int *count_ok); + void (*get_count)(imv_os_state_t *this, int *count, int *count_update, + int *count_blacklist, int *count_ok); /** * Set/reset OS Installed Packages request status * @@ -110,8 +112,10 @@ struct imv_os_state_t { * Store a bad package that has to be updated or removed * * @param package Name of software package + * @param package_state Security state of software package */ - void (*add_bad_package)(imv_os_state_t *this, char *package); + void (*add_bad_package)(imv_os_state_t *this, char *package, + os_package_state_t package_state); }; diff --git a/src/libimcv/plugins/imv_os/pacman.c b/src/libimcv/plugins/imv_os/pacman.c index 38e79dbb2..eef5ce07f 100644 --- a/src/libimcv/plugins/imv_os/pacman.c +++ b/src/libimcv/plugins/imv_os/pacman.c @@ -22,6 +22,8 @@ #include <syslog.h> #include <time.h> +#include "imv_os_state.h" + #include <library.h> #include <utils/debug.h> diff --git a/src/libpts/plugins/imv_attestation/attest.c b/src/libpts/plugins/imv_attestation/attest.c index bcce833df..281078aaf 100644 --- a/src/libpts/plugins/imv_attestation/attest.c +++ b/src/libpts/plugins/imv_attestation/attest.c @@ -128,7 +128,7 @@ static void do_args(int argc, char *argv[]) { "delete", no_argument, NULL, 'd' }, { "del", no_argument, NULL, 'd' }, { "aik", required_argument, NULL, 'A' }, - { "security", no_argument, NULL, 'B' }, + { "blacklist", no_argument, NULL, 'B' }, { "component", required_argument, NULL, 'C' }, { "comp", required_argument, NULL, 'C' }, { "directory", required_argument, NULL, 'D' }, @@ -142,8 +142,9 @@ static void do_args(int argc, char *argv[]) { "relative", no_argument, NULL, 'R' }, { "rel", no_argument, NULL, 'R' }, { "sequence", required_argument, NULL, 'S' }, - { "version", required_argument, NULL, 'V' }, { "seq", required_argument, NULL, 'S' }, + { "version", required_argument, NULL, 'V' }, + { "security", no_argument, NULL, 'Y' }, { "sha1", no_argument, NULL, '1' }, { "sha256", no_argument, NULL, '2' }, { "sha384", no_argument, NULL, '3' }, @@ -229,7 +230,7 @@ static void do_args(int argc, char *argv[]) continue; } case 'B': - attest->set_security(attest); + attest->set_security(attest, OS_PACKAGE_STATE_BLACKLIST); continue; case 'C': if (!attest->set_component(attest, optarg, op == OP_ADD)) @@ -290,6 +291,9 @@ static void do_args(int argc, char *argv[]) exit(EXIT_FAILURE); } continue; + case 'Y': + attest->set_security(attest, OS_PACKAGE_STATE_SECURITY); + continue; case '1': attest->set_algo(attest, PTS_MEAS_ALGO_SHA1); continue; diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c index 6be7093a8..8e64d0a28 100644 --- a/src/libpts/plugins/imv_attestation/attest_db.c +++ b/src/libpts/plugins/imv_attestation/attest_db.c @@ -143,9 +143,9 @@ struct private_attest_db_t { bool relative; /** - * TRUE if a security issue exists + * Package security state */ - bool security; + os_package_state_t security; /** * Sequence number for ordering entries @@ -722,9 +722,9 @@ METHOD(attest_db_t, set_relative, void, } METHOD(attest_db_t, set_security, void, - private_attest_db_t *this) + private_attest_db_t *this, os_package_state_t security) { - this->security = TRUE; + this->security = security; } METHOD(attest_db_t, set_sequence, void, @@ -897,7 +897,8 @@ METHOD(attest_db_t, list_packages, void, { enumerator_t *e; char *package, *version; - int gid, gid_old = 0, security, spaces, count = 0; + os_package_state_t security; + int gid, gid_old = 0, spaces, count = 0; time_t t; if (this->pid) @@ -924,7 +925,8 @@ METHOD(attest_db_t, list_packages, void, printf(" "); } } - printf(" %T (%s) %s\n", &t, TRUE, version, security ? "[s]" : ""); + printf(" %T (%s)%N\n", &t, TRUE, version, + os_package_state_names, security); count++; } e->destroy(e); @@ -1493,9 +1495,10 @@ METHOD(attest_db_t, add, bool, DB_UINT, this->gid, DB_UINT, this->pid, DB_TEXT, this->version, DB_UINT, this->security, DB_INT, t) == 1; - printf("'%s' package %s (%s) %s%sinserted into database\n", + printf("'%s' package %s (%s)%N %sinserted into database\n", this->product, this->package, this->version, - this->security ? "[s] " : "", success ? "" : "could not be "); + os_package_state_names, this->security, + success ? "" : "could not be "); } return success; } diff --git a/src/libpts/plugins/imv_attestation/attest_db.h b/src/libpts/plugins/imv_attestation/attest_db.h index cd7b5f4f5..81dd0ad84 100644 --- a/src/libpts/plugins/imv_attestation/attest_db.h +++ b/src/libpts/plugins/imv_attestation/attest_db.h @@ -23,7 +23,7 @@ #define ATTEST_DB_H_ #include <pts/pts_meas_algo.h> - +#include <os_info/os_info.h> #include <library.h> typedef struct attest_db_t attest_db_t; @@ -161,9 +161,9 @@ struct attest_db_t { void (*set_relative)(attest_db_t *this); /** - * Set the security vulnerability flag + * Set the package security state */ - void (*set_security)(attest_db_t *this); + void (*set_security)(attest_db_t *this, os_package_state_t security); /** * Set the sequence number |