generate reason strings and remediation instructions for improper OS settings
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 18 Nov 2012 10:44:03 +0000 (11:44 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 18 Nov 2012 10:44:03 +0000 (11:44 +0100)
src/libimcv/plugins/imv_os/imv_os.c
src/libimcv/plugins/imv_os/imv_os_state.c
src/libimcv/plugins/imv_os/imv_os_state.h

index 0091e3e..7ec7d34 100644 (file)
@@ -150,6 +150,7 @@ 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;
+       char non_market_apps_str[] = "install_non_market_apps";
 
        os_state = (imv_os_state_t*)state;
 
@@ -241,6 +242,11 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                        fwd_status = attr_cast->get_status(attr_cast);
                                        DBG1(DBG_IMV, "IPv4 forwarding status: %N",
                                                                   os_fwd_status_names, fwd_status);
+                                       if (fwd_status == OS_FWD_ENABLED)
+                                       {
+                                               os_state->set_os_settings(os_state,
+                                                                                       OS_SETTINGS_FWD_ENABLED);
+                                       }
                                        break;
                                }
                                case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
@@ -252,6 +258,11 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                        default_pwd_status = attr_cast->get_status(attr_cast);
                                        DBG1(DBG_IMV, "factory default password: %sabled",
                                                                   default_pwd_status ? "en":"dis");
+                                       if (default_pwd_status)
+                                       {
+                                               os_state->set_os_settings(os_state,
+                                                                                       OS_SETTINGS_DEFAULT_PWD_ENABLED);
+                                       }
                                        break;
                                }
                                case IETF_ATTR_INSTALLED_PACKAGES:
@@ -301,6 +312,12 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                        e = attr_cast->create_enumerator(attr_cast);
                                        while (e->enumerate(e, &name, &value))
                                        {
+                                               if (streq(name, non_market_apps_str) &&
+                                                       chunk_equals(value, chunk_from_chars('1')))
+                                               {
+                                                       os_state->set_os_settings(os_state,
+                                                                                               OS_SETTINGS_NON_MARKET_APPS);
+                                               }
                                                DBG1(DBG_IMV, "setting '%s'", name);
                                                dbg_imv_multi_line(value);
                                        }
@@ -323,58 +340,33 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
        if (os_name.len && os_version.len)
        {
                os_type_t os_type;
-               char *product_info;
-               char *uri = "http://remediation.strongswan.org/fix-it/";
-               char *string = "use a Linux operating system instead of Windows 1.2.3";
-               char *lang_code = "en";
+               ita_attr_get_settings_t *attr_cast;
 
+               /* set the OS type, name and version */
                os_type = os_type_from_name(os_name);
                os_state->set_info(os_state,os_type, os_name, os_version);
-               product_info = os_state->get_info(os_state, NULL, NULL, NULL);
 
-               if (streq(product_info, "Windows 1.2.3"))
-               {
-                       DBG1(DBG_IMV, "OS '%s' is not supported", product_info);
+               /* requesting installed packages */
+               os_state->set_package_request(os_state, TRUE);
+               attr = ietf_attr_attr_request_create(PEN_IETF,
+                                                                                        IETF_ATTR_INSTALLED_PACKAGES);
+               out_msg->add_attribute(out_msg, attr);
 
-                       attr = ietf_attr_remediation_instr_create_from_string(
-                                                               chunk_create(string, strlen(string)),
-                                                               chunk_create(lang_code, strlen(lang_code)));
-                       out_msg->add_attribute(out_msg, attr);
-                       attr = ietf_attr_remediation_instr_create_from_uri(
-                                                               chunk_create(uri, strlen(uri)));
-                       out_msg->add_attribute(out_msg, attr);
+               /* requesting Android or Linux settings */
+               attr = ita_attr_get_settings_create();
+               attr_cast = (ita_attr_get_settings_t*)attr;
 
-                       state->set_recommendation(state,
-                                                               TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
-                                                               TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR);
-                       assessment = TRUE;
+               if (os_type == OS_TYPE_ANDROID)
+               {
+                       attr_cast->add(attr_cast, "android_id");
+                       attr_cast->add(attr_cast, non_market_apps_str);
                }
                else
                {
-                       ita_attr_get_settings_t *attr_cast;
-
-                       /* requesting installed packages */
-                       os_state->set_package_request(os_state, TRUE);
-                       attr = ietf_attr_attr_request_create(PEN_IETF,
-                                                               IETF_ATTR_INSTALLED_PACKAGES);
-                       out_msg->add_attribute(out_msg, attr);
-
-                       /* requesting Android or Linux settings */
-                       attr = ita_attr_get_settings_create();
-                       attr_cast = (ita_attr_get_settings_t*)attr;
-
-                       if (os_type == OS_TYPE_ANDROID)
-                       {
-                               attr_cast->add(attr_cast, "android_id");
-                               attr_cast->add(attr_cast, "install_non_market_apps");
-                       }
-                       else
-                       {
-                               attr_cast->add(attr_cast, "/proc/sys/kernel/random/boot_id");
-                               attr_cast->add(attr_cast, "/proc/sys/kernel/tainted");
-                       }
-                       out_msg->add_attribute(out_msg, attr);
+                       attr_cast->add(attr_cast, "/proc/sys/kernel/random/boot_id");
+                       attr_cast->add(attr_cast, "/proc/sys/kernel/tainted");
                }
+               out_msg->add_attribute(out_msg, attr);
        }
 
        if (fatal_error)
@@ -398,7 +390,8 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                         "%d ok, %d not found", count, count_update, count_blacklist,
                         count_ok, count - count_update - count_blacklist - count_ok);
 
-               if (count_update || count_blacklist)
+               if (count_update || count_blacklist ||
+                       os_state->get_os_settings(os_state))
                {
                        state->set_recommendation(state,
                                                                TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
index 7796a47..470acc5 100644 (file)
@@ -20,7 +20,7 @@
 
 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 entry_t entry_t;
 typedef struct instruction_entry_t instruction_entry_t;
 
 /**
@@ -94,6 +94,11 @@ struct private_imv_os_state_t {
        linked_list_t *bad_packages;
 
        /**
+        * Local copy of the reason string
+        */
+       char *reasons;
+
+       /**
         * Local copy of the remediation instruction string
         */
        char *instructions;
@@ -124,6 +129,11 @@ struct private_imv_os_state_t {
        bool package_request;
 
        /**
+        * OS Settings
+        */
+       u_int os_settings;
+
+       /**
         * Angel count
         */
        int angel_count;
@@ -148,19 +158,51 @@ static void free_package_entry(package_entry_t *this)
 }
 
 /**
- * Define an internal reason string entry
+ * Define a language string entry
  */
-struct reason_entry_t {
+struct entry_t {
        char *lang;
        char *string;
 };
 
 /**
+ * Table of multi-lingual improper settings reason string entries
+ */
+static entry_t settings_reasons[] = {
+       { "en", "Improper OS settings were detected" },
+       { "de", "Unzul√§ssige OS Einstellungen wurden festgestellt" }
+};
+
+/**
  * Table of multi-lingual reason string entries
  */
-static reason_entry_t reasons[] = {
+static entry_t reasons[] = {
        { "en", "Vulnerable or blacklisted software packages were found" },
-       { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" },
+       { "de", "Schwachstellenbehaftete oder gesperrte Softwarepakete wurden gefunden" }
+};
+
+/**
+ * Table of multi-lingual forwarding enable string entries
+ */
+static entry_t instruction_fwd_enabled[] = {
+       { "en", "Please disable IP forwarding" },
+       { "de", "Bitte deaktivieren Sie das IP Forwarding" }
+};
+
+/**
+ * Table of multi-lingual default password enabled string entries
+ */
+static entry_t instruction_default_pwd_enabled[] = {
+       { "en", "Please change the default password" },
+       { "de", "Bitte √§ndern Sie das default Passwort" }
+};
+
+/**
+ * Table of multi-lingual defaul install non market apps string entries
+ */
+static entry_t instruction_non_market_apps[] = {
+       { "en", "Do not allow the installation of apps from unknown sources" },
+       { "de", "Erlauben Sie nicht die Installation von Apps von unbekannten Quellen" }
 };
 
 /**
@@ -248,18 +290,14 @@ METHOD(imv_state_t, get_reason_string, bool,
        char **reason_string, char **reason_language)
 {
        bool match = FALSE;
-       char *lang;
-       int i;
+       char *lang, *pos;
+       int i, i_chosen = 0, len = 0, nr_of_reasons = 0;
 
-       if (!this->count_update && !this->count_blacklist)
+       if (!this->count_update && !this->count_blacklist & !this->os_settings)
        {
                return FALSE;
        }
 
-       /* set the default language */
-       *reason_language = reasons[0].lang;
-       *reason_string   = reasons[0].string;
-
        while (language_enumerator->enumerate(language_enumerator, &lang))
        {
                for (i = 0; i < countof(reasons); i++)
@@ -267,8 +305,7 @@ METHOD(imv_state_t, get_reason_string, bool,
                        if (streq(lang, reasons[i].lang))
                        {
                                match = TRUE;
-                               *reason_language = reasons[i].lang;
-                               *reason_string   = reasons[i].string;
+                               i_chosen = i;
                                break;
                        }
                }
@@ -277,9 +314,40 @@ METHOD(imv_state_t, get_reason_string, bool,
                        break;
                }
        }
+       *reason_language = reasons[i_chosen].lang;
 
-       return TRUE;
+       if (this->count_update ||  this->count_blacklist)
+       {
+               len += strlen(reasons[i_chosen].string);
+               nr_of_reasons++;
+       }
+       if (this->os_settings)
+       {
+               len += strlen(settings_reasons[i_chosen].string);
+               nr_of_reasons++;
+       }
 
+       /* Allocate memory for the reason string */
+       pos = this->reasons = malloc(len + nr_of_reasons);
+
+       if (this->count_update ||  this->count_blacklist)
+       {
+               strcpy(pos, reasons[i_chosen].string);
+               pos += strlen(reasons[i_chosen].string);
+               if (--nr_of_reasons)
+               {
+                       *pos++ = '\n';
+               }
+       }
+       if (this->os_settings)
+       {
+               strcpy(pos, settings_reasons[i_chosen].string);
+               pos += strlen(settings_reasons[i_chosen].string);
+       }
+       *pos = '\0';
+       *reason_string = this->reasons;
+
+       return TRUE;
 }
 
 METHOD(imv_state_t, get_remediation_instructions, bool,
@@ -290,9 +358,9 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
        char *lang, *pos;
        enumerator_t *enumerator;
        package_entry_t *entry;
-       int i, i_chosen = 0, len = 0;
+       int i, i_chosen = 0, len = 0, nr_of_instructions = 0;
 
-       if (!this->count_update && !this->count_blacklist)
+       if (!this->count_update && !this->count_blacklist & !this->os_settings)
        {
                return FALSE;
        }
@@ -324,6 +392,21 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
        {
                len += strlen(instructions[i_chosen].removal_string);
        }
+       if (this->os_settings & OS_SETTINGS_FWD_ENABLED)
+       {
+               len += strlen(instruction_fwd_enabled[i_chosen].string);
+               nr_of_instructions++;
+       }
+       if (this->os_settings & OS_SETTINGS_DEFAULT_PWD_ENABLED)
+       {
+               len += strlen(instruction_default_pwd_enabled[i_chosen].string);
+               nr_of_instructions++;
+       }
+       if (this->os_settings & OS_SETTINGS_NON_MARKET_APPS)
+       {
+               len += strlen(instruction_non_market_apps[i_chosen].string);
+               nr_of_instructions++;
+       }
 
        enumerator = this->bad_packages->create_enumerator(this->bad_packages);
        while (enumerator->enumerate(enumerator, &entry))
@@ -333,7 +416,7 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
        enumerator->destroy(enumerator);
 
        /* Allocate memory for the remediation instructions */
-       pos = this->instructions = malloc(len + 1);
+       pos = this->instructions = malloc(len + nr_of_instructions + 1);
 
        /* List of blacklisted packages, if any */
        if (this->count_blacklist)
@@ -373,6 +456,31 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
                enumerator->destroy(enumerator);
        }
 
+       /* Add instructions concerning improper OS settings */
+       if (this->os_settings & OS_SETTINGS_FWD_ENABLED)
+       {
+               strcpy(pos, instruction_fwd_enabled[i_chosen].string);
+               pos += strlen(instruction_fwd_enabled[i_chosen].string);
+               if (--nr_of_instructions)
+               {
+                       *pos++ = '\n';
+               }
+       }
+       if (this->os_settings & OS_SETTINGS_DEFAULT_PWD_ENABLED)
+       {
+               strcpy(pos, instruction_default_pwd_enabled[i_chosen].string);
+               pos += strlen(instruction_default_pwd_enabled[i_chosen].string);
+               if (--nr_of_instructions)
+               {
+                       *pos++ = '\n';
+               }
+       }
+       if (this->os_settings & OS_SETTINGS_NON_MARKET_APPS)
+       {
+               strcpy(pos, instruction_non_market_apps[i_chosen].string);
+               pos += strlen(instruction_non_market_apps[i_chosen].string);
+       }
+
        *pos = '\0';
        *string = this->instructions;
        *uri = lib->settings->get_str(lib->settings,
@@ -386,6 +494,7 @@ METHOD(imv_state_t, destroy, void,
 {
        this->bad_packages->destroy_function(this->bad_packages,
                                                                                (void*)free_package_entry);
+       free(this->reasons);
        free(this->instructions);
        free(this->info);
        free(this->name.ptr);
@@ -471,6 +580,18 @@ METHOD(imv_os_state_t, get_package_request, bool,
        return this->package_request;
 }
 
+METHOD(imv_os_state_t, set_os_settings, void,
+       private_imv_os_state_t *this, u_int settings)
+{
+       this->os_settings |= settings;
+}
+
+METHOD(imv_os_state_t, get_os_settings, u_int,
+       private_imv_os_state_t *this)
+{
+       return this->os_settings;
+}
+
 METHOD(imv_os_state_t, set_angel_count, void,
        private_imv_os_state_t *this, bool start)
 {
@@ -524,6 +645,8 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                        .get_count = _get_count,
                        .set_package_request = _set_package_request,
                        .get_package_request = _get_package_request,
+                       .set_os_settings = _set_os_settings,
+                       .get_os_settings = _get_os_settings,
                        .set_angel_count = _set_angel_count,
                        .get_angel_count = _get_angel_count,
                        .add_bad_package = _add_bad_package,
index 760df78..29a851b 100644 (file)
 #include <library.h>
 
 typedef struct imv_os_state_t imv_os_state_t;
+typedef enum os_settings_t os_settings_t;
+
+enum os_settings_t {
+       OS_SETTINGS_FWD_ENABLED =         1,
+       OS_SETTINGS_DEFAULT_PWD_ENABLED = 2,
+       OS_SETTINGS_NON_MARKET_APPS =     4
+};
 
 /**
  * Internal state of an imv_os_t connection instance
@@ -95,6 +102,20 @@ struct imv_os_state_t {
        bool (*get_package_request)(imv_os_state_t *this);
 
        /**
+        * Set OS settings
+        *
+        * @param settings              OS settings
+        */
+       void (*set_os_settings)(imv_os_state_t *this, u_int settings);
+
+       /**
+        * Get OS settings
+        *
+        * @return                              OS settings
+        */
+       u_int (*get_os_settings)(imv_os_state_t *this);
+
+       /**
         * Increase/Decrease the ITA Angel count
         *
         * @param start                 TRUE increases and FALSE decreases count by one