From 7b1059a4b54cc7e0c4e0c13b90aa9aae6b231c4d Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Thu, 18 Jul 2024 20:17:52 +0200 Subject: [PATCH 01/64] GMP doc: GET_LICENSE: add missing SENSOR reference --- src/schema_formats/XML/GMP.xml.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 770120a01..ed22b872f 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -13579,6 +13579,7 @@ END:VCALENDAR model model_type + sensor model From d73f5a4933c109adddfee234477ad1c0ab960fa9 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Thu, 18 Jul 2024 20:24:03 +0200 Subject: [PATCH 02/64] Remove ELSE when the true branch returns The ELSE makes it look like the first branch of the IF can fall through. --- src/manage_license.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/manage_license.c b/src/manage_license.c index 89c6038e8..d11d0b4a9 100644 --- a/src/manage_license.c +++ b/src/manage_license.c @@ -82,8 +82,7 @@ manage_update_license_file (const char *new_license, char **error_msg) __func__, broker_address); return 1; } - else - g_debug ("%s: Connected to %s\n", __func__, broker_address); + g_debug ("%s: Connected to %s\n", __func__, broker_address); ret = theia_new_modify_license_cmd ((char *) new_license, &modify_license_cmd); @@ -105,13 +104,11 @@ manage_update_license_file (const char *new_license, char **error_msg) free (client); return 2; } - else - g_debug ("%s: Sent modify.license command" - " (message_id: %s, group_id: %s)\n", - __func__, - modify_license_cmd->message->id, - modify_license_cmd->message->group_id); - + g_debug ("%s: Sent modify.license command" + " (message_id: %s, group_id: %s)\n", + __func__, + modify_license_cmd->message->id, + modify_license_cmd->message->group_id); ret = theia_client_get_info_response (client, THEIA_LICENSE_INFO_TOPIC, "modified.license", @@ -127,8 +124,7 @@ manage_update_license_file (const char *new_license, char **error_msg) free (client); return 3; } - else - g_debug ("%s: Received modified.license response", __func__); + g_debug ("%s: Received modified.license response", __func__); if (failure_modify_license_info) { @@ -142,11 +138,8 @@ manage_update_license_file (const char *new_license, char **error_msg) free (client); return 5; } - else - { - g_message ("%s: Uploaded new license file (%lu bytes)", - __func__, strlen (new_license)); - } + g_message ("%s: Uploaded new license file (%lu bytes)", + __func__, strlen (new_license)); theia_client_disconnect (client); theia_modified_license_info_free (modified_license_info); @@ -207,8 +200,7 @@ manage_get_license (gchar **status, __func__, broker_address); return 1; } - else - g_debug ("%s: Connected to %s\n", __func__, broker_address); + g_debug ("%s: Connected to %s\n", __func__, broker_address); ret = theia_new_get_license_cmd (&get_license_cmd); if (ret) @@ -229,13 +221,11 @@ manage_get_license (gchar **status, free (client); return 2; } - else - g_debug ("%s: Sent get.license command" - " (message_id: %s, group_id: %s)\n", - __func__, - get_license_cmd->message->id, - get_license_cmd->message->group_id); - + g_debug ("%s: Sent get.license command" + " (message_id: %s, group_id: %s)\n", + __func__, + get_license_cmd->message->id, + get_license_cmd->message->group_id); ret = theia_client_get_info_response (client, THEIA_LICENSE_INFO_TOPIC, "got.license", NULL, @@ -250,8 +240,7 @@ manage_get_license (gchar **status, free (client); return 3; } - else - g_debug ("%s: Received got.license response", __func__); + g_debug ("%s: Received got.license response", __func__); theia_client_disconnect (client); From f7e50860d24afa7cae4817494d65f20c35158112 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 23 Sep 2024 11:08:55 +0200 Subject: [PATCH 03/64] Add: Added the new CVE scan method with the new CPE matching. --- src/manage.c | 398 ++++++++++++++++++++++++++++++++------- src/manage.h | 47 ++++- src/manage_pg.c | 13 +- src/manage_sql.c | 206 +++++++++++++++++++- src/manage_sql_secinfo.c | 105 ++++++++--- 5 files changed, 667 insertions(+), 102 deletions(-) diff --git a/src/manage.c b/src/manage.c index c924ca36e..97688b391 100644 --- a/src/manage.c +++ b/src/manage.c @@ -60,6 +60,7 @@ #include "manage_sql_nvts.h" #include "manage_sql_tickets.h" #include "manage_sql_tls_certificates.h" +#include "sql.h" #include "utils.h" #include @@ -86,9 +87,11 @@ #include #include #include +#include #include #include #include +#include #include #undef G_LOG_DOMAIN @@ -3106,6 +3109,138 @@ set_scanner_connection_retry (int new_retry) /* CVE tasks. */ +static int +check_version (const gchar *target, const gchar *start_incl, const gchar *start_excl, const gchar *end_incl, const gchar *end_excl) +{ + int result; + + if (start_incl != NULL) + { + result = cmp_versions (start_incl, target); + if (result == -5) + return -1; + if (result > 0) + { + return 0; + } + } + if (start_excl != NULL) + { + result = cmp_versions (start_excl, target); + if (result == -5) + return -1; + if (result >= 0) + { + return 0; + } + } + + if (end_incl != NULL) + { + result = cmp_versions (end_incl, target); + if (result == -5) + return -1; + if (result < 0) + { + return 0; + } + } + + if (end_excl != NULL) + { + result = cmp_versions (end_excl, target); + if (result == -5) + return -1; + if (result <= 0) + { + return 0; + } + } + + return (1); +} + +static void +check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, report_host_t report_host, const char *host_cpe) +{ + iterator_t cpe_match_node_childs; + gchar *operator; + operator = sql_string ("SELECT operator FROM scap.cpe_match_nodes WHERE id = %llu", node); + init_cpe_match_node_childs_iterator (&cpe_match_node_childs, node); + while (next (&cpe_match_node_childs)) + { + long long int child_node; + child_node = cpe_match_node_childs_iterator_id (&cpe_match_node_childs); + check_cpe_match_rule (child_node, match, vulnerable, report_host, host_cpe); + if (strcmp (operator, "AND") == 0 && !(*match)) + return; + if (strcmp (operator, "OR") == 0 && (*match) && (*vulnerable)) + return; + } + iterator_t cpe_match_ranges; + init_cpe_match_range_iterator (&cpe_match_ranges, node); + while (next (&cpe_match_ranges)) + { + iterator_t cpe_host_details_products; + gchar *range_fs_cpe; + gchar *range_uri_product; + gchar *vsi, *vse, *vei, *vee; + range_fs_cpe = vsi = vse = vei = vee = NULL; + range_fs_cpe = g_strdup (cpe_match_range_iterator_cpe (&cpe_match_ranges)); + vsi = (gchar*) cpe_match_range_iterator_version_start_incl(&cpe_match_ranges); + if (vsi != NULL) + vsi = g_strdup (cpe_match_range_iterator_version_start_incl(&cpe_match_ranges)); + vse = g_strdup (cpe_match_range_iterator_version_start_excl(&cpe_match_ranges)); + vei = g_strdup (cpe_match_range_iterator_version_end_incl(&cpe_match_ranges)); + vee = g_strdup (cpe_match_range_iterator_version_end_excl(&cpe_match_ranges)); + range_uri_product = fs_cpe_to_uri_product (range_fs_cpe); + init_host_details_cpe_product_iterator (&cpe_host_details_products, range_uri_product, report_host); + while (next (&cpe_host_details_products)) + { + cpe_struct_t source, target; + const char *host_details_cpe; + gboolean matches; + host_details_cpe = host_details_cpe_product_iterator_value(&cpe_host_details_products); + cpe_struct_init (&source); + cpe_struct_init (&target); + fs_cpe_to_cpe_struct (range_fs_cpe, &source); + uri_cpe_to_cpe_struct (host_details_cpe, &target); + matches = cpe_struct_match (source, target); + if (matches) + { + int result; + result = check_version (target.version, vsi, vse, vei, vee); + if (result == 1) + *match = TRUE; + } + cpe_struct_free (&source); + cpe_struct_free (&target); + } + if (*match && cpe_match_range_iterator_vulnerable(&cpe_match_ranges) == 1) + { + cpe_struct_t source, target; + cpe_struct_init (&source); + cpe_struct_init (&target); + fs_cpe_to_cpe_struct (range_fs_cpe, &source); + uri_cpe_to_cpe_struct (host_cpe, &target); + if (cpe_struct_match (source, target)) + *vulnerable = TRUE; + cpe_struct_free (&source); + cpe_struct_free (&target); + } + g_free (range_uri_product); + g_free (range_fs_cpe); + g_free (vsi); + g_free (vse); + g_free (vei); + g_free (vee); + if (strcmp (operator, "AND") == 0 && !(*match)) + return; + if (strcmp (operator, "OR") == 0 && (*match) && (*vulnerable)) + return; + } +} + /** * @brief Perform a CVE "scan" on a host. * @@ -3161,89 +3296,218 @@ cve_scan_host (task_t task, report_t report, gvm_host_t *gvm_host) results = g_array_new (TRUE, TRUE, sizeof (result_t)); start_time = time (NULL); prognosis_report_host = 0; - init_host_prognosis_iterator (&prognosis, report_host); - while (next (&prognosis)) + + gboolean use_json = FALSE; + if (sql_int64_0 ("SELECT count(*) FROM scap.cpe_match_nodes") > 0) + use_json = TRUE; + + if (use_json) { - const char *app, *cve; - double severity; - gchar *desc; - iterator_t locations_iter; - GString *locations; - result_t result; + iterator_t host_details_cpe; + init_host_details_cpe_iterator (&host_details_cpe, report_host); + while (next (&host_details_cpe)) + { + iterator_t cpe_match_root_node; + iterator_t locations_iter; + result_t result; + char *cpe_product; + const char *host_cpe; + double severity; + + host_cpe = host_details_cpe_iterator_cpe (&host_details_cpe); + cpe_product = uri_cpe_to_fs_product (host_cpe); + init_cpe_match_nodes_iterator (&cpe_match_root_node, cpe_product); + while (next (&cpe_match_root_node)) + { + result_t root_node; + gboolean match, vulnerable; + const char *app, *cve; + + vulnerable = FALSE; + match = FALSE; + root_node = cpe_match_nodes_iterator_root_id (&cpe_match_root_node); + check_cpe_match_rule (root_node, &match, &vulnerable, report_host, host_cpe); + if (match && vulnerable) + { + GString *locations; + gchar *desc; + + if (prognosis_report_host == 0) + prognosis_report_host = manage_report_host_add (report, + ip, + start_time, + 0); + + severity = sql_double ("SELECT severity FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); + + app = host_cpe; + cve = sql_string ("SELECT name FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); + locations = g_string_new(""); + + insert_report_host_detail (global_current_report, ip, "cve", cve, + "CVE Scanner", "App", app, NULL); + + init_app_locations_iterator (&locations_iter, report_host, app); + + while (next (&locations_iter)) + { + const char *location; + location = app_locations_iterator_location (&locations_iter); + + if (location == NULL) + { + g_warning ("%s: Location is null for ip %s, app %s", + __func__, ip, app); + continue; + } + + if (locations->len) + { + g_string_append (locations, ", "); + } + g_string_append (locations, location); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", app, location, NULL); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_at", + location, NULL); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_by", + /* Detected by itself. */ + cve, NULL); + } + + const char *description; + description = sql_string ("SELECT description FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); - if (prognosis_report_host == 0) - prognosis_report_host = manage_report_host_add (report, - ip, - start_time, - 0); + desc = g_strdup_printf ("The host carries the product: %s\n" + "It is vulnerable according to: %s.\n" + "%s%s%s" + "\n" + "%s", + app, + cve, + locations->len + ? "The product was found at: " + : "", + locations->len ? locations->str : "", + locations->len ? ".\n" : "", + description); - severity = prognosis_iterator_cvss_double (&prognosis); + g_debug ("%s: making result with severity %1.1f desc [%s]", + __func__, severity, desc); - app = prognosis_iterator_cpe (&prognosis); - cve = prognosis_iterator_cve (&prognosis); - locations = g_string_new(""); + result = make_cve_result (task, ip, cve, severity, desc); + g_free (desc); - insert_report_host_detail (global_current_report, ip, "cve", cve, - "CVE Scanner", "App", app, NULL); + g_array_append_val (results, result); - init_app_locations_iterator (&locations_iter, report_host, app); + g_string_free (locations, TRUE); - while (next (&locations_iter)) + } + } + g_free (cpe_product); + } + cleanup_iterator (&host_details_cpe); + } + + if (!use_json) + { + init_host_prognosis_iterator (&prognosis, report_host); + while (next (&prognosis)) { - const char *location; - location = app_locations_iterator_location (&locations_iter); + const char *app, *cve; + double severity; + gchar *desc; + iterator_t locations_iter; + GString *locations; + result_t result; + + if (prognosis_report_host == 0) + prognosis_report_host = manage_report_host_add (report, + ip, + start_time, + 0); + + severity = prognosis_iterator_cvss_double (&prognosis); + + app = prognosis_iterator_cpe (&prognosis); + cve = prognosis_iterator_cve (&prognosis); + locations = g_string_new(""); + + insert_report_host_detail (global_current_report, ip, "cve", cve, + "CVE Scanner", "App", app, NULL); - if (location == NULL) + init_app_locations_iterator (&locations_iter, report_host, app); + + while (next (&locations_iter)) { - g_warning ("%s: Location is null for ip %s, app %s", - __func__, ip, app); - continue; - } + const char *location; + location = app_locations_iterator_location (&locations_iter); + + if (location == NULL) + { + g_warning ("%s: Location is null for ip %s, app %s", + __func__, ip, app); + continue; + } - if (locations->len) - g_string_append (locations, ", "); - g_string_append (locations, location); + if (locations->len) + g_string_append (locations, ", "); + g_string_append (locations, location); - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", app, location, NULL); + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", app, location, NULL); - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", "detected_at", - location, NULL); + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_at", + location, NULL); - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", "detected_by", - /* Detected by itself. */ - cve, NULL); - } + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_by", + /* Detected by itself. */ + cve, NULL); + } - desc = g_strdup_printf ("The host carries the product: %s\n" - "It is vulnerable according to: %s.\n" - "%s%s%s" - "\n" - "%s", - app, - cve, - locations->len - ? "The product was found at: " - : "", - locations->len ? locations->str : "", - locations->len ? ".\n" : "", - prognosis_iterator_description - (&prognosis)); - - g_debug ("%s: making result with severity %1.1f desc [%s]", - __func__, severity, desc); - - result = make_cve_result (task, ip, cve, severity, desc); - g_free (desc); - - g_array_append_val (results, result); - - g_string_free (locations, TRUE); + desc = g_strdup_printf ("The host carries the product: %s\n" + "It is vulnerable according to: %s.\n" + "%s%s%s" + "\n" + "%s", + app, + cve, + locations->len + ? "The product was found at: " + : "", + locations->len ? locations->str : "", + locations->len ? ".\n" : "", + prognosis_iterator_description + (&prognosis)); + + g_debug ("%s: making result with severity %1.1f desc [%s]", + __func__, severity, desc); + + result = make_cve_result (task, ip, cve, severity, desc); + g_free (desc); + + g_array_append_val (results, result); + + g_string_free (locations, TRUE); + } + cleanup_iterator (&prognosis); } - cleanup_iterator (&prognosis); - report_add_results_array (report, results); g_array_free (results, TRUE); diff --git a/src/manage.h b/src/manage.h index 0ee2e9c23..226f56753 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1688,7 +1688,52 @@ void init_app_locations_iterator (iterator_t*, report_host_t, const gchar *); const char * -app_locations_iterator_location (iterator_t *); +app_locations_iterator_location (iterator_t*); + +void +init_cpe_match_nodes_iterator (iterator_t*, const char *); + +long long int +cpe_match_nodes_iterator_root_id (iterator_t*); + +void +init_host_details_cpe_iterator (iterator_t*, report_host_t); + +const char* +host_details_cpe_iterator_cpe (iterator_t*); + +void +init_cpe_match_node_childs_iterator (iterator_t*, long long int); + +long long int +cpe_match_node_childs_iterator_id (iterator_t*); + +void +init_cpe_match_range_iterator (iterator_t*, long long int); + +const char* +cpe_match_range_iterator_cpe (iterator_t*); + +const char* +cpe_match_range_iterator_version_start_incl (iterator_t*); + +const char* +cpe_match_range_iterator_version_start_excl (iterator_t*); + +const char* +cpe_match_range_iterator_version_end_incl (iterator_t*); + +const char* +cpe_match_range_iterator_version_end_excl (iterator_t*); + +int +cpe_match_range_iterator_vulnerable (iterator_t*); + +void +init_host_details_cpe_product_iterator (iterator_t*, const char *, report_host_t); + +const char* +host_details_cpe_product_iterator_value (iterator_t*); void init_host_prognosis_iterator (iterator_t*, report_host_t); diff --git a/src/manage_pg.c b/src/manage_pg.c index dba91d68f..e4e8ca4b8 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -1589,6 +1589,8 @@ manage_create_sql_functions () " THEN $1 = 0" " WHEN 'false'" " THEN $1 = -1" + " WHEN 'error'" + " THEN $1 = -3" " ELSE 0::boolean" " END);" "$$ LANGUAGE SQL" @@ -3533,6 +3535,7 @@ manage_db_init (const gchar *name) sql ("CREATE TABLE scap2.cpe_match_nodes" " (id SERIAL PRIMARY KEY," " parent_id INTEGER DEFAULT 0," + " root_id INTEGER DEFAULT 0," " cve_id INTEGER DEFAULT 0," " operator text);"); @@ -3540,11 +3543,11 @@ manage_db_init (const gchar *name) " (id SERIAL PRIMARY KEY," " node_id INTEGER DEFAULT 0," " vulnerable INTEGER DEFAULT 0," - " cpe text," - " version_start_incl text," - " version_start_excl text," - " version_end_incl text," - " version_end_excl text);"); + " cpe text DEFAULT NULL," + " version_start_incl text DEFAULT NULL," + " version_start_excl text DEFAULT NULL," + " version_end_incl text DEFAULT NULL," + " version_end_excl text DEFAULT NULL);"); sql ("CREATE TABLE scap2.cpe_details" " (id SERIAL PRIMARY KEY," diff --git a/src/manage_sql.c b/src/manage_sql.c index c90a3a882..a3b67eb7b 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20446,6 +20446,198 @@ app_locations_iterator_location (iterator_t *iterator) return iterator_string (iterator, 0); } +/** + * @brief Initialize an iterator of CPEs for a report's host. + * + * @param[in] iterator Iterator. + * @param[in] report_host Report host. + */ +void +init_host_details_cpe_iterator (iterator_t* iterator, report_host_t report_host) +{ + init_iterator (iterator, + "SELECT LOWER (value) FROM report_host_details" + " WHERE name = 'App' and report_host = %llu;", + report_host); +} + +/** + * @brief Get a CPE from an CPE iterator. + * + * @param[in] iterator Iterator. + * + * @return The CPE. + */ +DEF_ACCESS (host_details_cpe_iterator_cpe, 0); + +/** + * @brief Initialize an iterator of CPEs for a product of a report's host. + * + * @param[in] iterator Iterator. + * @param[in] product The product for which to get the CPEs. + * @param[in] report_host Report host. + */ +void +init_host_details_cpe_product_iterator (iterator_t* iterator, const char *product, report_host_t report_host) +{ + gchar *quoted_product; + quoted_product = sql_quote (product); + init_iterator (iterator, + "SELECT DISTINCT LOWER (value) FROM report_host_details" + " WHERE name = 'App' AND report_host = %llu" + " AND value like '%s%s';", + report_host, quoted_product, "%"); + g_free (quoted_product); +} + +/** + * @brief Get a CPE from an CPE product iterator. + * + * @param[in] iterator Iterator. + * + * @return The CPE. + */ +DEF_ACCESS (host_details_cpe_product_iterator_value, 0); + +/** + * @brief Initialize an iterator of root_ids of CPE match nodes. + * + * @param[in] iterator Iterator. + * @param[in] cpe The cpe contained in the match nodes. + */ +void +init_cpe_match_nodes_iterator (iterator_t* iterator, const char *cpe) +{ + gchar *quoted_cpe; + quoted_cpe = sql_quote (cpe); + init_iterator (iterator, + "SELECT DISTINCT root_id" + " FROM scap.cpe_match_nodes, scap.cpe_match_range" + " WHERE cpe like '%s%s' AND scap.cpe_match_nodes.id = node_id;", + quoted_cpe, "%"); + g_free (quoted_cpe); +} + +/** + * @brief Get a root id from an CPE match node iterator. + * + * @param[in] iterator Iterator. + * + * @return The root id. + */ +long long int +cpe_match_nodes_iterator_root_id (iterator_t* iterator) +{ + return iterator_int64 (iterator, 0); +} + +/** + * @brief Initialize an iterator of childs of an CPE match node. + * + * @param[in] iterator Iterator. + * @param[in] node The match node with the childs. + */ +void +init_cpe_match_node_childs_iterator (iterator_t* iterator, long long int node) +{ + init_iterator (iterator, + "SELECT id FROM scap.cpe_match_nodes" + " WHERE parent_id = %llu;", + node); +} + +/** + * @brief Get a child from an CPE match node childs iterator. + * + * @param[in] iterator Iterator. + * + * @return The id of the child node. + */ +long long int +cpe_match_node_childs_iterator_id (iterator_t* iterator) +{ + return iterator_int64 (iterator, 0); +} + +/** + * @brief Initialize an iterator of match ranges of an CPE match node. + * + * @param[in] iterator Iterator. + * @param[in] node The match node with match ranges. + */ +void +init_cpe_match_range_iterator (iterator_t* iterator, long long int node) +{ + init_iterator (iterator, + "SELECT vulnerable, cpe, version_start_incl," + " version_start_excl, version_end_incl, version_end_excl" + " FROM scap.cpe_match_range" + " WHERE node_id = %llu;", + node); +} + +/** + * @brief Return if the CPE of the actual match node is vulnerable. + * + * @param[in] iterator Iterator. + * + * @return 1 if the match node is vulnerable, 0 otherwise. + */ +int +cpe_match_range_iterator_vulnerable (iterator_t* iterator) +{ + return iterator_int64 (iterator, 0); +} + +/** + * @brief Return the CPE of the actual match node. + * + * @param[in] iterator Iterator. + * + * @return The CPE of the actual match node. + */ +DEF_ACCESS (cpe_match_range_iterator_cpe, 1); + +/** + * @brief Return the start included version of the actual match node. + * + * @param[in] iterator Iterator. + * + * @return The start included version of the actual match node, if any. + * NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_version_start_incl, 2); + +/** + * @brief Return the start excluded version of the actual match node. + * + * @param[in] iterator Iterator. + * + * @return The start excluded version of the actual match node, if any. + * NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_version_start_excl, 3); + +/** + * @brief Return the end included version of the actual match node. + * + * @param[in] iterator Iterator. + * + * @return The end included version of the actual match node, if any. + * NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_version_end_incl, 4); + +/** + * @brief Return the end excluded version of the actual match node. + * + * @param[in] iterator Iterator. + * + * @return The end excluded version of the actual match node, if any. + * NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_version_end_excl, 5); + /** * @brief Initialise a report host prognosis iterator. * @@ -22357,6 +22549,16 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append (levels_sql, ", 'false'"); count++; } + if (strchr (levels, 'e')) + { + g_string_append (levels_sql, ", 'error'"); + count++; + } + if (strchr (levels, 'd')) + { + g_string_append (levels_sql, ", 'error'"); + count++; + } if (count == 0) { @@ -23086,6 +23288,8 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod_clause = where_qod (min_qod); + g_message ("PROTO1: %s", levels); + fflush (NULL); levels_clause = where_levels_auto (levels ? levels : "hmlgdf", given_new_severity_sql ? given_new_severity_sql @@ -23099,7 +23303,7 @@ results_extra_where (int trash, report_t report, const gchar* host, extra_where = g_strdup_printf("%s%s%s%s%s", report_clause ? report_clause : "", host_clause ? host_clause : "", - levels_clause->str, + (levels_clause && levels_clause->str) ? levels_clause->str : "", min_qod_clause ? min_qod_clause : "", compliance_levels_clause ?: ""); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index d189d83bb..e592f4606 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2703,7 +2703,9 @@ json_object_item_double (cJSON *object, char *key, double fallback) * @brief Save the node of a cve match rule tree. * * @param[in] parent_id The parent_id of the node. If this value is 0, - * this node is the root of the tree. + * the node is the root of the tree. + * @param[in] root_id The id of the root of the tree. If this value + * is 0, the node is the root of the tree. * @param[in] cve_id The id of the CVE to which the tree belongs. * @param[in] operator The operator for the match rules. * @@ -2737,7 +2739,6 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) cJSON *cpe_js; gboolean vulnerable = FALSE; - char * cpe = NULL; char * version_start_incl = NULL; char * version_start_excl = NULL; char * version_end_incl = NULL; @@ -2745,9 +2746,9 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) cJSON_ArrayForEach(match_rule, match_rules) { - char *quoted_cpe; + char *quoted_cpe = NULL; + char *sql_cpe = NULL; vulnerable = FALSE; - cpe = NULL; version_start_incl = NULL; version_start_excl = NULL; version_end_incl = NULL; @@ -2757,22 +2758,40 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) vulnerable = TRUE; else vulnerable = FALSE; + cpe_js = cJSON_GetObjectItemCaseSensitive(match_rule, "cpe23Uri"); - if (cpe_js != NULL) - cpe = cpe_js->valuestring; - quoted_cpe = sql_quote (cpe); + if (cpe_js != NULL && strcmp (cpe_js->valuestring, "(null)")) + { + quoted_cpe = sql_quote (cpe_js->valuestring); + sql_cpe = g_strdup_printf ("'%s'", quoted_cpe); + g_free (quoted_cpe); + } + else + sql_cpe = g_strdup ("NULL"); + ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionStartIncluding"); - if (ver_se != NULL) - version_start_incl = ver_se->valuestring; + if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) + version_start_incl = g_strdup_printf ("'%s'", ver_se->valuestring); + else + version_start_incl = g_strdup ("NULL"); + ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionStartExcluding"); - if (ver_se != NULL) - version_start_excl = ver_se->valuestring; + if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) + version_start_excl = g_strdup_printf ("'%s'", ver_se->valuestring); + else + version_start_excl = g_strdup ("NULL"); + ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionEndIncluding"); - if (ver_se != NULL) - version_end_incl = ver_se->valuestring; + if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) + version_end_incl = g_strdup_printf ("'%s'", ver_se->valuestring); + else + version_end_incl = g_strdup ("NULL"); + ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionEndExcluding"); - if (ver_se != NULL) - version_end_excl = ver_se->valuestring; + if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) + version_end_excl = g_strdup_printf ("'%s'", ver_se->valuestring); + else + version_end_excl = g_strdup ("NULL"); sql ("INSERT INTO scap2.cpe_match_range" @@ -2780,30 +2799,51 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) " version_start_incl, version_start_excl," " version_end_incl, version_end_excl)" " VALUES" - " (%llu, %d, '%s', '%s', '%s', '%s', '%s')", + " (%llu, %d, %s, %s, %s, %s, %s)", id, vulnerable ? 1 : 0, - quoted_cpe, - version_start_incl, - version_start_excl, - version_end_incl, - version_end_excl); - g_free (quoted_cpe); + sql_cpe ? sql_cpe : "", + version_start_incl ? version_start_incl : "", + version_start_excl ? version_start_excl : "", + version_end_incl ? version_end_incl : "", + version_end_excl ? version_end_excl : ""); + + g_free (sql_cpe); + g_free (version_start_incl); + g_free (version_start_excl); + g_free (version_end_incl); + g_free (version_end_excl); } } +/** + * @brief Set the root id for a node of a cve match rule tree. + * + * @param[in] id The id of the node for which the root id is to be set. + * @param[in] root_id The id of the root of the tree this node belongs to. + */ +static void +set_root_id (long int id, long int root_id) +{ + sql ("UPDATE scap2.cpe_match_nodes set root_id = %i" + " WHERE id = %i;", + root_id, + id); +} + /** * @brief Load and add recursively all nodes of a match rule tree for a * specific CVE. Build a match rule tree. * - * @param[in] parent_id The parent_id of the nodes to insert + * @param[in] parent_id The parent id of the nodes to insert * (0 for the root node). + * @param[in] root_id The root id of the nodes to insert * @param[in] cveid The id of the CVE the tree belongs to. * @param[in] nodes The JSON object that contains the rules for a * specific tree level. */ static void -load_nodes (resource_t parent_id, resource_t cveid, cJSON *nodes) +load_nodes (resource_t parent_id, resource_t cveid, resource_t root_id, cJSON *nodes) { cJSON *node; resource_t id; @@ -2823,13 +2863,22 @@ load_nodes (resource_t parent_id, resource_t cveid, cJSON *nodes) cJSON_ArrayForEach(node, nodes) { operator = cJSON_GetObjectItemCaseSensitive(node, "operator"); - if (operator) - id = save_node (parent_id, cveid, operator->valuestring); + if (operator && operator->valuestring) + { + id = save_node (parent_id, cveid, operator->valuestring); + } + else + return; + + if (parent_id == 0) + root_id = id; + set_root_id (id, root_id); + cpe_match_rules = cJSON_GetObjectItemCaseSensitive(node, "cpe_match"); if (cpe_match_rules) add_cpe_match_rules (id, cpe_match_rules); child_nodes = cJSON_GetObjectItemCaseSensitive(node, "children"); - load_nodes (id, cveid, child_nodes); + load_nodes (id, cveid, root_id, child_nodes); } } @@ -3007,7 +3056,7 @@ handle_json_cve_item (cJSON *item) g_warning("%s: nodes missing for %s.", __func__, cve_id); return -1; } - load_nodes (0, cve_db_id, nodes_json); + load_nodes (0, cve_db_id, 0, nodes_json); return 0; } From d0c6ffd8c925476de5a50bc89bcd171896f0f85f Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Tue, 24 Sep 2024 10:14:33 +0200 Subject: [PATCH 04/64] Small amendment. --- src/manage.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/manage.c b/src/manage.c index 97688b391..54b549754 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3298,7 +3298,9 @@ cve_scan_host (task_t task, report_t report, gvm_host_t *gvm_host) prognosis_report_host = 0; gboolean use_json = FALSE; - if (sql_int64_0 ("SELECT count(*) FROM scap.cpe_match_nodes") > 0) + if (sql_int64_0 ("SELECT count(1) FROM information_schema.tables" + " WHERE table_schema = 'scap'" + " AND table_name = 'cpe_match_nodes';") > 0) use_json = TRUE; if (use_json) From 271bd1e7ad20292afb2c5c4aaee0d1eba3775343 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Wed, 25 Sep 2024 13:24:27 +0200 Subject: [PATCH 05/64] Small amendment. --- src/manage_sql.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 5b19f2237..c468b3b5e 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20453,10 +20453,10 @@ app_locations_iterator_location (iterator_t *iterator) * @param[in] report_host Report host. */ void -init_host_details_cpe_iterator (iterator_t* iterator, report_host_t report_host) +init_host_details_cpe_iterator (iterator_t *iterator, report_host_t report_host) { init_iterator (iterator, - "SELECT LOWER (value) FROM report_host_details" + "SELECT DISTINCT LOWER (value) FROM report_host_details" " WHERE name = 'App' and report_host = %llu;", report_host); } From 821576749702907b03ae1c8f17b9e49867fac86a Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Thu, 17 Oct 2024 09:55:36 +0000 Subject: [PATCH 06/64] Automatic release to 24.0.0 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc7b71249..6ffdec4a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 23.10.1 + VERSION 24.0.0 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 1) +set (PROJECT_DEV_VERSION 0) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From 88cdf82af784e57ee65eea936b94044c663c7b3b Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Thu, 17 Oct 2024 09:55:38 +0000 Subject: [PATCH 07/64] Automatic adjustments after release [skip ci] * Update to version 24.0.1-dev1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ffdec4a2..9d3b36a5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 24.0.0 + VERSION 24.0.1 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 0) +set (PROJECT_DEV_VERSION 1) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From ed5123e29077dd2a5e73fc81326f3e2cab33ad31 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Fri, 18 Oct 2024 16:06:09 +0200 Subject: [PATCH 08/64] Some amendments. --- src/manage.c | 316 +++++++++++++++++++++------------------ src/manage_sql.c | 11 +- src/manage_sql_secinfo.c | 10 +- 3 files changed, 176 insertions(+), 161 deletions(-) diff --git a/src/manage.c b/src/manage.c index 54b549754..159d5fa60 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3165,6 +3165,8 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, { iterator_t cpe_match_node_childs; gchar *operator; + iterator_t cpe_match_ranges; + operator = sql_string ("SELECT operator FROM scap.cpe_match_nodes WHERE id = %llu", node); init_cpe_match_node_childs_iterator (&cpe_match_node_childs, node); while (next (&cpe_match_node_childs)) @@ -3177,7 +3179,7 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, if (strcmp (operator, "OR") == 0 && (*match) && (*vulnerable)) return; } - iterator_t cpe_match_ranges; + init_cpe_match_range_iterator (&cpe_match_ranges, node); while (next (&cpe_match_ranges)) { @@ -3187,12 +3189,10 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, gchar *vsi, *vse, *vei, *vee; range_fs_cpe = vsi = vse = vei = vee = NULL; range_fs_cpe = g_strdup (cpe_match_range_iterator_cpe (&cpe_match_ranges)); - vsi = (gchar*) cpe_match_range_iterator_version_start_incl(&cpe_match_ranges); - if (vsi != NULL) - vsi = g_strdup (cpe_match_range_iterator_version_start_incl(&cpe_match_ranges)); - vse = g_strdup (cpe_match_range_iterator_version_start_excl(&cpe_match_ranges)); - vei = g_strdup (cpe_match_range_iterator_version_end_incl(&cpe_match_ranges)); - vee = g_strdup (cpe_match_range_iterator_version_end_excl(&cpe_match_ranges)); + vsi = g_strdup (cpe_match_range_iterator_version_start_incl (&cpe_match_ranges)); + vse = g_strdup (cpe_match_range_iterator_version_start_excl (&cpe_match_ranges)); + vei = g_strdup (cpe_match_range_iterator_version_end_incl (&cpe_match_ranges)); + vee = g_strdup (cpe_match_range_iterator_version_end_excl (&cpe_match_ranges)); range_uri_product = fs_cpe_to_uri_product (range_fs_cpe); init_host_details_cpe_product_iterator (&cpe_host_details_products, range_uri_product, report_host); while (next (&cpe_host_details_products)) @@ -3200,12 +3200,12 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, cpe_struct_t source, target; const char *host_details_cpe; gboolean matches; - host_details_cpe = host_details_cpe_product_iterator_value(&cpe_host_details_products); + host_details_cpe = host_details_cpe_product_iterator_value (&cpe_host_details_products); cpe_struct_init (&source); cpe_struct_init (&target); fs_cpe_to_cpe_struct (range_fs_cpe, &source); uri_cpe_to_cpe_struct (host_details_cpe, &target); - matches = cpe_struct_match (source, target); + matches = cpe_struct_match (&source, &target); if (matches) { int result; @@ -3216,18 +3216,18 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, cpe_struct_free (&source); cpe_struct_free (&target); } - if (*match && cpe_match_range_iterator_vulnerable(&cpe_match_ranges) == 1) - { - cpe_struct_t source, target; - cpe_struct_init (&source); - cpe_struct_init (&target); - fs_cpe_to_cpe_struct (range_fs_cpe, &source); - uri_cpe_to_cpe_struct (host_cpe, &target); - if (cpe_struct_match (source, target)) - *vulnerable = TRUE; - cpe_struct_free (&source); - cpe_struct_free (&target); - } + if (*match && cpe_match_range_iterator_vulnerable (&cpe_match_ranges) == 1) + { + cpe_struct_t source, target; + cpe_struct_init (&source); + cpe_struct_init (&target); + fs_cpe_to_cpe_struct (range_fs_cpe, &source); + uri_cpe_to_cpe_struct (host_cpe, &target); + if (cpe_struct_match (&source, &target)) + *vulnerable = TRUE; + cpe_struct_free (&source); + cpe_struct_free (&target); + } g_free (range_uri_product); g_free (range_fs_cpe); g_free (vsi); @@ -3241,6 +3241,150 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, } } +/** + * @brief Perform the json CVE "scan" for the found report host. + * + * @param[in] task Task. + * @param[in] report The report to add the host, results and details to. + * @param[in] report_host The report host. + * @param[in] ip The ip of the report host. + * @param[in] start_time The start time of the scan. + * + * @param[out] prognosis_report_host The report_host with prognosis results + * and host details. + * @param[out] results The results of the scan. + */ +static void +cve_scan_report_host_json (task_t task, + report_t report, + report_host_t report_host, + gchar *ip, + int start_time, + int *prognosis_report_host, + GArray *results) +{ + iterator_t host_details_cpe; + init_host_details_cpe_iterator (&host_details_cpe, report_host); + while (next (&host_details_cpe)) + { + iterator_t cpe_match_root_node; + iterator_t locations_iter; + result_t result; + char *cpe_product; + const char *host_cpe; + double severity; + + g_message ("PROTO1: WHILE1"); + + host_cpe = host_details_cpe_iterator_cpe (&host_details_cpe); + cpe_product = uri_cpe_to_fs_product (host_cpe); + init_cpe_match_nodes_iterator (&cpe_match_root_node, cpe_product); + while (next (&cpe_match_root_node)) + { + result_t root_node; + gboolean match, vulnerable; + const char *app, *cve; + + vulnerable = FALSE; + match = FALSE; + root_node = cpe_match_nodes_iterator_root_id (&cpe_match_root_node); + check_cpe_match_rule (root_node, &match, &vulnerable, report_host, host_cpe); + if (match && vulnerable) + { + GString *locations; + gchar *desc; + + if (*prognosis_report_host == 0) + *prognosis_report_host = manage_report_host_add (report, + ip, + start_time, + 0); + + severity = sql_double ("SELECT severity FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); + + app = host_cpe; + cve = sql_string ("SELECT name FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); + locations = g_string_new (""); + + insert_report_host_detail (global_current_report, ip, "cve", cve, + "CVE Scanner", "App", app, NULL); + + init_app_locations_iterator (&locations_iter, report_host, app); + + while (next (&locations_iter)) + { + const char *location; + location = app_locations_iterator_location (&locations_iter); + + if (location == NULL) + { + g_warning ("%s: Location is null for ip %s, app %s", + __func__, ip, app); + continue; + } + + if (locations->len) + { + g_string_append (locations, ", "); + } + g_string_append (locations, location); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", app, location, NULL); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_at", + location, NULL); + + insert_report_host_detail (report, ip, "cve", cve, + "CVE Scanner", "detected_by", + /* Detected by itself. */ + cve, NULL); + } + + const char *description; + description = sql_string ("SELECT description FROM scap.cves, scap.cpe_match_nodes" + " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" + " AND scap.cpe_match_nodes.id = %llu;", + root_node); + + desc = g_strdup_printf ("The host carries the product: %s\n" + "It is vulnerable according to: %s.\n" + "%s%s%s" + "\n" + "%s", + app, + cve, + locations->len + ? "The product was found at: " + : "", + locations->len ? locations->str : "", + locations->len ? ".\n" : "", + description); + + g_debug ("%s: making result with severity %1.1f desc [%s]", + __func__, severity, desc); + + result = make_cve_result (task, ip, cve, severity, desc); + g_free (desc); + + g_array_append_val (results, result); + + g_string_free (locations, TRUE); + + } + } + g_free (cpe_product); + } + cleanup_iterator (&host_details_cpe); +} + /** * @brief Perform a CVE "scan" on a host. * @@ -3297,136 +3441,18 @@ cve_scan_host (task_t task, report_t report, gvm_host_t *gvm_host) start_time = time (NULL); prognosis_report_host = 0; - gboolean use_json = FALSE; if (sql_int64_0 ("SELECT count(1) FROM information_schema.tables" " WHERE table_schema = 'scap'" " AND table_name = 'cpe_match_nodes';") > 0) - use_json = TRUE; - - if (use_json) { - iterator_t host_details_cpe; - init_host_details_cpe_iterator (&host_details_cpe, report_host); - while (next (&host_details_cpe)) - { - iterator_t cpe_match_root_node; - iterator_t locations_iter; - result_t result; - char *cpe_product; - const char *host_cpe; - double severity; - - host_cpe = host_details_cpe_iterator_cpe (&host_details_cpe); - cpe_product = uri_cpe_to_fs_product (host_cpe); - init_cpe_match_nodes_iterator (&cpe_match_root_node, cpe_product); - while (next (&cpe_match_root_node)) - { - result_t root_node; - gboolean match, vulnerable; - const char *app, *cve; - - vulnerable = FALSE; - match = FALSE; - root_node = cpe_match_nodes_iterator_root_id (&cpe_match_root_node); - check_cpe_match_rule (root_node, &match, &vulnerable, report_host, host_cpe); - if (match && vulnerable) - { - GString *locations; - gchar *desc; - - if (prognosis_report_host == 0) - prognosis_report_host = manage_report_host_add (report, - ip, - start_time, - 0); - - severity = sql_double ("SELECT severity FROM scap.cves, scap.cpe_match_nodes" - " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" - " AND scap.cpe_match_nodes.id = %llu;", - root_node); - - app = host_cpe; - cve = sql_string ("SELECT name FROM scap.cves, scap.cpe_match_nodes" - " WHERE scap.cves.id = cpe_match_nodes.cve_id" - " AND scap.cpe_match_nodes.id = %llu;", - root_node); - locations = g_string_new(""); - - insert_report_host_detail (global_current_report, ip, "cve", cve, - "CVE Scanner", "App", app, NULL); - - init_app_locations_iterator (&locations_iter, report_host, app); - - while (next (&locations_iter)) - { - const char *location; - location = app_locations_iterator_location (&locations_iter); - - if (location == NULL) - { - g_warning ("%s: Location is null for ip %s, app %s", - __func__, ip, app); - continue; - } - - if (locations->len) - { - g_string_append (locations, ", "); - } - g_string_append (locations, location); - - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", app, location, NULL); - - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", "detected_at", - location, NULL); - - insert_report_host_detail (report, ip, "cve", cve, - "CVE Scanner", "detected_by", - /* Detected by itself. */ - cve, NULL); - } - - const char *description; - description = sql_string ("SELECT description FROM scap.cves, scap.cpe_match_nodes" - " WHERE scap.cves.id = scap.cpe_match_nodes.cve_id" - " AND scap.cpe_match_nodes.id = %llu;", - root_node); - - desc = g_strdup_printf ("The host carries the product: %s\n" - "It is vulnerable according to: %s.\n" - "%s%s%s" - "\n" - "%s", - app, - cve, - locations->len - ? "The product was found at: " - : "", - locations->len ? locations->str : "", - locations->len ? ".\n" : "", - description); - - g_debug ("%s: making result with severity %1.1f desc [%s]", - __func__, severity, desc); - - result = make_cve_result (task, ip, cve, severity, desc); - g_free (desc); - - g_array_append_val (results, result); - - g_string_free (locations, TRUE); - - } - } - g_free (cpe_product); - } - cleanup_iterator (&host_details_cpe); + // Use new JSON CVE scan + cve_scan_report_host_json (task, report, report_host, ip, + start_time, &prognosis_report_host, + results); } - - if (!use_json) + else { + // Use XML CVE scan init_host_prognosis_iterator (&prognosis, report_host); while (next (&prognosis)) { diff --git a/src/manage_sql.c b/src/manage_sql.c index c468b3b5e..d0746a186 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20513,8 +20513,8 @@ init_cpe_match_nodes_iterator (iterator_t* iterator, const char *cpe) init_iterator (iterator, "SELECT DISTINCT root_id" " FROM scap.cpe_match_nodes, scap.cpe_match_range" - " WHERE cpe like '%s%s' AND scap.cpe_match_nodes.id = node_id;", - quoted_cpe, "%"); + " WHERE cpe like '%s%%' AND scap.cpe_match_nodes.id = node_id;", + quoted_cpe); g_free (quoted_cpe); } @@ -22554,11 +22554,6 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append (levels_sql, ", 'error'"); count++; } - if (strchr (levels, 'd')) - { - g_string_append (levels_sql, ", 'error'"); - count++; - } if (count == 0) { @@ -23288,8 +23283,6 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod_clause = where_qod (min_qod); - g_message ("PROTO1: %s", levels); - fflush (NULL); levels_clause = where_levels_auto (levels ? levels : "hmlgdf", given_new_severity_sql ? given_new_severity_sql diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 6b552f035..2ecf26ec3 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2704,8 +2704,6 @@ json_object_item_double (cJSON *object, char *key, double fallback) * * @param[in] parent_id The parent_id of the node. If this value is 0, * the node is the root of the tree. - * @param[in] root_id The id of the root of the tree. If this value - * is 0, the node is the root of the tree. * @param[in] cve_id The id of the CVE to which the tree belongs. * @param[in] operator The operator for the match rules. * @@ -2837,8 +2835,8 @@ set_root_id (long int id, long int root_id) * * @param[in] parent_id The parent id of the nodes to insert * (0 for the root node). - * @param[in] root_id The root id of the nodes to insert * @param[in] cveid The id of the CVE the tree belongs to. + * @param[in] root_id The root id of the nodes to insert. * @param[in] nodes The JSON object that contains the rules for a * specific tree level. */ @@ -2864,14 +2862,12 @@ load_nodes (resource_t parent_id, resource_t cveid, resource_t root_id, cJSON *n { operator = cJSON_GetObjectItemCaseSensitive(node, "operator"); if (operator && operator->valuestring) - { - id = save_node (parent_id, cveid, operator->valuestring); - } + id = save_node (parent_id, cveid, operator->valuestring); else return; if (parent_id == 0) - root_id = id; + root_id = id; set_root_id (id, root_id); cpe_match_rules = cJSON_GetObjectItemCaseSensitive(node, "cpe_match"); From 94377da9dc8e81e49906b38ae0b6246698b022e8 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Fri, 18 Oct 2024 17:18:12 +0200 Subject: [PATCH 09/64] Removed stray (debug) message. --- src/manage.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/manage.c b/src/manage.c index 159d5fa60..fca82209f 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3274,8 +3274,6 @@ cve_scan_report_host_json (task_t task, const char *host_cpe; double severity; - g_message ("PROTO1: WHILE1"); - host_cpe = host_details_cpe_iterator_cpe (&host_details_cpe); cpe_product = uri_cpe_to_fs_product (host_cpe); init_cpe_match_nodes_iterator (&cpe_match_root_node, cpe_product); From 02cb67fd6983ae792946081149b9824187952397 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 21 Oct 2024 13:20:59 +0200 Subject: [PATCH 10/64] Add: Added reading of gzip files for CVEs and EPSS. --- src/manage_sql_secinfo.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index a12e4f256..9496964c1 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -3046,7 +3047,7 @@ update_cve_json (const gchar *cve_path, GHashTable *hashed_cpes) g_info ("Updating %s", full_path); - cve_file = fdopen (fd, "r"); + cve_file = gvm_gzip_open_file_reader_fd (fd); if (cve_file == NULL) { g_warning ("%s: Failed to open CVE file: %s", @@ -3283,7 +3284,8 @@ update_scap_cves () gboolean read_json = FALSE; while ((cve_path = g_dir_read_name (dir))) { - if (fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) + if (fnmatch ("nvdcve-1.1-*.json.gz", cve_path, 0) == 0 || + fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) { read_json = TRUE; break; @@ -3294,7 +3296,9 @@ update_scap_cves () count = 0; while ((cve_path = g_dir_read_name (dir))) { - if ((fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) && read_json) + if ((fnmatch ("nvdcve-1.1-*.json.gz", cve_path, 0) == 0 || + fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) + && read_json) { if (update_cve_json (cve_path, hashed_cpes)) { @@ -3380,10 +3384,19 @@ update_epss_scores () inserts_t inserts; current_json_path = g_build_filename (GVM_SCAP_DATA_DIR, - "epss-scores-current.json", + "epss-scores-current.json.gz", NULL); int fd = open(current_json_path, O_RDONLY); + if (fd < 0 && errno == ENOENT) + { + g_free (current_json_path); + current_json_path = g_build_filename (GVM_SCAP_DATA_DIR, + "epss-scores-current.json", + NULL); + fd = open(current_json_path, O_RDONLY); + } + if (fd < 0) { int ret; @@ -3403,7 +3416,7 @@ update_epss_scores () return ret; } - epss_scores_file = fdopen(fd, "r"); + epss_scores_file = gvm_gzip_open_file_reader_fd (fd); if (epss_scores_file == NULL) { g_warning ("%s: Failed to convert file descriptor to FILE*: %s", From e76cc69150531b119ad19130b6707657ddd8a62f Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 21 Oct 2024 15:43:02 +0200 Subject: [PATCH 11/64] Change: Log to stderr, new log file build option. Now the log messages are logged to stderr by default. The log file for the generated gvmd_log.conf can now be set by a new build option GVMD_LOG_FILE. --- CMakeLists.txt | 15 ++++++++++----- src/gvmd_log_conf.cmake_in | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d3b36a5a..ec0d19b3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,11 +163,15 @@ if (NOT GVMD_STATE_DIR) set (GVMD_STATE_DIR "${GVM_STATE_DIR}/gvmd") endif (NOT GVMD_STATE_DIR) -if (NOT GVM_LOG_DIR) - set (GVM_LOG_DIR "${LOCALSTATEDIR}/log/gvm") -else (NOT GVM_LOG_DIR) - set (GVM_LOG_DIR "${GVM_LOG_DIR}") -endif (NOT GVM_LOG_DIR) +if (NOT GVMD_LOG_FILE) + if (GVM_LOG_DIR) + set (GVMD_LOG_FILE "${GVM_LOG_DIR}/gvmd.log") + else (GVM_LOG_DIR) + set (GVMD_LOG_FILE "-") + endif (GVMD_LOG_DIR) +else (NOT GVMD_LOG_FILE) + set (GVMD_LOG_FILE "${GVMD_LOG_FILE}") +endif (NOT GVMD_LOG_FILE) set (GVM_SCAP_RES_DIR "${GVM_DATA_DIR}/scap") set (GVM_CERT_RES_DIR "${GVM_DATA_DIR}/cert") @@ -253,6 +257,7 @@ endif (NOT COMPLIANCE_REPORTS) add_definitions (-DCOMPLIANCE_REPORTS=${COMPLIANCE_REPORTS}) message ("-- Install prefix: ${CMAKE_INSTALL_PREFIX}") +message ("-- Log file: ${GVMD_LOG_FILE}") ## Version diff --git a/src/gvmd_log_conf.cmake_in b/src/gvmd_log_conf.cmake_in index fd0c375a0..e5dcc3d73 100644 --- a/src/gvmd_log_conf.cmake_in +++ b/src/gvmd_log_conf.cmake_in @@ -7,63 +7,63 @@ prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [md manage] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [md gmp] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [md crypt] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [md utils] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [libgvm base] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [libgvm gmp] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [libgvm osp] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [libgvm util] prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 [event syslog] @@ -86,5 +86,5 @@ level=128 prepend=%t %s %p separator=: prepend_time_format=%Y-%m-%d %Hh%M.%S %Z -file=${GVM_LOG_DIR}/gvmd.log +file=${GVMD_LOG_FILE} level=127 From cfc885af072e6a6e0804116d7022f4141c8320a8 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Tue, 22 Oct 2024 10:13:56 +0200 Subject: [PATCH 12/64] Changed location of initialization of "*quoted_cpe". --- src/manage_sql_secinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 2ecf26ec3..6230408de 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2744,7 +2744,6 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) cJSON_ArrayForEach(match_rule, match_rules) { - char *quoted_cpe = NULL; char *sql_cpe = NULL; vulnerable = FALSE; version_start_incl = NULL; @@ -2760,7 +2759,7 @@ add_cpe_match_rules (result_t id, cJSON *match_rules) cpe_js = cJSON_GetObjectItemCaseSensitive(match_rule, "cpe23Uri"); if (cpe_js != NULL && strcmp (cpe_js->valuestring, "(null)")) { - quoted_cpe = sql_quote (cpe_js->valuestring); + char *quoted_cpe = sql_quote (cpe_js->valuestring); sql_cpe = g_strdup_printf ("'%s'", quoted_cpe); g_free (quoted_cpe); } From 2168aa40aca3266fe64e538ee6bed4756b7e1535 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Tue, 22 Oct 2024 10:22:26 +0200 Subject: [PATCH 13/64] Removed the option "e" for the display of errors. --- src/manage_sql.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index d0746a186..fc1bf3905 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -22549,11 +22549,6 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append (levels_sql, ", 'false'"); count++; } - if (strchr (levels, 'e')) - { - g_string_append (levels_sql, ", 'error'"); - count++; - } if (count == 0) { From d0f409e1f496ccdeb10516a6ae8f5b476d8423f5 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 30 Sep 2024 11:36:22 +0200 Subject: [PATCH 14/64] Change: Adjust loading of CPEs to new JSON API CPEs can now be loaded from JSON files based on the NVD API. As some fields in the old XML differ the JSON API, they are replaced by similar fields: "nvd_id" is replaced by "cpe_name_id" and "status" is replaced by "deprecated". The "raw_data" will no longer be available after switching to JSON, so the references are and "deprecated_by" element are handled explictly. These changes are made because the XML-based data feeds have been deprecated by NVD. --- CMakeLists.txt | 2 +- src/gmp.c | 35 +- src/manage.h | 18 +- src/manage_pg.c | 12 +- src/manage_sql_secinfo.c | 619 +++++++++++++++++++++++++++--- src/manage_sql_secinfo.h | 6 +- src/schema_formats/XML/GMP.xml.in | 41 +- 7 files changed, 650 insertions(+), 83 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d3b36a5a..eb6b215d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,7 @@ include (CPack) set (GVMD_DATABASE_VERSION 256) -set (GVMD_SCAP_DATABASE_VERSION 21) +set (GVMD_SCAP_DATABASE_VERSION 22) set (GVMD_CERT_DATABASE_VERSION 8) diff --git a/src/gmp.c b/src/gmp.c index 8ede8d6a9..ac95a6f67 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13473,24 +13473,33 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) "%s", cpe_info_iterator_title (&info)); xml_string_append (result, - "%s" + "%s" "%s" "%s" - "%s", - cpe_info_iterator_nvd_id (&info) - ? cpe_info_iterator_nvd_id (&info) + "%s", + cpe_info_iterator_cpe_name_id (&info) + ? cpe_info_iterator_cpe_name_id (&info) : "", cpe_info_iterator_severity (&info) ? cpe_info_iterator_severity (&info) : "", cpe_info_iterator_cve_refs (&info), - cpe_info_iterator_status (&info) - ? cpe_info_iterator_status (&info) - : ""); + cpe_info_iterator_deprecated (&info) + ? cpe_info_iterator_deprecated (&info) + : "0"); if (get_info_data->details == 1) { - iterator_t cves; + const char *deprecated_by_id + = cpe_info_iterator_deprecated_by_id (&info); + if (deprecated_by_id && strcmp (deprecated_by_id, "")) + { + xml_string_append (result, + "%s", + deprecated_by_id); + } + + iterator_t cves, refs; g_string_append (result, ""); init_cpe_cve_iterator (&cves, get_iterator_name (&info), 0, NULL); while (next (&cves)) @@ -13518,6 +13527,16 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) : ""); cleanup_iterator (&cves); g_string_append (result, ""); + + g_string_append (result, ""); + init_cpe_reference_iterator (&refs, get_iterator_name (&info)); + while (next (&refs)) + xml_string_append (result, + "%s", + cpe_reference_iterator_href (&refs), + cpe_reference_iterator_type (&refs)); + cleanup_iterator (&refs); + g_string_append (result, ""); } } else if (g_strcmp0 ("cve", get_info_data->type) == 0) diff --git a/src/manage.h b/src/manage.h index 0ee2e9c23..6d34f02f9 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3355,23 +3355,33 @@ const char* cpe_info_iterator_title (iterator_t*); const char* -cpe_info_iterator_status (iterator_t*); +cpe_info_iterator_deprecated (iterator_t*); const char * cpe_info_iterator_severity (iterator_t*); const char* -cpe_info_iterator_deprecated_by_id (iterator_t*); +cpe_info_iterator_cve_refs (iterator_t*); const char* -cpe_info_iterator_cve_refs (iterator_t*); +cpe_info_iterator_cpe_name_id (iterator_t*); const char* -cpe_info_iterator_nvd_id (iterator_t*); +cpe_info_iterator_deprecated_by_id (iterator_t*); gchar * cpe_details_xml (const char*); +void +init_cpe_reference_iterator (iterator_t *, const char *); + +const char* +cpe_reference_iterator_href (iterator_t *); + +const char* +cpe_reference_iterator_type (iterator_t *); + + /* CVE. */ const char* diff --git a/src/manage_pg.c b/src/manage_pg.c index dba91d68f..7088a4e9c 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3525,10 +3525,18 @@ manage_db_init (const gchar *name) " modification_time integer," " title text," " status text," - " deprecated_by_id INTEGER," + " deprecated_by_id TEXT," " severity DOUBLE PRECISION DEFAULT 0," " cve_refs INTEGER DEFAULT 0," - " nvd_id text);"); + " nvd_id text," + " deprecated integer," + " cpe_name_id text);"); + + sql ("CREATE TABLE scap2.cpe_refs" + " (id SERIAL PRIMARY KEY," + " cpe INTEGER," + " ref TEXT," + " type TEXT);"); sql ("CREATE TABLE scap2.cpe_match_nodes" " (id SERIAL PRIMARY KEY," diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index a12e4f256..b03413453 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -377,6 +378,72 @@ inserts_run (inserts_t *inserts, gboolean finalize) inserts_free_statements (inserts); } +/** + * @brief Get the string value for a specified key from a JSON object. + * + * @param[in] object JSON object + * @param[in] key The key of the string in the JSON object. + * + * @return The string out of the JSON object with key "key", if any. + * NULL otherwise. + */ +static char* +json_object_item_string (cJSON *object, char *key) +{ + cJSON *value_json; + + value_json = cJSON_GetObjectItemCaseSensitive(object, key); + if (cJSON_IsString(value_json)) + return value_json->valuestring; + return NULL; +} + +/** + * @brief Get the double value for a specified key from a JSON object. + * + * @param[in] object JSON object + * @param[in] key The key of the double value in the JSON object. + * @param[in] fallback The fallback value if the double value is not + * available. + * + * @return The double value out of the JSON object with key "key", if any. + * The fallback value otherwise. + */ +static double +json_object_item_double (cJSON *object, char *key, double fallback) +{ + cJSON *value_json; + + value_json = cJSON_GetObjectItemCaseSensitive(object, key); + if (cJSON_IsNumber(value_json)) + return value_json->valuedouble; + return fallback; +} + +/** + * @brief Get the boolean value for a specified key from a JSON object. + * + * @param[in] object JSON object + * @param[in] key The key of the double value in the JSON object. + * @param[in] fallback The fallback value if the boolean value is not + * available. + * + * @return The double value out of the JSON object with key "key", if any. + * The fallback value otherwise. + */ +static int +json_object_item_boolean (cJSON *object, char *key, int fallback) +{ + cJSON *value_json; + + value_json = cJSON_GetObjectItemCaseSensitive(object, key); + if (cJSON_IsTrue(value_json)) + return 1; + else if (cJSON_IsFalse(value_json)) + return 0; + return fallback; +} + /* CPE data. */ @@ -495,14 +562,25 @@ init_cpe_info_iterator_all (iterator_t* iterator, get_data_t *get) DEF_ACCESS (cpe_info_iterator_title, GET_ITERATOR_COLUMN_COUNT); /** - * @brief Get the status from a CPE iterator. + * @brief Get the deprecation status from a CPE iterator. * * @param[in] iterator Iterator. * - * @return The Status of the CPE, or NULL if iteration is complete. Freed by - * cleanup_iterator. + * @return The deprecation status of the CPE, or NULL if iteration is complete. + * Freed by cleanup_iterator. + */ +DEF_ACCESS (cpe_info_iterator_deprecated, GET_ITERATOR_COLUMN_COUNT + 1); + +/** + * @brief Get the first CPE the current one is deprecated by + * from a CPE iterator. + * + * @param[in] iterator Iterator. + * + * @return The first CPE the current one is deprecated by, + * or NULL if iteration is complete. Freed by cleanup_iterator. */ -DEF_ACCESS (cpe_info_iterator_status, GET_ITERATOR_COLUMN_COUNT + 1); +DEF_ACCESS (cpe_info_iterator_deprecated_by_id, GET_ITERATOR_COLUMN_COUNT + 2); /** * @brief Get the highest severity Score of all CVE's referencing this cpe. @@ -525,14 +603,14 @@ DEF_ACCESS (cpe_info_iterator_severity, GET_ITERATOR_COLUMN_COUNT + 3); DEF_ACCESS (cpe_info_iterator_cve_refs, GET_ITERATOR_COLUMN_COUNT + 4); /** - * @brief Get the NVD ID for this CPE. + * @brief Get the NVD assigned cpeNameId for this CPE. * * @param[in] iterator Iterator. * * @return The NVD ID of this CPE, or NULL if iteration is * complete. Freed by cleanup_iterator. */ -DEF_ACCESS (cpe_info_iterator_nvd_id, GET_ITERATOR_COLUMN_COUNT + 5); +DEF_ACCESS (cpe_info_iterator_cpe_name_id, GET_ITERATOR_COLUMN_COUNT + 5); /** * @brief Get the XML details / raw data for a given CPE ID. @@ -553,6 +631,44 @@ cpe_details_xml (const char *cpe_id) { return details_xml; } +/** + * @brief Initialise a CPE refrerences iterator. + * + * @param[in] iterator Iterator. + * @param[in] cpe CPE to get references of. + */ +void +init_cpe_reference_iterator (iterator_t *iterator, const char *cpe) +{ + gchar *quoted_cpe; + quoted_cpe = sql_quote (cpe); + init_iterator (iterator, + "SELECT ref, type FROM cpe_refs" + " WHERE cpe = (SELECT id FROM cpes WHERE uuid = '%s');", + quoted_cpe); + g_free (quoted_cpe); +} + +/** + * @brief Get the reference URL from CPE reference iterator. + * + * @param[in] iterator Iterator. + * + * @return The reference URL, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (cpe_reference_iterator_href, 0); + +/** + * @brief Get the reference type from CPE reference iterator. + * + * @param[in] iterator Iterator. + * + * @return The reference type, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (cpe_reference_iterator_type, 1); + /* CVE data. */ @@ -1895,6 +2011,29 @@ update_cert_bund_advisories (int last_cert_update) /* SCAP update: CPEs. */ +/** + * @brief Convert a CPE name from formatted string to URI and SQL quote it. + * + * @param[in] name Name. + * + * @return URI converted uoted name. + */ +static gchar * +fs_to_uri_convert_and_quote_cpe_name (const char *name) +{ + gchar *name_converted, *name_decoded, *name_tilde, *quoted_name; + + name_converted = fs_cpe_to_uri_cpe (name); + name_decoded = g_uri_unescape_string (name_converted, NULL); + name_tilde = string_replace (name_decoded, + "~", "%7E", "%7e", NULL); + g_free (name_decoded); + g_free (name_converted); + quoted_name = sql_quote (name_tilde); + g_free (name_tilde); + return quoted_name; +} + /** * @brief Decode and SQL quote a CPE name. * @@ -1917,7 +2056,7 @@ decode_and_quote_cpe_name (const char *name) } /** - * @brief Insert a SCAP CPE. + * @brief Insert a SCAP CPE from XML. * * @param[in] inserts Pointer to SQL buffer. * @param[in] cpe_item CPE item XML element. @@ -2081,14 +2220,408 @@ insert_scap_cpe_details (inserts_t *inserts, element_t cpe_item) } /** - * @brief Update SCAP CPEs from a file. + * @brief Try to skip to the products list in a CPEs JSON parser. + * + * @param[in] parser Parser to skip elements in. + * @param[in] event Parser event structure. + * + * @return 0 success, -1 error. + */ +static int +scap_cpes_json_skip_to_products (gvm_json_pull_parser_t *parser, + gvm_json_pull_event_t *event) +{ + gvm_json_pull_parser_next (parser, event); + if (event->type == GVM_JSON_PULL_EVENT_ERROR) + { + g_warning ("%s: Parser error: %s", __func__, event->error_message); + return -1; + } + else if (event->type != GVM_JSON_PULL_EVENT_OBJECT_START) + { + g_warning ("%s: CPEs file content is not a JSON object.", __func__); + return -1; + } + + gboolean products_found = FALSE; + while (!products_found) + { + gvm_json_pull_parser_next (parser, event); + gvm_json_path_elem_t *path_tail = g_queue_peek_tail (event->path); + if (event->type == GVM_JSON_PULL_EVENT_ARRAY_START && path_tail && + path_tail->key && strcmp (path_tail->key, "products") == 0) + { + products_found = TRUE; + } + else if (event->type == GVM_JSON_PULL_EVENT_ERROR) + { + g_warning ("%s: Parser error: %s", __func__, event->error_message); + return -1; + } + else if (event->type == GVM_JSON_PULL_EVENT_OBJECT_END) + { + g_warning ("%s: Unexpected json object end.", __func__); + return -1; + } + } + gvm_json_pull_parser_next (parser, event); + + return 0; +} + +/** + * @brief Insert a SCAP CPE from JSON. + * + * @param[in] inserts Pointer to SQL buffer. + * @param[in] product_item JSON object from the products list. + * + * @return 0 success, -1 error. + */ +static int +handle_json_cpe_item (inserts_t *inserts, cJSON *product_item) +{ + cJSON *cpe_item; + char *name, *cpe_name_id, *last_modified, *title_text; + char *deprecated_by; + gchar *quoted_name, *quoted_title, *quoted_cpe_name_id; + gchar *quoted_deprecated_by; + cJSON *titles, *title; + time_t modification_time; + int deprecated; + int first; + + assert (inserts); + + cpe_item = cJSON_GetObjectItemCaseSensitive (product_item, "cpe"); + if (! cJSON_IsObject (cpe_item)) + { + g_warning ("%s: 'cpe' field in product missing or not an object", + __func__); + return -1; + } + + name = json_object_item_string (cpe_item, "cpeName"); + if (name == NULL) + { + g_warning ("%s: 'cpeName' field missing or not a string", __func__); + return -1; + } + + cpe_name_id = json_object_item_string (cpe_item, "cpeNameId"); + if (cpe_name_id == NULL) + { + g_warning ("%s: 'cpeNameId' field missing or not a string", __func__); + return -1; + } + + last_modified = json_object_item_string (cpe_item, "lastModified"); + if (last_modified == NULL) + { + g_warning ("%s: 'lastModified' field missing or not a string", __func__); + return -1; + } + modification_time = parse_iso_time (last_modified); + + titles = cJSON_GetObjectItemCaseSensitive (cpe_item, "titles"); + if (! cJSON_IsArray (titles)) + { + g_warning ("%s: 'titles' field missing or not an array", __func__); + return -1; + } + + title_text = NULL; + cJSON_ArrayForEach (title, titles) + { + gchar *lang = json_object_item_string (title, "lang"); + if (lang && strcmp (lang, "en") == 0) + { + title_text = json_object_item_string (title, "title"); + break; + } + } + + deprecated = json_object_item_boolean (cpe_item, "deprecated", -1); + if (deprecated == -1) + { + g_warning ("%s: 'deprecated' field missing or not a boolean", __func__); + return -1; + } + + deprecated_by = NULL; + if (deprecated) + { + /* CPEs can have multiple deprecatedBy entries, + * but for the GMP field only the first one is used */ + cJSON *deprecated_by_array, *first_deprecated_by; + deprecated_by_array = cJSON_GetObjectItemCaseSensitive (cpe_item, + "deprecatedBy"); + if (! cJSON_IsArray (deprecated_by_array)) + { + g_warning ("%s: 'deprecatedBy' field missing or not an array", + __func__); + return -1; + } + else if (cJSON_GetArraySize (deprecated_by_array) == 0) + { + g_warning ("%s: 'deprecatedBy' array is empty", + __func__); + return -1; + } + + first_deprecated_by = cJSON_GetArrayItem (deprecated_by_array, 0); + deprecated_by = json_object_item_string (first_deprecated_by, "cpeName"); + if (deprecated_by == NULL) + { + g_warning ("%s: Could not get 'cpeName' string from 'deprecatedBy'", + __func__); + return -1; + } + } + + quoted_name = fs_to_uri_convert_and_quote_cpe_name (name); + quoted_cpe_name_id = sql_quote (cpe_name_id); + quoted_title = sql_quote (title_text ? title_text : ""); + quoted_deprecated_by + = deprecated_by ? fs_to_uri_convert_and_quote_cpe_name (deprecated_by) + : NULL; + + first = inserts_check_size (inserts); + + g_string_append_printf (inserts->statement, + "%s ('%s', '%s', '%s', %li, %li, %d, '%s', '%s')", + first ? "" : ",", + quoted_name, + quoted_name, + quoted_title, + modification_time, + modification_time, + deprecated, + quoted_deprecated_by ? quoted_deprecated_by : "", + quoted_cpe_name_id); + + inserts->current_chunk_size++; + + g_free (quoted_title); + g_free (quoted_name); + g_free (quoted_cpe_name_id); + g_free (quoted_deprecated_by); + + return 0; +} + +/** + * @brief Insert a SCAP CPE from JSON. + * + * @param[in] inserts Pointer to SQL buffer. + * @param[in] product_item JSON object from the products list. + * + * @return 0 success, -1 error. + */ +static int +handle_json_cpe_refs (inserts_t *inserts, cJSON *product_item) +{ + cJSON *cpe_item, *refs, *refs_item; + gchar *name, *quoted_name; + + assert (inserts); + + cpe_item = cJSON_GetObjectItemCaseSensitive (product_item, "cpe"); + if (! cJSON_IsObject (cpe_item)) + { + g_warning ("%s: 'cpe' field in product missing or not an object", + __func__); + return -1; + } + + name = json_object_item_string (cpe_item, "cpeName"); + if (name == NULL) + { + g_warning ("%s: 'cpeName' field missing or not a string", __func__); + return -1; + } + + refs = cJSON_GetObjectItemCaseSensitive (cpe_item, "refs"); + if (! cJSON_IsArray (refs)) + { + g_debug ("%s: 'refs' field missing or not an array", __func__); + return 0; + } + + quoted_name = fs_to_uri_convert_and_quote_cpe_name (name); + cJSON_ArrayForEach (refs_item, refs) + { + int first; + char *ref, *type; + gchar *quoted_ref, *quoted_type; + ref = json_object_item_string (refs_item, "ref"); + if (ref == NULL) + { + g_warning ("%s: 'ref' field missing or not a string", __func__); + g_free (quoted_name); + return -1; + } + type = json_object_item_string (refs_item, "type"); + quoted_ref = sql_quote (ref ? ref : ""); + quoted_type = sql_quote (type ? type : ""); + + first = inserts_check_size (inserts); + + g_string_append_printf (inserts->statement, + "%s ('%s', '%s', '%s')", + first ? "" : ",", + quoted_name, + quoted_ref, + quoted_type); + + inserts->current_chunk_size++; + } + g_free (quoted_name); + + return 0; +} + +/** + * @brief Update SCAP CPEs from a JSON file. * * @param[in] path Path to file. * * @return 0 success, -1 error. */ static int -update_scap_cpes_from_file (const gchar *path) +update_scap_cpes_from_json_file (const gchar *path) +{ + inserts_t inserts; + gvm_json_pull_parser_t parser; + gvm_json_pull_event_t event; + FILE *json_stream = fopen (path, "r"); + if (json_stream == NULL) + { + g_warning ("%s: Could not open file '%s': %s", + __func__, path, strerror(errno)); + return -1; + } + + gvm_json_pull_parser_init (&parser, json_stream); + gvm_json_pull_event_init (&event); + if (scap_cpes_json_skip_to_products (&parser, &event)) + { + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (json_stream); + return -1; + } + + sql_begin_immediate (); + inserts_init (&inserts, + CPE_MAX_CHUNK_SIZE, + setting_secinfo_sql_buffer_threshold_bytes (), + "INSERT INTO scap2.cpes" + " (uuid, name, title, creation_time," + " modification_time, deprecated, deprecated_by_id," + " cpe_name_id)" + " VALUES", + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.name," + " title = EXCLUDED.title," + " creation_time = EXCLUDED.creation_time," + " modification_time = EXCLUDED.modification_time," + " deprecated = EXCLUDED.deprecated," + " deprecated_by_id = EXCLUDED.deprecated_by_id," + " cpe_name_id = EXCLUDED.cpe_name_id"); + + while (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) + { + gchar *error_message; + cJSON *entry = gvm_json_pull_expand_container (&parser, &error_message); + if (error_message) + { + g_warning ("%s: Error expanding CVE item: %s", __func__, error_message); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + cJSON_Delete (entry); + fclose (json_stream); + sql_commit (); + return -1; + } + if (handle_json_cpe_item (&inserts, entry)) + { + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + cJSON_Delete (entry); + fclose (json_stream); + sql_commit (); + return -1; + } + cJSON_Delete (entry); + gvm_json_pull_parser_next (&parser, &event); + } + inserts_run (&inserts, TRUE); + sql_commit (); + gvm_json_pull_parser_cleanup (&parser); + + // Reset and insert refs + fseek (json_stream, 0, SEEK_SET); + gvm_json_pull_parser_init (&parser, json_stream); + + if (scap_cpes_json_skip_to_products (&parser, &event)) + { + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (json_stream); + return -1; + } + + sql_begin_immediate (); + inserts_init (&inserts, 10, + setting_secinfo_sql_buffer_threshold_bytes (), + "INSERT INTO scap2.cpe_refs (cpe, ref, type)" + " SELECT scap2.cpes.id, new_refs.ref, new_refs.type" + " FROM scap2.cpes JOIN (VALUES ", + ") AS new_refs (cpe_name, ref, type)" + " ON scap2.cpes.name = cpe_name;"); + + while (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) + { + gchar *error_message; + cJSON *entry = gvm_json_pull_expand_container (&parser, &error_message); + if (error_message) + { + g_warning ("%s: Error expanding CVE item: %s", __func__, error_message); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + cJSON_Delete (entry); + fclose (json_stream); + sql_commit (); + return -1; + } + if (handle_json_cpe_refs (&inserts, entry)) + { + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + cJSON_Delete (entry); + fclose (json_stream); + sql_commit (); + return -1; + } + cJSON_Delete (entry); + gvm_json_pull_parser_next (&parser, &event); + } + inserts_run (&inserts, TRUE); + sql_commit (); + gvm_json_pull_parser_cleanup (&parser); + + return 0; +} + +/** + * @brief Update SCAP CPEs from an XML file. + * + * @param[in] path Path to file. + * + * @return 0 success, -1 error. + */ +static int +update_scap_cpes_from_xml_file (const gchar *path) { int ret; element_t cpe_item; @@ -2287,21 +2820,39 @@ update_scap_cpes () int ret; full_path = g_build_filename (GVM_SCAP_DATA_DIR, - "official-cpe-dictionary_v2.2.xml", + "nvd-cpes.json", NULL); if (g_stat (full_path, &state)) { - g_warning ("%s: No CPE dictionary found at %s", + g_warning ("%s: No JSON CPE dictionary found at %s", __func__, full_path); g_free (full_path); - return -1; + + full_path = g_build_filename (GVM_SCAP_DATA_DIR, + "official-cpe-dictionary_v2.2.xml", + NULL); + + if (g_stat (full_path, &state)) + { + g_warning ("%s: No CPE dictionary found at %s", + __func__, + full_path); + g_free (full_path); + return -1; + } + + ret = update_scap_cpes_from_xml_file (full_path); + if (ret) + return -1; + + return 0; } g_info ("Updating CPEs"); - ret = update_scap_cpes_from_file (full_path); + ret = update_scap_cpes_from_json_file (full_path); if (ret) return -1; @@ -2657,48 +3208,6 @@ insert_cve_from_entry (element_t entry, element_t last_modified, return 0; } -/** - * @brief Get the string value for a specified key from a JSON object. - * - * @param[in] object JSON object - * @param[in] key The key of the string in the JSON object. - * - * @return The string out of the JSON object with key "key", if any. - * NULL otherwise. - */ -static char* -json_object_item_string (cJSON *object, char *key) -{ - cJSON *value_json; - - value_json = cJSON_GetObjectItemCaseSensitive(object, key); - if (cJSON_IsString(value_json)) - return value_json->valuestring; - return NULL; -} - -/** - * @brief Get the double value for a specified key from a JSON object. - * - * @param[in] object JSON object - * @param[in] key The key of the double value in the JSON object. - * @param[in] fallback The fallback value if the double value is not - * available. - * - * @return The double value out of the JSON object with key "key", if any. - * The fallback value otherwise. - */ -static double -json_object_item_double (cJSON *object, char *key, double fallback) -{ - cJSON *value_json; - - value_json = cJSON_GetObjectItemCaseSensitive(object, key); - if (cJSON_IsNumber(value_json)) - return value_json->valuedouble; - return fallback; -} - /** * @brief Save the node of a cve match rule tree. * diff --git a/src/manage_sql_secinfo.h b/src/manage_sql_secinfo.h index 5e8ad4761..656f240eb 100644 --- a/src/manage_sql_secinfo.h +++ b/src/manage_sql_secinfo.h @@ -102,7 +102,7 @@ */ #define CPE_INFO_ITERATOR_FILTER_COLUMNS \ { GET_ITERATOR_FILTER_COLUMNS, "title", "status", \ - "deprecated_by_id", "severity", "cves", "nvd_id", \ + "deprecated_by_id", "severity", "cves", "cpe_name_id", \ NULL } /** @@ -114,11 +114,11 @@ { "''", "_owner", KEYWORD_TYPE_STRING }, \ { "0", NULL, KEYWORD_TYPE_INTEGER }, \ { "title", NULL, KEYWORD_TYPE_STRING }, \ - { "status", NULL, KEYWORD_TYPE_STRING }, \ + { "deprecated", NULL, KEYWORD_TYPE_INTEGER }, \ { "deprecated_by_id", NULL, KEYWORD_TYPE_INTEGER }, \ { "severity", NULL, KEYWORD_TYPE_DOUBLE }, \ { "cve_refs", "cves", KEYWORD_TYPE_INTEGER }, \ - { "nvd_id", NULL, KEYWORD_TYPE_INTEGER }, \ + { "cpe_name_id", NULL, KEYWORD_TYPE_STRING }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ } diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 3218e237a..7ba7b8b05 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -12785,9 +12785,9 @@ END:VCALENDAR Number of CVEs referencing this CPE - nvd_id - integer - NVD ID of the CVE + cpe_name_id + uuid + NVD assigned cpeNameId of the CPE @@ -13012,18 +13012,19 @@ END:VCALENDAR cpe - nvd_id + cpe_name_id title severity cve_refs - status + deprecated cves + references raw_data A CPE info element - nvd_id - The NVD ID of the CPE + cpe_name_id + NVD assigned cpeNameId of the CPE text @@ -13050,10 +13051,10 @@ END:VCALENDAR - status - The status of this CPE + deprecated + Whether the CPE is deprecated - text + boolean @@ -13070,6 +13071,26 @@ END:VCALENDAR + + references + References of this CPE. Only when details were requested + + reference + + + reference + Reference of the CPE. Text contains type + + + href + text + Reference URL + 1 + + text + + + raw_data Source representation of the information. Only when details were requested From 1012034fef29b8717a89c5f575979621b2313c49 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Wed, 2 Oct 2024 11:51:30 +0200 Subject: [PATCH 15/64] Change deprecated_by of CPEs to a list. --- src/gmp.c | 14 +++-- src/manage.h | 6 ++ src/manage_pg.c | 5 ++ src/manage_sql_secinfo.c | 93 +++++++++++++++++++++++-------- src/schema_formats/XML/GMP.xml.in | 13 +++++ 5 files changed, 103 insertions(+), 28 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index ac95a6f67..2b179fa4e 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13490,16 +13490,18 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) if (get_info_data->details == 1) { - const char *deprecated_by_id - = cpe_info_iterator_deprecated_by_id (&info); - if (deprecated_by_id && strcmp (deprecated_by_id, "")) + iterator_t deprecated_by, cves, refs; + + init_cpe_deprecated_by_iterator (&deprecated_by, + get_iterator_name (&info)); + while (next (&deprecated_by)) { xml_string_append (result, - "%s", - deprecated_by_id); + "", + cpe_deprecated_by_iterator_deprecated_by + (&deprecated_by)); } - iterator_t cves, refs; g_string_append (result, ""); init_cpe_cve_iterator (&cves, get_iterator_name (&info), 0, NULL); while (next (&cves)) diff --git a/src/manage.h b/src/manage.h index 6d34f02f9..9d2434292 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3339,6 +3339,12 @@ manage_scap_update_time (); /* CPE. */ +void +init_cpe_deprecated_by_iterator (iterator_t *, const char *); + +const char * +cpe_deprecated_by_iterator_deprecated_by (iterator_t *); + void init_cpe_cve_iterator (iterator_t *, const char *, int, const char *); diff --git a/src/manage_pg.c b/src/manage_pg.c index 7088a4e9c..0cad6c0af 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3538,6 +3538,11 @@ manage_db_init (const gchar *name) " ref TEXT," " type TEXT);"); + sql ("CREATE TABLE scap2.cpes_deprecated_by" + " (id SERIAL PRIMARY KEY," + " cpe TEXT," + " deprecated_by TEXT);"); + sql ("CREATE TABLE scap2.cpe_match_nodes" " (id SERIAL PRIMARY KEY," " parent_id INTEGER DEFAULT 0," diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index b03413453..680602322 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -696,6 +696,28 @@ cve_info_filter_columns () return filter_columns; } +/** + * @brief Initialise an iterator listing CPEs another CPE is deprecated_by. + * + * @param[in] iterator Iterator. + * @param[in] cpe CPE to get which other CPEs it's deprecated by. + */ +void +init_cpe_deprecated_by_iterator (iterator_t *iterator, const char *cpe) +{ + gchar *quoted_cpe; + assert (cpe); + quoted_cpe = sql_quote (cpe); + init_iterator (iterator, + "SELECT deprecated_by FROM cpes_deprecated_by" + " WHERE cpe = '%s'" + " ORDER BY deprecated_by;", + quoted_cpe); + g_free (quoted_cpe); +} + +DEF_ACCESS (cpe_deprecated_by_iterator_deprecated_by, 0); + /** * @brief Initialise an CVE iterator, for CVEs reported for a certain CPE. * @@ -2272,19 +2294,19 @@ scap_cpes_json_skip_to_products (gvm_json_pull_parser_t *parser, /** * @brief Insert a SCAP CPE from JSON. * - * @param[in] inserts Pointer to SQL buffer. + * @param[in] inserts Pointer to SQL buffer for main CPE entries. + * @param[in] deprecated_by_inserts Pointer to SQL buffer for deprecated_by. * @param[in] product_item JSON object from the products list. * * @return 0 success, -1 error. */ static int -handle_json_cpe_item (inserts_t *inserts, cJSON *product_item) +handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, + cJSON *product_item) { cJSON *cpe_item; char *name, *cpe_name_id, *last_modified, *title_text; - char *deprecated_by; gchar *quoted_name, *quoted_title, *quoted_cpe_name_id; - gchar *quoted_deprecated_by; cJSON *titles, *title; time_t modification_time; int deprecated; @@ -2347,48 +2369,70 @@ handle_json_cpe_item (inserts_t *inserts, cJSON *product_item) return -1; } - deprecated_by = NULL; + quoted_name = fs_to_uri_convert_and_quote_cpe_name (name); if (deprecated) { /* CPEs can have multiple deprecatedBy entries, * but for the GMP field only the first one is used */ - cJSON *deprecated_by_array, *first_deprecated_by; + cJSON *deprecated_by_array, *deprecated_by_item; + char *deprecated_by_id; + gchar *quoted_deprecated_by_id; deprecated_by_array = cJSON_GetObjectItemCaseSensitive (cpe_item, "deprecatedBy"); if (! cJSON_IsArray (deprecated_by_array)) { g_warning ("%s: 'deprecatedBy' field missing or not an array", __func__); + g_free (quoted_name); return -1; } else if (cJSON_GetArraySize (deprecated_by_array) == 0) { g_warning ("%s: 'deprecatedBy' array is empty", __func__); + g_free (quoted_name); return -1; } - first_deprecated_by = cJSON_GetArrayItem (deprecated_by_array, 0); - deprecated_by = json_object_item_string (first_deprecated_by, "cpeName"); - if (deprecated_by == NULL) + cJSON_ArrayForEach (deprecated_by_item, deprecated_by_array) { - g_warning ("%s: Could not get 'cpeName' string from 'deprecatedBy'", - __func__); - return -1; + deprecated_by_id = json_object_item_string (deprecated_by_item, + "cpeName"); + if (deprecated_by_id == NULL) + { + g_warning ("%s: 'cpeName' field in 'deprecatedBy' missing or not" + " a string", + __func__); + g_free (quoted_name); + return -1; + } + + quoted_deprecated_by_id + = fs_to_uri_convert_and_quote_cpe_name (deprecated_by_id); + + g_message ("%s deprecated by %s", quoted_name, quoted_deprecated_by_id); + + first = inserts_check_size (deprecated_by_inserts); + + g_string_append_printf (deprecated_by_inserts->statement, + "%s ('%s', '%s')", + first ? "" : ",", + quoted_name, + quoted_deprecated_by_id); + + deprecated_by_inserts->current_chunk_size++; + + g_free (quoted_deprecated_by_id); } } - quoted_name = fs_to_uri_convert_and_quote_cpe_name (name); quoted_cpe_name_id = sql_quote (cpe_name_id); quoted_title = sql_quote (title_text ? title_text : ""); - quoted_deprecated_by - = deprecated_by ? fs_to_uri_convert_and_quote_cpe_name (deprecated_by) - : NULL; first = inserts_check_size (inserts); g_string_append_printf (inserts->statement, - "%s ('%s', '%s', '%s', %li, %li, %d, '%s', '%s')", + "%s ('%s', '%s', '%s', %li, %li, %d, '%s')", first ? "" : ",", quoted_name, quoted_name, @@ -2396,7 +2440,6 @@ handle_json_cpe_item (inserts_t *inserts, cJSON *product_item) modification_time, modification_time, deprecated, - quoted_deprecated_by ? quoted_deprecated_by : "", quoted_cpe_name_id); inserts->current_chunk_size++; @@ -2404,7 +2447,6 @@ handle_json_cpe_item (inserts_t *inserts, cJSON *product_item) g_free (quoted_title); g_free (quoted_name); g_free (quoted_cpe_name_id); - g_free (quoted_deprecated_by); return 0; } @@ -2490,7 +2532,7 @@ handle_json_cpe_refs (inserts_t *inserts, cJSON *product_item) static int update_scap_cpes_from_json_file (const gchar *path) { - inserts_t inserts; + inserts_t inserts, deprecated_by_inserts; gvm_json_pull_parser_t parser; gvm_json_pull_event_t event; FILE *json_stream = fopen (path, "r"); @@ -2517,7 +2559,7 @@ update_scap_cpes_from_json_file (const gchar *path) setting_secinfo_sql_buffer_threshold_bytes (), "INSERT INTO scap2.cpes" " (uuid, name, title, creation_time," - " modification_time, deprecated, deprecated_by_id," + " modification_time, deprecated," " cpe_name_id)" " VALUES", " ON CONFLICT (uuid) DO UPDATE" @@ -2529,6 +2571,12 @@ update_scap_cpes_from_json_file (const gchar *path) " deprecated_by_id = EXCLUDED.deprecated_by_id," " cpe_name_id = EXCLUDED.cpe_name_id"); + inserts_init (&deprecated_by_inserts, 10, + setting_secinfo_sql_buffer_threshold_bytes (), + "INSERT INTO scap2.cpes_deprecated_by (cpe, deprecated_by)" + " VALUES ", + ""); + while (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) { gchar *error_message; @@ -2543,7 +2591,7 @@ update_scap_cpes_from_json_file (const gchar *path) sql_commit (); return -1; } - if (handle_json_cpe_item (&inserts, entry)) + if (handle_json_cpe_item (&inserts, &deprecated_by_inserts, entry)) { gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); @@ -2556,6 +2604,7 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_parser_next (&parser, &event); } inserts_run (&inserts, TRUE); + inserts_run (&deprecated_by_inserts, TRUE); sql_commit (); gvm_json_pull_parser_cleanup (&parser); diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 7ba7b8b05..eb2feaf73 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -13017,6 +13017,7 @@ END:VCALENDAR severity cve_refs deprecated + deprecated_by cves references raw_data @@ -13057,6 +13058,18 @@ END:VCALENDAR boolean + + deprecated_by + Another CPE the current one is deprecated by + + + cpe_id + uuid + CPE id the current CPE is deprecated by + 1 + + + cves CVEs referring to this CPE. Only when details were requested From 96208aa4724978f7ef1296d87b66a0f94f2372dc Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 18 Oct 2024 09:44:18 +0200 Subject: [PATCH 16/64] Apply review suggestions for JSON CPEs Add missing cleanup, fix comments and remove leftover test log output. --- src/gmp.c | 1 + src/manage_sql_secinfo.c | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 2b179fa4e..b90c1ff54 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13501,6 +13501,7 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) cpe_deprecated_by_iterator_deprecated_by (&deprecated_by)); } + cleanup_iterator (&deprecated_by); g_string_append (result, ""); init_cpe_cve_iterator (&cves, get_iterator_name (&info), 0, NULL); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 680602322..d8bbe4ec3 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -424,11 +424,11 @@ json_object_item_double (cJSON *object, char *key, double fallback) * @brief Get the boolean value for a specified key from a JSON object. * * @param[in] object JSON object - * @param[in] key The key of the double value in the JSON object. + * @param[in] key The key of the boolean value in the JSON object. * @param[in] fallback The fallback value if the boolean value is not * available. * - * @return The double value out of the JSON object with key "key", if any. + * @return The boolean value out of the JSON object with key "key", if any. * The fallback value otherwise. */ static int @@ -2372,8 +2372,6 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, quoted_name = fs_to_uri_convert_and_quote_cpe_name (name); if (deprecated) { - /* CPEs can have multiple deprecatedBy entries, - * but for the GMP field only the first one is used */ cJSON *deprecated_by_array, *deprecated_by_item; char *deprecated_by_id; gchar *quoted_deprecated_by_id; @@ -2410,8 +2408,6 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, quoted_deprecated_by_id = fs_to_uri_convert_and_quote_cpe_name (deprecated_by_id); - g_message ("%s deprecated by %s", quoted_name, quoted_deprecated_by_id); - first = inserts_check_size (deprecated_by_inserts); g_string_append_printf (deprecated_by_inserts->statement, @@ -2420,8 +2416,7 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, quoted_name, quoted_deprecated_by_id); - deprecated_by_inserts->current_chunk_size++; - + deprecated_by_inserts->current_chunk_size++; g_free (quoted_deprecated_by_id); } } @@ -2516,6 +2511,8 @@ handle_json_cpe_refs (inserts_t *inserts, cJSON *product_item) quoted_type); inserts->current_chunk_size++; + g_free (quoted_ref); + g_free (quoted_type); } g_free (quoted_name); From 8a1c684a36c6ba3d24058295f27f97dd232d88cb Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 18 Oct 2024 10:52:27 +0200 Subject: [PATCH 17/64] Remove: Drop unused deprecated_by column of CPEs The column has been replaced by a table to allow multiple deprecated_by entries per CPE. --- src/manage.h | 3 --- src/manage_pg.c | 1 - src/manage_sql_secinfo.c | 23 +++++------------------ src/manage_sql_secinfo.h | 5 ++--- 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/manage.h b/src/manage.h index 9d2434292..a2cfc5775 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3372,9 +3372,6 @@ cpe_info_iterator_cve_refs (iterator_t*); const char* cpe_info_iterator_cpe_name_id (iterator_t*); -const char* -cpe_info_iterator_deprecated_by_id (iterator_t*); - gchar * cpe_details_xml (const char*); diff --git a/src/manage_pg.c b/src/manage_pg.c index 0cad6c0af..4bc218524 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3525,7 +3525,6 @@ manage_db_init (const gchar *name) " modification_time integer," " title text," " status text," - " deprecated_by_id TEXT," " severity DOUBLE PRECISION DEFAULT 0," " cve_refs INTEGER DEFAULT 0," " nvd_id text," diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index d8bbe4ec3..f0a87c63c 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -571,17 +571,6 @@ DEF_ACCESS (cpe_info_iterator_title, GET_ITERATOR_COLUMN_COUNT); */ DEF_ACCESS (cpe_info_iterator_deprecated, GET_ITERATOR_COLUMN_COUNT + 1); -/** - * @brief Get the first CPE the current one is deprecated by - * from a CPE iterator. - * - * @param[in] iterator Iterator. - * - * @return The first CPE the current one is deprecated by, - * or NULL if iteration is complete. Freed by cleanup_iterator. - */ -DEF_ACCESS (cpe_info_iterator_deprecated_by_id, GET_ITERATOR_COLUMN_COUNT + 2); - /** * @brief Get the highest severity Score of all CVE's referencing this cpe. * @@ -590,7 +579,7 @@ DEF_ACCESS (cpe_info_iterator_deprecated_by_id, GET_ITERATOR_COLUMN_COUNT + 2); * @return The highest severity score of the CPE, * or NULL if iteration is complete. Freed by cleanup_iterator. */ -DEF_ACCESS (cpe_info_iterator_severity, GET_ITERATOR_COLUMN_COUNT + 3); +DEF_ACCESS (cpe_info_iterator_severity, GET_ITERATOR_COLUMN_COUNT + 2); /** * @brief Get the Number of CVE's referencing this cpe from a CPE iterator. @@ -600,7 +589,7 @@ DEF_ACCESS (cpe_info_iterator_severity, GET_ITERATOR_COLUMN_COUNT + 3); * @return The Number of references to the CPE, or NULL if iteration is * complete. Freed by cleanup_iterator. */ -DEF_ACCESS (cpe_info_iterator_cve_refs, GET_ITERATOR_COLUMN_COUNT + 4); +DEF_ACCESS (cpe_info_iterator_cve_refs, GET_ITERATOR_COLUMN_COUNT + 3); /** * @brief Get the NVD assigned cpeNameId for this CPE. @@ -610,7 +599,7 @@ DEF_ACCESS (cpe_info_iterator_cve_refs, GET_ITERATOR_COLUMN_COUNT + 4); * @return The NVD ID of this CPE, or NULL if iteration is * complete. Freed by cleanup_iterator. */ -DEF_ACCESS (cpe_info_iterator_cpe_name_id, GET_ITERATOR_COLUMN_COUNT + 5); +DEF_ACCESS (cpe_info_iterator_cpe_name_id, GET_ITERATOR_COLUMN_COUNT + 4); /** * @brief Get the XML details / raw data for a given CPE ID. @@ -2373,7 +2362,6 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, if (deprecated) { cJSON *deprecated_by_array, *deprecated_by_item; - char *deprecated_by_id; gchar *quoted_deprecated_by_id; deprecated_by_array = cJSON_GetObjectItemCaseSensitive (cpe_item, "deprecatedBy"); @@ -2394,6 +2382,7 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, cJSON_ArrayForEach (deprecated_by_item, deprecated_by_array) { + char *deprecated_by_id; deprecated_by_id = json_object_item_string (deprecated_by_item, "cpeName"); if (deprecated_by_id == NULL) @@ -2565,7 +2554,6 @@ update_scap_cpes_from_json_file (const gchar *path) " creation_time = EXCLUDED.creation_time," " modification_time = EXCLUDED.modification_time," " deprecated = EXCLUDED.deprecated," - " deprecated_by_id = EXCLUDED.deprecated_by_id," " cpe_name_id = EXCLUDED.cpe_name_id"); inserts_init (&deprecated_by_inserts, 10, @@ -2705,7 +2693,7 @@ update_scap_cpes_from_xml_file (const gchar *path) setting_secinfo_sql_buffer_threshold_bytes (), "INSERT INTO scap2.cpes" " (uuid, name, title, creation_time," - " modification_time, status, deprecated_by_id," + " modification_time, status," " nvd_id)" " VALUES", " ON CONFLICT (uuid) DO UPDATE" @@ -2714,7 +2702,6 @@ update_scap_cpes_from_xml_file (const gchar *path) " creation_time = EXCLUDED.creation_time," " modification_time = EXCLUDED.modification_time," " status = EXCLUDED.status," - " deprecated_by_id = EXCLUDED.deprecated_by_id," " nvd_id = EXCLUDED.nvd_id"); cpe_item = xml_file_iterator_next (file_iterator, &error_message); diff --git a/src/manage_sql_secinfo.h b/src/manage_sql_secinfo.h index 656f240eb..71f00c091 100644 --- a/src/manage_sql_secinfo.h +++ b/src/manage_sql_secinfo.h @@ -101,8 +101,8 @@ * @brief Filter columns for CVE iterator. */ #define CPE_INFO_ITERATOR_FILTER_COLUMNS \ - { GET_ITERATOR_FILTER_COLUMNS, "title", "status", \ - "deprecated_by_id", "severity", "cves", "cpe_name_id", \ + { GET_ITERATOR_FILTER_COLUMNS, "title", "deprecated", \ + "severity", "cves", "cpe_name_id", \ NULL } /** @@ -115,7 +115,6 @@ { "0", NULL, KEYWORD_TYPE_INTEGER }, \ { "title", NULL, KEYWORD_TYPE_STRING }, \ { "deprecated", NULL, KEYWORD_TYPE_INTEGER }, \ - { "deprecated_by_id", NULL, KEYWORD_TYPE_INTEGER }, \ { "severity", NULL, KEYWORD_TYPE_DOUBLE }, \ { "cve_refs", "cves", KEYWORD_TYPE_INTEGER }, \ { "cpe_name_id", NULL, KEYWORD_TYPE_STRING }, \ From 624f1444d87aa26e6b488b86e7ce85a2437558e5 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Thu, 24 Oct 2024 11:56:09 +0200 Subject: [PATCH 18/64] Add: Added reading of gzip files for CPEs. --- src/manage_sql_secinfo.c | 71 ++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 71cc6e055..0f5527da6 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2522,21 +2522,35 @@ update_scap_cpes_from_json_file (const gchar *path) inserts_t inserts, deprecated_by_inserts; gvm_json_pull_parser_t parser; gvm_json_pull_event_t event; - FILE *json_stream = fopen (path, "r"); - if (json_stream == NULL) + FILE *cpe_file; + + int fd = open (path, O_RDONLY); + + if (fd < 0) { - g_warning ("%s: Could not open file '%s': %s", + g_warning ("%s: Failed to open CPE file '%s': %s", __func__, path, strerror(errno)); return -1; } - gvm_json_pull_parser_init (&parser, json_stream); + g_info ("Updating %s", path); + + cpe_file = gvm_gzip_open_file_reader_fd (fd); + if (cpe_file == NULL) + { + g_warning ("%s: Failed to open CPE file: %s", + __func__, + strerror (errno)); + return -1; + } + + gvm_json_pull_parser_init (&parser, cpe_file); gvm_json_pull_event_init (&event); if (scap_cpes_json_skip_to_products (&parser, &event)) { gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); - fclose (json_stream); + fclose (cpe_file); return -1; } @@ -2573,7 +2587,7 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); cJSON_Delete (entry); - fclose (json_stream); + fclose (cpe_file); sql_commit (); return -1; } @@ -2582,7 +2596,7 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); cJSON_Delete (entry); - fclose (json_stream); + fclose (cpe_file); sql_commit (); return -1; } @@ -2595,14 +2609,31 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_parser_cleanup (&parser); // Reset and insert refs - fseek (json_stream, 0, SEEK_SET); - gvm_json_pull_parser_init (&parser, json_stream); + fclose (cpe_file); + fd = open (path, O_RDONLY); + + if (fd < 0) + { + g_warning ("%s: Failed to open CPE file '%s': %s", + __func__, path, strerror(errno)); + return -1; + } + + cpe_file = gvm_gzip_open_file_reader_fd (fd); + if (cpe_file == NULL) + { + g_warning ("%s: Failed to open CPE file: %s", + __func__, + strerror (errno)); + return -1; + } + gvm_json_pull_parser_init (&parser, cpe_file); if (scap_cpes_json_skip_to_products (&parser, &event)) { gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); - fclose (json_stream); + fclose (cpe_file); return -1; } @@ -2625,7 +2656,7 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); cJSON_Delete (entry); - fclose (json_stream); + fclose (cpe_file); sql_commit (); return -1; } @@ -2634,7 +2665,7 @@ update_scap_cpes_from_json_file (const gchar *path) gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); cJSON_Delete (entry); - fclose (json_stream); + fclose (cpe_file); sql_commit (); return -1; } @@ -2645,6 +2676,7 @@ update_scap_cpes_from_json_file (const gchar *path) sql_commit (); gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_file); return 0; } @@ -2854,8 +2886,15 @@ update_scap_cpes () int ret; full_path = g_build_filename (GVM_SCAP_DATA_DIR, - "nvd-cpes.json", + "nvd-cpes.json.gz", NULL); + if (g_stat (full_path, &state)) + { + g_free (full_path); + full_path = g_build_filename (GVM_SCAP_DATA_DIR, + "nvd-cpes.json", + NULL); + } if (g_stat (full_path, &state)) { @@ -2888,8 +2927,12 @@ update_scap_cpes () ret = update_scap_cpes_from_json_file (full_path); if (ret) - return -1; + { + g_free (full_path); + return -1; + } + g_free (full_path); return 0; } From f5f77acec7ba290f146ac7af2ddc8ebee87d88f4 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 28 Oct 2024 16:01:30 +0100 Subject: [PATCH 19/64] Very small optimization. --- src/manage_sql_secinfo.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 0f5527da6..998ccf891 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2926,13 +2926,12 @@ update_scap_cpes () g_info ("Updating CPEs"); ret = update_scap_cpes_from_json_file (full_path); - if (ret) - { - g_free (full_path); - return -1; - } g_free (full_path); + + if (ret) + return -1; + return 0; } From 3d75038b71ece78869244b50017a3f496569492f Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 4 Oct 2024 17:38:52 +0200 Subject: [PATCH 20/64] Change: Update handling of CVEs for the new JSON API. - Handle references explicitly to remove raw_data. - Add affected software configurations and references to the response of get_info for CVEs when details are enabled. --- src/gmp.c | 195 ++++++++ src/manage.h | 27 + src/manage_pg.c | 39 +- src/manage_sql.c | 160 +++++- src/manage_sql_secinfo.c | 797 ++++++++++++++++++++++-------- src/schema_formats/XML/GMP.xml.in | 157 ++++++ 6 files changed, 1138 insertions(+), 237 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index b90c1ff54..fe766df12 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -101,6 +101,7 @@ #include "manage_report_configs.h" #include "manage_report_formats.h" #include "manage_tls_certificates.h" +#include "sql.h" #include "utils.h" #include @@ -128,6 +129,7 @@ #include #include #include +#include #undef G_LOG_DOMAIN /** @@ -13252,6 +13254,194 @@ handle_get_groups (gmp_parser_t *gmp_parser, GError **error) set_client_state (CLIENT_AUTHENTIC); } +/** + * @brief Print CPE match node with its matched CPEs. + * + * @param[in] node CPE match node to print. + * @param[in] buffer Buffer into which to print match node. + */ +static void +print_cpe_match_nodes_xml(resource_t node, GString *buffer) +{ + iterator_t cpe_match_nodes, cpe_match_ranges; + const char *operator = NULL; + int negate = 0; + + init_iterator (&cpe_match_nodes, + "SELECT operator, negate FROM scap.cpe_match_nodes WHERE id = %llu;", + node); + while (next (&cpe_match_nodes)) + { + operator = iterator_string (&cpe_match_nodes, 0); + negate = iterator_int (&cpe_match_nodes, 1); + } + cleanup_iterator (&cpe_match_nodes); + + xml_string_append (buffer, "%s", operator?: ""); + xml_string_append (buffer, "%s", negate? "1" : "0"); + + init_cpe_match_range_iterator (&cpe_match_ranges, node); + while (next (&cpe_match_ranges)) + { + const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *range_uri_product; + + xml_string_append (buffer, ""); + match_criteria_id = cpe_match_range_iterator_match_criteria_id (&cpe_match_ranges); + range_uri_product + = fs_cpe_to_uri_cpe (cpe_match_range_iterator_cpe (&cpe_match_ranges)); + xml_string_append (buffer, "%s", range_uri_product?: ""); + xml_string_append (buffer, "%s", + cpe_match_range_iterator_vulnerable (&cpe_match_ranges) != 0 + ? "1" + : "0"); + vsi = cpe_match_range_iterator_version_start_incl(&cpe_match_ranges); + vse = cpe_match_range_iterator_version_start_excl(&cpe_match_ranges); + vei = cpe_match_range_iterator_version_end_incl(&cpe_match_ranges); + vee = cpe_match_range_iterator_version_end_excl(&cpe_match_ranges); + + xml_string_append (buffer, + "%s", + vsi ?: ""); + xml_string_append (buffer, + "%s", + vse ?: ""); + xml_string_append (buffer, + "%s", + vei ?: ""); + xml_string_append (buffer, + "%s", + vee ?: ""); + + iterator_t cpe_matches; + init_cpe_match_range_matches_iterator (&cpe_matches, match_criteria_id); + xml_string_append (buffer, ""); + + while (next (&cpe_matches)) + { + iterator_t cpes; + + init_iterator (&cpes, + "SELECT name, deprecated FROM scap.cpes" + " WHERE cpe_name_id = '%s';", + cpe_matches_cpe_name_id(&cpe_matches)); + + const char* cpe = NULL; + int deprecated = 0; + while (next (&cpes)) + { + cpe = iterator_string (&cpes, 0); + deprecated = iterator_int (&cpes, 1); + } + cleanup_iterator (&cpes); + + xml_string_append (buffer, ""); + xml_string_append (buffer, "%s", cpe?: ""); + xml_string_append (buffer, + "%s", + deprecated ? "1" : "0"); + if (deprecated) + { + iterator_t deprecated_by; + init_cpe_deprecated_by_iterator (&deprecated_by, cpe); + while (next (&deprecated_by)) + { + xml_string_append (buffer, + "", + cpe_deprecated_by_iterator_deprecated_by + (&deprecated_by)); + } + cleanup_iterator (&deprecated_by); + } + xml_string_append (buffer, ""); + } + xml_string_append (buffer, ""); + xml_string_append (buffer, ""); + cleanup_iterator (&cpe_matches); + } + cleanup_iterator (&cpe_match_ranges); +} +/** + * @brief Print CVE affected software configurations + * + * @param[in] cve_uuid uuid of the CVE. + * @param[out] result Buffer into which to print. + * + */ +static void +print_cve_affected_software_configs_xml (gchar *cve_uuid, GString *result) +{ + iterator_t cpe_match_root_nodes; + xml_string_append (result, ""); + init_cve_cpe_match_nodes_iterator (&cpe_match_root_nodes, cve_uuid); + while (next (&cpe_match_root_nodes)) + { + result_t root_node; + iterator_t cpe_match_node_childs; + root_node = cpe_match_nodes_iterator_root_id (&cpe_match_root_nodes); + xml_string_append (result, ""); + print_cpe_match_nodes_xml(root_node, result); + init_cpe_match_node_childs_iterator (&cpe_match_node_childs, root_node); + while (next (&cpe_match_node_childs)) + { + resource_t child_node; + child_node = cpe_match_node_childs_iterator_id (&cpe_match_node_childs); + xml_string_append (result, ""); + print_cpe_match_nodes_xml(child_node, result); + xml_string_append (result, ""); + } + xml_string_append (result, ""); + cleanup_iterator (&cpe_match_node_childs); + } + xml_string_append (result, ""); + cleanup_iterator (&cpe_match_root_nodes); +} + +/** + * @brief Print CVE references + * + * @param[in] cve_uuid uuid of the CVE. + * @param[out] result Buffer into which to print. + * + */ +static void +print_cve_references_xml (gchar *cve_uuid, GString *result) +{ + iterator_t references; + init_cve_reference_iterator (&references, cve_uuid); + xml_string_append (result, ""); + while (next (&references)) + { + xml_string_append (result, ""); + xml_string_append (result, "%s", cve_reference_iterator_url (&references)); + xml_string_append (result, ""); + const char * tags_array = cve_reference_iterator_tags (&references); + if(tags_array && strlen(tags_array) > 2) + { + char *trimmed_array = g_strndup (tags_array + 1, strlen (tags_array) - 2); + gchar **tags, **current_tag; + tags = g_strsplit (trimmed_array, ",", -1); + current_tag = tags; + while (*current_tag) + { + if (strlen (*current_tag) > 2 && (*current_tag)[0] == '"' && (*current_tag)[strlen (*current_tag) - 1] == '"') + { + char *trimmed_tag = g_strndup (*current_tag + 1, strlen (*current_tag) - 2); + xml_string_append (result, "%s", trimmed_tag); + g_free (trimmed_tag); + } + else + xml_string_append (result, "%s", *current_tag); + current_tag++; + } + g_strfreev (tags); + g_free (trimmed_array); + } + xml_string_append (result, ""); + xml_string_append (result, ""); + } + xml_string_append (result, ""); + cleanup_iterator (&references); +} /** * @brief Handle end of GET_INFO element. * @@ -13627,6 +13817,11 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) ""); } g_string_append (result, ""); + + gchar *cve_uuid = g_strdup(get_iterator_uuid (&info)); + print_cve_affected_software_configs_xml (cve_uuid, result); + print_cve_references_xml (cve_uuid, result); + g_free(cve_uuid); } } else if (g_strcmp0 ("cert_bund_adv", get_info_data->type) == 0) diff --git a/src/manage.h b/src/manage.h index df8f144a4..93cbb01e2 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1693,6 +1693,21 @@ app_locations_iterator_location (iterator_t*); void init_cpe_match_nodes_iterator (iterator_t*, const char *); +void +init_cve_cpe_match_nodes_iterator (iterator_t*, const char *); + +void +init_cve_reference_iterator (iterator_t*, const char *); + +const char* +cve_reference_iterator_url (iterator_t*); + +const char* +cve_reference_iterator_tags (iterator_t*); + +const char* +cve_reference_iterator_tags_count (iterator_t*); + long long int cpe_match_nodes_iterator_root_id (iterator_t*); @@ -1714,6 +1729,12 @@ init_cpe_match_range_iterator (iterator_t*, long long int); const char* cpe_match_range_iterator_cpe (iterator_t*); +const char* +cpe_match_range_iterator_match_criteria_id (iterator_t*); + +const char* +cpe_match_range_iterator_status (iterator_t*); + const char* cpe_match_range_iterator_version_start_incl (iterator_t*); @@ -1729,6 +1750,12 @@ cpe_match_range_iterator_version_end_excl (iterator_t*); int cpe_match_range_iterator_vulnerable (iterator_t*); +void +init_cpe_match_range_matches_iterator (iterator_t*, const char *); + +const char* +cpe_matches_cpe_name_id (iterator_t*); + void init_host_details_cpe_product_iterator (iterator_t*, const char *, report_host_t); diff --git a/src/manage_pg.c b/src/manage_pg.c index f53b9f601..893d3e240 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3546,20 +3546,31 @@ manage_db_init (const gchar *name) sql ("CREATE TABLE scap2.cpe_match_nodes" " (id SERIAL PRIMARY KEY," - " parent_id INTEGER DEFAULT 0," - " root_id INTEGER DEFAULT 0," - " cve_id INTEGER DEFAULT 0," - " operator text);"); + " root_id integer DEFAULT 0," + " cve_id integer DEFAULT 0," + " operator text," + " negate integer DEFAULT 0);"); + + sql ("CREATE TABLE scap2.cpe_nodes_match_criteria" + " (id SERIAL PRIMARY KEY," + " node_id integer DEFAULT 0," + " vulnerable integer DEFAULT 0," + " match_criteria_id text);"); sql ("CREATE TABLE scap2.cpe_match_range" " (id SERIAL PRIMARY KEY," - " node_id INTEGER DEFAULT 0," - " vulnerable INTEGER DEFAULT 0," + " match_criteria_id text," " cpe text DEFAULT NULL," " version_start_incl text DEFAULT NULL," " version_start_excl text DEFAULT NULL," " version_end_incl text DEFAULT NULL," - " version_end_excl text DEFAULT NULL);"); + " version_end_excl text DEFAULT NULL," + " status text);"); + + sql ("CREATE TABLE scap2.cpe_matches" + " (id SERIAL PRIMARY KEY," + " match_criteria_id text," + " cpe_name_id text);"); sql ("CREATE TABLE scap2.cpe_details" " (id SERIAL PRIMARY KEY," @@ -3575,6 +3586,11 @@ manage_db_init (const gchar *name) " epss DOUBLE PRECISION," " percentile DOUBLE PRECISION);"); + sql ("CREATE TABLE scap2.cve_references" + " (id SERIAL PRIMARY KEY," + " cve_id INTEGER," + " url text," + " tags text[]);"); /* Init tables. */ @@ -3624,6 +3640,15 @@ manage_db_add_constraints (const gchar *name) sql ("ALTER TABLE scap2.epss_scores" " ALTER cve SET NOT NULL," " ADD UNIQUE (cve);"); + + sql ("ALTER TABLE scap2.cve_references" + " ALTER cve_id SET NOT NULL," + " ALTER url SET NOT NULL," + " ADD UNIQUE (cve_id, url);"); + + sql ("ALTER TABLE scap2.cpe_match_range" + " ADD UNIQUE (match_criteria_id);"); + } else { diff --git a/src/manage_sql.c b/src/manage_sql.c index fc1bf3905..71461dc00 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20511,13 +20511,80 @@ init_cpe_match_nodes_iterator (iterator_t* iterator, const char *cpe) gchar *quoted_cpe; quoted_cpe = sql_quote (cpe); init_iterator (iterator, - "SELECT DISTINCT root_id" - " FROM scap.cpe_match_nodes, scap.cpe_match_range" - " WHERE cpe like '%s%%' AND scap.cpe_match_nodes.id = node_id;", + " SELECT DISTINCT n.root_id" + " FROM scap.cpe_match_nodes n" + " JOIN scap.cpe_nodes_match_criteria c ON n.id = c.node_id" + " JOIN scap.cpe_match_range r ON c.match_criteria = r.match_criteria_id" + " WHERE cpe like '%s%%';", quoted_cpe); g_free (quoted_cpe); } +/** + * @brief Initialize an iterator of CPE match nodes root_ids for a CVE. + * + * @param[in] iterator Iterator. + * @param[in] cve The CVE contained in the match nodes. + */ +void +init_cve_cpe_match_nodes_iterator (iterator_t* iterator, const char *cve) +{ + gchar *quoted_cve; + quoted_cve = sql_quote (cve); + init_iterator (iterator, + "SELECT DISTINCT root_id" + " FROM scap.cpe_match_nodes" + " WHERE cve_id = (SELECT id from scap.cves where uuid = '%s');", + quoted_cve); + g_free (quoted_cve); +} + +/** + * @brief Initialize an iterator of references for a CVE. + * + * @param[in] iterator Iterator. + * @param[in] cve The CVE with the references. + */ +void +init_cve_reference_iterator (iterator_t* iterator, const char *cve) +{ + gchar *quoted_cve; + quoted_cve = sql_quote (cve); + init_iterator (iterator, + "SELECT url, array_length(tags, 1), tags" + " FROM scap.cve_references" + " WHERE cve_id = (SELECT id from scap.cves where uuid = '%s');", + quoted_cve); + g_free (quoted_cve); +} + +/** + * @brief Get a URL from a CVE reference iterator. + * + * @param[in] iterator Iterator. + * + * @return The URL. + */ +DEF_ACCESS (cve_reference_iterator_url, 0); + +/** + * @brief Get the length of the tags array from a CVE reference iterator. + * + * @param[in] iterator Iterator. + * + * @return Length of the tags array. + */ +DEF_ACCESS (cve_reference_iterator_tags_count, 1); + +/** + * @brief Get the tags array from a CVE reference iterator. + * + * @param[in] iterator Iterator. + * + * @return The tags array. + */ +DEF_ACCESS (cve_reference_iterator_tags, 2); + /** * @brief Get a root id from an CPE match node iterator. * @@ -20542,7 +20609,8 @@ init_cpe_match_node_childs_iterator (iterator_t* iterator, long long int node) { init_iterator (iterator, "SELECT id FROM scap.cpe_match_nodes" - " WHERE parent_id = %llu;", + " WHERE root_id = %llu" + " AND root_id <> id;", node); } @@ -20569,10 +20637,13 @@ void init_cpe_match_range_iterator (iterator_t* iterator, long long int node) { init_iterator (iterator, - "SELECT vulnerable, cpe, version_start_incl," - " version_start_excl, version_end_incl, version_end_excl" - " FROM scap.cpe_match_range" - " WHERE node_id = %llu;", + "SELECT n.vulnerable, r.cpe, r.match_criteria_id, r.status," + " r.version_start_incl, r.version_start_excl," + " r.version_end_incl, r.version_end_excl" + " FROM scap.cpe_match_range r" + " JOIN scap.cpe_nodes_match_criteria n" + " ON r.match_criteria_id = n.match_criteria_id" + " WHERE n.node_id = %llu;", node); } @@ -20599,44 +20670,93 @@ cpe_match_range_iterator_vulnerable (iterator_t* iterator) DEF_ACCESS (cpe_match_range_iterator_cpe, 1); /** - * @brief Return the start included version of the actual match node. + * @brief Return the match criteria id of the CPE match range. + * + * @param[in] iterator Iterator. + * + * @return The match criteria id, if any. NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_match_criteria_id, 2); + +/** + * @brief Return the status of the CPE match range. * * @param[in] iterator Iterator. * - * @return The start included version of the actual match node, if any. + * @return The status of the CPE match range, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_start_incl, 2); +DEF_ACCESS (cpe_match_range_iterator_status, 3); /** - * @brief Return the start excluded version of the actual match node. + * @brief Return the start included version of the match range. * * @param[in] iterator Iterator. * - * @return The start excluded version of the actual match node, if any. + * @return The start included version of the match range, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_start_excl, 3); +DEF_ACCESS (cpe_match_range_iterator_version_start_incl, 4); /** - * @brief Return the end included version of the actual match node. + * @brief Return the start excluded version of the match range. * * @param[in] iterator Iterator. * - * @return The end included version of the actual match node, if any. + * @return The start excluded version of the match range, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_end_incl, 4); +DEF_ACCESS (cpe_match_range_iterator_version_start_excl, 5); /** - * @brief Return the end excluded version of the actual match node. + * @brief Return the end included version of the match range. * * @param[in] iterator Iterator. * - * @return The end excluded version of the actual match node, if any. + * @return The end included version of the match range, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_end_excl, 5); +DEF_ACCESS (cpe_match_range_iterator_version_end_incl, 6); + +/** + * @brief Return the end excluded version of the match range. + * + * @param[in] iterator Iterator. + * + * @return The end excluded version of the match range, if any. + * NULL otherwise. + */ +DEF_ACCESS (cpe_match_range_iterator_version_end_excl, 7); + +/** + * @brief Initialize an iterator of CPE matches for a match range + * given a match criteria id. + * + * @param[in] iterator Iterator. + * @param[in] match_criteria_id The match criteria id to get the matches for. + */ +void +init_cpe_match_range_matches_iterator (iterator_t* iterator, const char *match_criteria_id) +{ + init_iterator (iterator, + "SELECT cpe_name_id" + " FROM scap.cpe_matches" + " WHERE match_criteria_id = '%s'", + match_criteria_id); +} + +/** + * @brief Get the CPE name id from a CPE match range matches iterator. + * + * @param[in] iterator Iterator. + * + * @return The CPE name id. + */ +const char * +cpe_matches_cpe_name_id (iterator_t* iterator) +{ + return iterator_string (iterator, 0); +} /** * @brief Initialise a report host prognosis iterator. diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index cd95c4aff..3eee935c7 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3245,115 +3245,24 @@ insert_cve_from_entry (element_t entry, element_t last_modified, /** * @brief Save the node of a cve match rule tree. * - * @param[in] parent_id The parent_id of the node. If this value is 0, - * the node is the root of the tree. * @param[in] cve_id The id of the CVE to which the tree belongs. * @param[in] operator The operator for the match rules. + * @param[in] negate Whether the match rules are negated. * * @return The (database) id of the node. */ static resource_t -save_node (resource_t parent_id, resource_t cve_id, char *operator) +save_node (resource_t cve_id, char *operator, gboolean negate) { return sql_int64_0 ("INSERT INTO scap2.cpe_match_nodes" - " (parent_id, cve_id, operator)" + " (cve_id, operator, negate)" " VALUES" - " (%llu, %llu, '%s')" + " (%llu, '%s', %d)" " RETURNING scap2.cpe_match_nodes.id;", - parent_id, cve_id, - operator); -} - -/** - * @brief Add match rules to a node of a match rule tree* - * - * @param[in] id The id of the node the rules belong to. - * @param[in] match_rules The JSON object that contains the rules. - */ -static void -add_cpe_match_rules (result_t id, cJSON *match_rules) -{ - cJSON *match_rule; - cJSON *ver_se; - cJSON *cpe_js; - - gboolean vulnerable = FALSE; - char * version_start_incl = NULL; - char * version_start_excl = NULL; - char * version_end_incl = NULL; - char * version_end_excl = NULL; - - cJSON_ArrayForEach(match_rule, match_rules) - { - char *sql_cpe = NULL; - vulnerable = FALSE; - version_start_incl = NULL; - version_start_excl = NULL; - version_end_incl = NULL; - version_end_excl = NULL; - - if (cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(match_rule, "vulnerable"))) - vulnerable = TRUE; - else - vulnerable = FALSE; - - cpe_js = cJSON_GetObjectItemCaseSensitive(match_rule, "cpe23Uri"); - if (cpe_js != NULL && strcmp (cpe_js->valuestring, "(null)")) - { - char *quoted_cpe = sql_quote (cpe_js->valuestring); - sql_cpe = g_strdup_printf ("'%s'", quoted_cpe); - g_free (quoted_cpe); - } - else - sql_cpe = g_strdup ("NULL"); - - ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionStartIncluding"); - if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) - version_start_incl = g_strdup_printf ("'%s'", ver_se->valuestring); - else - version_start_incl = g_strdup ("NULL"); - - ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionStartExcluding"); - if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) - version_start_excl = g_strdup_printf ("'%s'", ver_se->valuestring); - else - version_start_excl = g_strdup ("NULL"); - - ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionEndIncluding"); - if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) - version_end_incl = g_strdup_printf ("'%s'", ver_se->valuestring); - else - version_end_incl = g_strdup ("NULL"); - - ver_se = cJSON_GetObjectItemCaseSensitive(match_rule, "versionEndExcluding"); - if (ver_se != NULL && strcmp (ver_se->valuestring, "(null)")) - version_end_excl = g_strdup_printf ("'%s'", ver_se->valuestring); - else - version_end_excl = g_strdup ("NULL"); - - sql - ("INSERT INTO scap2.cpe_match_range" - " (node_id, vulnerable, cpe," - " version_start_incl, version_start_excl," - " version_end_incl, version_end_excl)" - " VALUES" - " (%llu, %d, %s, %s, %s, %s, %s)", - id, - vulnerable ? 1 : 0, - sql_cpe ? sql_cpe : "", - version_start_incl ? version_start_incl : "", - version_start_excl ? version_start_excl : "", - version_end_incl ? version_end_incl : "", - version_end_excl ? version_end_excl : ""); - - g_free (sql_cpe); - g_free (version_start_incl); - g_free (version_start_excl); - g_free (version_end_incl); - g_free (version_end_excl); - } + operator, + negate ? 1 : 0); } /** @@ -3372,52 +3281,185 @@ set_root_id (long int id, long int root_id) } /** - * @brief Load and add recursively all nodes of a match rule tree for a - * specific CVE. Build a match rule tree. + * @brief Handle the references of a CVE. + * + * @param[in] cve_db_id The id of the CVE the references belong to. + * @param[in] cve_id The id of the CVE. + * @param[in] reference_json JSON array containing the references. * - * @param[in] parent_id The parent id of the nodes to insert - * (0 for the root node). - * @param[in] cveid The id of the CVE the tree belongs to. - * @param[in] root_id The root id of the nodes to insert. - * @param[in] nodes The JSON object that contains the rules for a - * specific tree level. + * @return 0 on success, -1 on error. */ -static void -load_nodes (resource_t parent_id, resource_t cveid, resource_t root_id, cJSON *nodes) +static int +handle_cve_references (resource_t cve_db_id, char * cve_id, cJSON* reference_json) { - cJSON *node; - resource_t id; - cJSON *operator; - cJSON *cpe_match_rules; - cJSON *child_nodes; - - node = NULL; - id = 0; - operator = NULL; - cpe_match_rules = NULL; - child_nodes = NULL; - - if (nodes == NULL) - return; + cJSON *reference_data; + cJSON *tags; - cJSON_ArrayForEach(node, nodes) + cJSON_ArrayForEach(reference_data, reference_json) { - operator = cJSON_GetObjectItemCaseSensitive(node, "operator"); - if (operator && operator->valuestring) - id = save_node (parent_id, cveid, operator->valuestring); - else - return; + GString *tags_string; + char *url_value = json_object_item_string (reference_data, "url"); + if (url_value == NULL) + { + g_warning("%s: url missing in reference for %s.", __func__, cve_id); + return -1; + } + + tags = cJSON_GetObjectItemCaseSensitive(reference_data, "tags"); + if (cJSON_IsArray(tags)) + { + array_t *tags_array = make_array (); + tags_string = g_string_new ("{"); + + for (int i = 0; i < cJSON_GetArraySize(tags); i++) + { + cJSON *tag = cJSON_GetArrayItem(tags, i); + if (!cJSON_IsString(tag)) + { + g_warning("%s: tag for %s is NULL or not a string.", __func__, cve_id); + return -1; + } + if ((strcmp (tag->valuestring, "(null)") == 0) || strlen(tag->valuestring) == 0) + { + g_warning("%s: tag for %s is an empty string or has value (null).", __func__, cve_id); + return -1; + } + array_add (tags_array, tag->valuestring); + } + + for (int i = 0; i < tags_array->len; i++) + { + gchar *tag = g_ptr_array_index (tags_array, i); + gchar *quoted_tag = sql_quote (tag); - if (parent_id == 0) - root_id = id; - set_root_id (id, root_id); + g_string_append (tags_string, quoted_tag); - cpe_match_rules = cJSON_GetObjectItemCaseSensitive(node, "cpe_match"); - if (cpe_match_rules) - add_cpe_match_rules (id, cpe_match_rules); - child_nodes = cJSON_GetObjectItemCaseSensitive(node, "children"); - load_nodes (id, cveid, root_id, child_nodes); + if (i < tags_array->len - 1) + g_string_append (tags_string, ","); + + g_free (quoted_tag); + } + g_string_append (tags_string, "}"); + g_ptr_array_free (tags_array, TRUE); + } + + gchar *quoted_url = sql_quote (url_value); + + sql("INSERT INTO scap2.cve_references" + " (cve_id, url, tags)" + " VALUES" + " (%llu, '%s', '%s')" + " ON CONFLICT (cve_id, url) DO UPDATE" + " SET tags = EXCLUDED.tags;", + cve_db_id, + quoted_url, + tags_string->str ?: "{}"); + + g_free (quoted_url); + if (tags_string) + g_string_free (tags_string, TRUE); + } + return 0; +} + +/** + * @brief Handle the configurations of a CVE. + * + * @param[in] cve_db_id The id of the CVE the configurations belong to. + * @param[in] cve_id The id of the CVE. + * @param[in] configurations_json JSON array containing the configurations. + * + * @return 0 on success, -1 on error. + */ +static int +handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configurations_json) +{ + cJSON *configuration_item; + + cJSON_ArrayForEach (configuration_item, configurations_json) + { + cJSON *nodes_array, *node_item; + resource_t id, root_id; + char *config_operator; + int negate; + + nodes_array = cJSON_GetObjectItemCaseSensitive (configuration_item, "nodes"); + if (!cJSON_IsArray (nodes_array)) + { + g_warning("%s: 'nodes' field missing or not an array for %s.", + __func__, cve_id); + return -1; + } + + root_id = -1; + config_operator = json_object_item_string (configuration_item, "operator"); + if (config_operator) + { + negate = json_object_item_boolean (configuration_item, "negate", 0); + id = save_node (cve_db_id, config_operator, negate); + set_root_id (id, id); + root_id = id; + } + + char *node_operator; + cJSON_ArrayForEach(node_item, nodes_array) + { + node_operator = json_object_item_string (node_item, "operator"); + if (node_operator == NULL) + { + g_warning("%s: operator missing for %s.", __func__, cve_id); + return -1; + } + + negate = json_object_item_boolean (node_item, "negate", 0); + + cJSON *cpe_matches_array; + cpe_matches_array = cJSON_GetObjectItemCaseSensitive (node_item, "cpeMatch"); + if (!cJSON_IsArray (cpe_matches_array)) + { + g_warning("%s: cpeMatch missing or not an array for %s.", __func__, cve_id); + return -1; + } + + id = save_node (cve_db_id, node_operator, negate); + if(root_id < 0) + root_id = id; + set_root_id (id, root_id); + + cJSON *cpe_match_item; + cJSON_ArrayForEach(cpe_match_item, cpe_matches_array) + { + char *match_criteria_id; + int vulnerable; + gchar *quoted_match_criteria_id; + + vulnerable = json_object_item_boolean (cpe_match_item, "vulnerable", -1); + if (vulnerable == -1) + { + g_warning("%s: vulnerable missing in cpeMatch for %s.", __func__, cve_id); + return -1; + } + match_criteria_id = json_object_item_string (cpe_match_item, "matchCriteriaId"); + if (match_criteria_id == NULL) + { + g_warning("%s: matchCriteriaId missing in cpeMatch for %s.", __func__, cve_id); + return -1; + } + quoted_match_criteria_id = sql_quote (match_criteria_id); + + sql("INSERT INTO scap2.cpe_nodes_match_criteria" + " (node_id, vulnerable, match_criteria_id)" + " VALUES" + " (%llu, %d, lower ('%s'))", + id, + vulnerable ? 1 : 0, + quoted_match_criteria_id); + + g_free (quoted_match_criteria_id); + } + } } + return 0; } /** @@ -3432,23 +3474,26 @@ static int handle_json_cve_item (cJSON *item) { cJSON *cve_json; - cJSON *cve_data_meta_json; - - char *cve_id; + char *cve_id, *vector; + double score_dbl; resource_t cve_db_id; - cve_json = cJSON_GetObjectItemCaseSensitive(item, "cve"); - cve_data_meta_json = cJSON_GetObjectItemCaseSensitive(cve_json, "CVE_data_meta"); - cve_id = json_object_item_string (cve_data_meta_json, "ID"); + cve_json = cJSON_GetObjectItemCaseSensitive (item, "cve"); + if (!cJSON_IsObject (cve_json)) + { + g_warning("%s: 'cve' field is missing or not an object.", __func__); + return -1; + } + cve_id = json_object_item_string (cve_json, "id"); if (cve_id == NULL) { - g_warning("%s: ID missing.", __func__); + g_warning("%s: cve id missing.", __func__); return -1; } char *published; time_t published_time; - published = json_object_item_string (item, "publishedDate"); + published = json_object_item_string (cve_json, "published"); if (published == NULL) { g_warning("%s: publishedDate missing for %s.", __func__, cve_id); @@ -3458,7 +3503,7 @@ handle_json_cve_item (cJSON *item) char *modified; time_t modified_time; - modified = json_object_item_string (item, "lastModifiedDate"); + modified = json_object_item_string (cve_json, "lastModified"); if (modified == NULL) { g_warning("%s: lastModifiedDate missing for %s.", __func__, cve_id); @@ -3466,55 +3511,64 @@ handle_json_cve_item (cJSON *item) } modified_time = parse_iso_time (modified); - cJSON *impact_json; - cJSON *base_metric_json; - char * cvss_key; - cJSON *cvss_json; - char * vector; - double score_dbl; + cJSON *metrics_json; + cJSON *cvss_metric_array; - impact_json = cJSON_GetObjectItemCaseSensitive(item, "impact"); - if (impact_json == NULL) + metrics_json = cJSON_GetObjectItemCaseSensitive(cve_json, "metrics"); + if (!cJSON_IsObject (metrics_json)) { - g_warning("%s: Impact missing for %s.", __func__, cve_id); + g_warning("%s: Metrics missing or not an object for %s.", __func__, cve_id); return -1; } - base_metric_json = cJSON_GetObjectItemCaseSensitive(impact_json, "baseMetricV4"); - if (base_metric_json != NULL) - cvss_key = "cvssV4"; - else + + gboolean cvss_metric_found = FALSE; + + const char *cvss_metric_keys[] = {"cvssMetricV40", "cvssMetricV31", "cvssMetricV30", "cvssMetricV2"}; + for (int i = 0; i < 4; i++) { - base_metric_json = cJSON_GetObjectItemCaseSensitive(impact_json, "baseMetricV3"); - if (base_metric_json != NULL) - cvss_key = "cvssV3"; - else + cvss_metric_array = cJSON_GetObjectItemCaseSensitive(metrics_json, cvss_metric_keys[i]); + if (cJSON_IsArray (cvss_metric_array) && cJSON_GetArraySize(cvss_metric_array) > 0) { - base_metric_json = cJSON_GetObjectItemCaseSensitive(impact_json, "baseMetricV2"); - if (base_metric_json != NULL) - cvss_key = "cvssV2"; - else - cvss_key = NULL; + cvss_metric_found = TRUE; + break; } } - if (cvss_key != NULL) + + if (cvss_metric_found) { - cvss_json = cJSON_GetObjectItemCaseSensitive(base_metric_json, cvss_key); - if (cvss_json == NULL) - { - g_warning("%s: %s missing for %s.", __func__, cvss_key, cve_id); - return -1; - } - score_dbl = json_object_item_double (cvss_json, "baseScore", SEVERITY_MISSING); - if (score_dbl == SEVERITY_MISSING) - { - g_warning("%s: baseScore missing in %s for %s.", __func__, cvss_key, cve_id); - return -1; - } - vector = json_object_item_string (cvss_json, "vectorString"); - if (vector == NULL) + cJSON *cvss_json; + cJSON *cvss_metric_item; + char *source_type; + + cJSON_ArrayForEach (cvss_metric_item, cvss_metric_array) { - g_warning("%s: vectorString missing for %s.", __func__, cve_id); - return -1; + source_type = json_object_item_string (cvss_metric_item, "type"); + if (source_type == NULL) + { + g_warning("%s: type missing in CVSS metric for %s.", __func__, cve_id); + return -1; + } + else if (strcmp (source_type, "Primary")) + continue; + + cvss_json = cJSON_GetObjectItemCaseSensitive(cvss_metric_item, "cvssData"); + if (!cJSON_IsObject (cvss_json)) + { + g_warning("%s: cvssData missing or not an object for %s.", __func__, cve_id); + return -1; + } + score_dbl = json_object_item_double (cvss_json, "baseScore", SEVERITY_MISSING); + if (score_dbl == SEVERITY_MISSING) + { + g_warning("%s: baseScore missing for %s.", __func__, cve_id); + return -1; + } + vector = json_object_item_string (cvss_json, "vectorString"); + if (vector == NULL) + { + g_warning("%s: vectorString missing for %s.", __func__, cve_id); + return -1; + } } } else @@ -3523,25 +3577,17 @@ handle_json_cve_item (cJSON *item) vector = NULL; } - cJSON *description_json; - cJSON *description_data_json; + cJSON *descriptions_json; cJSON *description_item_json; char *description_value; - description_json = cJSON_GetObjectItemCaseSensitive(cve_json, "description"); - if (description_json == NULL) + descriptions_json = cJSON_GetObjectItemCaseSensitive(cve_json, "descriptions"); + if (!cJSON_IsArray(descriptions_json)) { - g_warning("%s: description missing for %s.", __func__, cve_id); + g_warning("%s: descriptions for %s is missing or not an array.", __func__, cve_id); return -1; } - - description_data_json = cJSON_GetObjectItemCaseSensitive(description_json, "description_data"); - if (description_data_json == NULL) - { - g_warning("%s: description_data missing for %s.", __func__, cve_id); - return -1; - } - cJSON_ArrayForEach (description_item_json, description_data_json) + cJSON_ArrayForEach (description_item_json, descriptions_json) { char *lang = json_object_item_string (description_item_json, "lang"); if (lang != NULL && strcmp(lang, "en") == 0) @@ -3577,24 +3623,27 @@ handle_json_cve_item (cJSON *item) g_free (quoted_description); - cJSON *configurations_json; - cJSON *nodes_json; - - configurations_json = - cJSON_GetObjectItemCaseSensitive(item, "configurations"); - if (configurations_json == NULL) + cJSON *configurations_array; + configurations_array = cJSON_GetObjectItemCaseSensitive(cve_json, "configurations"); + if (! cJSON_IsArray(configurations_array)) { - g_warning("%s: configurations missing for %s.", __func__, cve_id); + g_warning("%s: configurations for %s is missing or not an array.", __func__, cve_id); return -1; } - nodes_json = - cJSON_GetObjectItemCaseSensitive(configurations_json, "nodes"); - if (nodes_json == NULL) + + if (handle_cve_configurations (cve_db_id, cve_id, configurations_array)) + return -1; + + cJSON *references_array; + references_array = cJSON_GetObjectItemCaseSensitive(cve_json, "references"); + if (!cJSON_IsArray(references_array)) { - g_warning("%s: nodes missing for %s.", __func__, cve_id); + g_warning("%s: references for %s is missing or not an array.", __func__, cve_id); return -1; } - load_nodes (0, cve_db_id, 0, nodes_json); + + if (handle_cve_references (cve_db_id, cve_id, references_array)) + return -1; return 0; } @@ -3657,7 +3706,7 @@ update_cve_json (const gchar *cve_path, GHashTable *hashed_cpes) gvm_json_pull_parser_next (&parser, &event); gvm_json_path_elem_t *path_tail = g_queue_peek_tail (event.path); if (event.type == GVM_JSON_PULL_EVENT_ARRAY_START && path_tail && - path_tail->key && strcmp (path_tail->key, "CVE_Items") == 0) + path_tail->key && strcmp (path_tail->key, "vulnerabilities") == 0) { cve_items_found = TRUE; } @@ -3685,7 +3734,7 @@ update_cve_json (const gchar *cve_path, GHashTable *hashed_cpes) entry = gvm_json_pull_expand_container (&parser, &error_message); if (error_message) { - g_warning ("%s: Error expanding CVE item: %s", __func__, error_message); + g_warning ("%s: Error expanding vulnerability item: %s", __func__, error_message); gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); cJSON_Delete (entry); @@ -3917,6 +3966,325 @@ update_scap_cves () return 0; } +/** + * @brief Insert a SCAP CPE match string from JSON. + * + * @param[in] inserts Pointer to SQL buffer for match string entries. + * @param[in] matches_inserts Pointer to SQL buffer for match string matches. + * @param[in] match_string_item JSON object from the matchStrings list. + * + * @return 0 success, -1 error. + */ +static int +handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, + cJSON *match_string_item) +{ + cJSON *match_string, *matches_array; + char *criteria, *match_criteria_id, *status, *ver_se; + gchar *quoted_version_start_incl, *quoted_version_start_excl; + gchar *quoted_version_end_incl, *quoted_version_end_excl; + gchar *quoted_criteria, *quoted_match_criteria_id, *quoted_cpe_name_id; + int first; + + assert (inserts); + assert (matches_inserts); + + match_string = cJSON_GetObjectItemCaseSensitive (match_string_item, "matchString"); + if (!cJSON_IsObject (match_string)) + { + g_warning ("%s: 'matchString' field is missing or not an object", + __func__); + return -1; + } + + criteria = json_object_item_string (match_string, "criteria"); + if (criteria == NULL) + { + g_warning ("%s: 'criteria' field missing or not a string", __func__); + return -1; + } + + match_criteria_id = json_object_item_string (match_string, "matchCriteriaId"); + if (match_criteria_id == NULL) + { + g_warning ("%s: 'matchCriteriaId' field missing or not a string", __func__); + return -1; + } + + status = json_object_item_string (match_string, "status"); + if (status == NULL) + { + g_warning ("%s: 'status' field missing or not a string", __func__); + return -1; + } + + ver_se = json_object_item_string (match_string, "versionStartIncluding"); + if (ver_se == NULL) + quoted_version_start_incl = g_strdup ("NULL"); + else + quoted_version_start_incl = g_strdup_printf ("'%s'", ver_se); + + ver_se = json_object_item_string (match_string, "versionStartExcluding"); + if (ver_se == NULL) + quoted_version_start_excl = g_strdup ("NULL"); + else + quoted_version_start_excl = g_strdup_printf ("'%s'", ver_se); + + ver_se = json_object_item_string (match_string, "versionEndIncluding"); + if (ver_se == NULL) + quoted_version_end_incl = g_strdup ("NULL"); + else + quoted_version_end_incl = g_strdup_printf ("'%s'", ver_se); + + ver_se = json_object_item_string (match_string, "versionEndExcluding"); + if (ver_se == NULL) + quoted_version_end_excl = g_strdup ("NULL"); + else + quoted_version_end_excl = g_strdup_printf ("'%s'", ver_se); + + quoted_match_criteria_id = sql_quote (match_criteria_id); + quoted_criteria = sql_quote (criteria); + + first = inserts_check_size (inserts); + + g_string_append_printf (inserts->statement, + "%s (lower('%s'), '%s', %s, %s, %s, %s, '%s')", + first ? "" : ",", + quoted_match_criteria_id, + quoted_criteria, + quoted_version_start_incl, + quoted_version_start_excl, + quoted_version_end_incl, + quoted_version_end_excl, + status); + + inserts->current_chunk_size++; + + g_free (quoted_criteria); + g_free (quoted_version_start_incl); + g_free (quoted_version_start_excl); + g_free (quoted_version_end_incl); + g_free (quoted_version_end_excl); + + matches_array = cJSON_GetObjectItemCaseSensitive (match_string, "matches"); + + if (cJSON_IsArray (matches_array) && cJSON_GetArraySize (matches_array) > 0) + { + cJSON *match_item; + cJSON_ArrayForEach (match_item, matches_array) + { + char *cpe_name_id; + + cpe_name_id = json_object_item_string (match_item, "cpeNameId"); + if (cpe_name_id == NULL) + { + g_warning ("%s: 'cpeNameId' field missing or not a string", __func__); + g_free (quoted_match_criteria_id); + return -1; + } + + quoted_cpe_name_id = sql_quote (cpe_name_id); + + first = inserts_check_size (matches_inserts); + + g_string_append_printf (matches_inserts->statement, + "%s (lower('%s'), lower('%s'))", + first ? "" : ",", + quoted_match_criteria_id, + quoted_cpe_name_id); + + matches_inserts->current_chunk_size++; + + g_free (quoted_cpe_name_id); + } + } + + g_free (quoted_match_criteria_id); + return 0; +} + +/** + * @brief Updates the CPE match strings in the SCAP database. + * + * @return 0 success, -1 error. + */ +static int +update_scap_cpe_match_strings () +{ + gchar *current_json_path; + FILE *cpe_match_strings_file; + gvm_json_pull_event_t event; + gvm_json_pull_parser_t parser; + inserts_t inserts, matches_inserts; + + current_json_path = g_build_filename (GVM_SCAP_DATA_DIR, + "cpe_match_strings.json.gz", + NULL); + int fd = open(current_json_path, O_RDONLY); + + if (fd < 0 && errno == ENOENT) + { + g_free (current_json_path); + current_json_path = g_build_filename (GVM_SCAP_DATA_DIR, + "cpe_match_strings.json", + NULL); + fd = open(current_json_path, O_RDONLY); + } + + if (fd < 0) + { + int ret; + if (errno == ENOENT) + { + g_info ("%s: CPE match strings file '%s' not found", + __func__, current_json_path); + ret = 0; + } + else + { + g_warning ("%s: Failed to open CPE match strings file: %s", + __func__, strerror (errno)); + ret = -1; + } + g_free (current_json_path); + return ret; + } + + cpe_match_strings_file = gvm_gzip_open_file_reader_fd (fd); + + if (cpe_match_strings_file == NULL) + { + g_warning ("%s: Failed to convert file descriptor to FILE*: %s", + __func__, + strerror (errno)); + g_free (current_json_path); + close (fd); + return -1; + } + + g_info ("Updating CPE match strings from %s", current_json_path); + g_free (current_json_path); + + gvm_json_pull_event_init (&event); + gvm_json_pull_parser_init (&parser, cpe_match_strings_file); + + gvm_json_pull_parser_next (&parser, &event); + + if (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) + { + gboolean cpe_match_strings_found = FALSE; + while (!cpe_match_strings_found) + { + gvm_json_pull_parser_next (&parser, &event); + gvm_json_path_elem_t *path_tail = g_queue_peek_tail (event.path); + if (event.type == GVM_JSON_PULL_EVENT_ARRAY_START + && path_tail && strcmp (path_tail->key, "matchStrings") == 0) + { + cpe_match_strings_found = TRUE; + } + else if (event.type == GVM_JSON_PULL_EVENT_ERROR) + { + g_warning ("%s: Parser error: %s", __func__, event.error_message); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + else if (event.type == GVM_JSON_PULL_EVENT_OBJECT_END + && g_queue_is_empty (event.path)) + { + g_warning ("%s: Unexpected json object end. Missing CPE matched strings field", __func__); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + } + + sql_begin_immediate (); + inserts_init (&inserts, + CPE_MAX_CHUNK_SIZE, + setting_secinfo_sql_buffer_threshold_bytes (), + "INSERT INTO scap2.cpe_match_range" + " (match_criteria_id, cpe, version_start_incl," + " version_start_excl, version_end_incl, version_end_excl," + " status)" + " VALUES ", + " ON CONFLICT (match_criteria_id) DO UPDATE" + " SET cpe = EXCLUDED.cpe," + " version_start_incl = EXCLUDED.version_start_incl," + " version_start_excl = EXCLUDED.version_start_excl," + " version_end_incl = EXCLUDED.version_end_incl," + " version_end_excl = EXCLUDED.version_end_excl," + " status = EXCLUDED.status"); + + inserts_init (&matches_inserts, 10, + setting_secinfo_sql_buffer_threshold_bytes (), + "INSERT INTO scap2.cpe_matches" + " (match_criteria_id, cpe_name_id)" + " VALUES ", + ""); + + gvm_json_pull_parser_next (&parser, &event); + while (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) + { + gchar *error_message; + cJSON *cpe_match_string_item = gvm_json_pull_expand_container (&parser, &error_message); + if (error_message) + { + g_warning ("%s: Error expanding match string item: %s", __func__, error_message); + cJSON_Delete (cpe_match_string_item); + inserts_free (&inserts); + inserts_free (&matches_inserts); + sql_commit (); + g_warning ("Update of cpe match strings failed"); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + if (handle_json_cpe_match_string (&inserts, &matches_inserts, cpe_match_string_item)) + { + cJSON_Delete (cpe_match_string_item); + inserts_free (&inserts); + inserts_free (&matches_inserts); + sql_commit (); + g_warning ("Update of cpe match strings failed"); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + cJSON_Delete (cpe_match_string_item); + gvm_json_pull_parser_next (&parser, &event); + } + } + else if (event.type == GVM_JSON_PULL_EVENT_ERROR) + { + g_warning ("%s: Parser error: %s", __func__, event.error_message); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + else + { + g_warning ("%s: CVE affected products file is not a JSON object.", __func__); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return -1; + } + + inserts_run (&inserts, TRUE); + inserts_run (&matches_inserts, TRUE); + sql_commit (); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (cpe_match_strings_file); + return 0; +} + /** * @brief Adds a EPSS score entry to an SQL inserts buffer. * @@ -5120,6 +5488,15 @@ update_scap (gboolean reset_scap_db) return -1; } + g_debug ("%s: update cpe match strings", __func__); + setproctitle ("Syncing SCAP: Updating CPE Match Strings"); + + if (update_scap_cpe_match_strings () == -1) + { + abort_scap_update (); + return -1; + } + g_debug ("%s: update cves", __func__); setproctitle ("Syncing SCAP: Updating CVEs"); diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index eb2feaf73..216f603d5 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -13129,6 +13129,8 @@ END:VCALENDAR epss nvts cert + configuration_nodes + references raw_data A CVE info element @@ -13249,6 +13251,161 @@ END:VCALENDAR + + configuration_nodes + List of configuration nodes. Only when details were requested + + node + + + node + A configuration node for the CVE + + operator + match_criteria + node + + + operator + The operator for the match criteria + + text + + + + match_criteria + The match criteria for the node + + match_string + vulnerable + version_start_including + version_start_excluding + version_end_including + version_end_excluding + matched_cpes + + + match_string + A CPE Match string + + text + + + + vulnerable + A true or false value, whether matching CPEs are considered vulnerable + + text + + + + version_start_including + From version (including) + + text + + + + version_start_excluding + From version (excluding) + + text + + + + version_end_including + Up to version (including) + + text + + + + version_end_excluding + Up to version (exluding) + + text + + + + matched_cpes + List of matching CPEs + + name + deprecated + deprecated_by + + + name + Name of the matching CPE + + text + + + + deprecated + A true or false value, whether the CPE is deprecated + + text + + + + deprecated_by + CPE ID the current CPE is deprecated by. Only when the CPE is deprecated + + + cpe_id + uuid + CPE ID the current CPE is deprecated by + + + + + + + node + Nodes can contain other nested nodes + + node + + + + + + references + References of this CVE. Only when details were requested + + reference + + + reference + Reference of the CVE + + url + tags + + + url + The URL of the reference + + text + + + + tags + List of tags for the reference + + tag + + + tag + Tag for a reference + + text + + + + + raw_data Source representation of the information. Only when details were requested From ba2dcd533f7d8dca8a56b1587f36ec982fd8ee85 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 1 Nov 2024 17:39:00 +0100 Subject: [PATCH 21/64] Address minor issues --- src/gmp.c | 10 ++++------ src/manage_sql_secinfo.c | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index fe766df12..9857f9825 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13283,13 +13283,12 @@ print_cpe_match_nodes_xml(resource_t node, GString *buffer) init_cpe_match_range_iterator (&cpe_match_ranges, node); while (next (&cpe_match_ranges)) { - const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *range_uri_product; + const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *match_string; xml_string_append (buffer, ""); match_criteria_id = cpe_match_range_iterator_match_criteria_id (&cpe_match_ranges); - range_uri_product - = fs_cpe_to_uri_cpe (cpe_match_range_iterator_cpe (&cpe_match_ranges)); - xml_string_append (buffer, "%s", range_uri_product?: ""); + match_string = cpe_match_range_iterator_cpe (&cpe_match_ranges); + xml_string_append (buffer, "%s", match_string?: ""); xml_string_append (buffer, "%s", cpe_match_range_iterator_vulnerable (&cpe_match_ranges) != 0 ? "1" @@ -13334,8 +13333,7 @@ print_cpe_match_nodes_xml(resource_t node, GString *buffer) } cleanup_iterator (&cpes); - xml_string_append (buffer, ""); - xml_string_append (buffer, "%s", cpe?: ""); + xml_string_append (buffer, "", cpe?: ""); xml_string_append (buffer, "%s", deprecated ? "1" : "0"); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 8b3cdbde0..2fd61350e 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3492,7 +3492,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configura sql("INSERT INTO scap2.cpe_nodes_match_criteria" " (node_id, vulnerable, match_criteria_id)" " VALUES" - " (%llu, %d, lower ('%s'))", + " (%llu, %d, '%s')", id, vulnerable ? 1 : 0, quoted_match_criteria_id); @@ -4085,12 +4085,12 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, quoted_version_end_excl = g_strdup_printf ("'%s'", ver_se); quoted_match_criteria_id = sql_quote (match_criteria_id); - quoted_criteria = sql_quote (criteria); + quoted_criteria = fs_to_uri_convert_and_quote_cpe_name (criteria); first = inserts_check_size (inserts); g_string_append_printf (inserts->statement, - "%s (lower('%s'), '%s', %s, %s, %s, %s, '%s')", + "%s ('%s', '%s', %s, %s, %s, %s, '%s')", first ? "" : ",", quoted_match_criteria_id, quoted_criteria, @@ -4130,7 +4130,7 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, first = inserts_check_size (matches_inserts); g_string_append_printf (matches_inserts->statement, - "%s (lower('%s'), lower('%s'))", + "%s ('%s', '%s')", first ? "" : ",", quoted_match_criteria_id, quoted_cpe_name_id); From 03f546ad9b58bd3648fc3e8ab9319d9599c2081f Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 1 Nov 2024 17:41:53 +0100 Subject: [PATCH 22/64] Update names of CVE JSON feed files --- src/manage_sql_secinfo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 2fd61350e..19bea8b35 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3961,8 +3961,8 @@ update_scap_cves () gboolean read_json = FALSE; while ((cve_path = g_dir_read_name (dir))) { - if (fnmatch ("nvdcve-1.1-*.json.gz", cve_path, 0) == 0 || - fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) + if (fnmatch ("nvdcve-2.0-*.json.gz", cve_path, 0) == 0 || + fnmatch ("nvdcve-2.0-*.json", cve_path, 0) == 0) { read_json = TRUE; break; @@ -3973,8 +3973,8 @@ update_scap_cves () count = 0; while ((cve_path = g_dir_read_name (dir))) { - if ((fnmatch ("nvdcve-1.1-*.json.gz", cve_path, 0) == 0 || - fnmatch ("nvdcve-1.1-*.json", cve_path, 0) == 0) + if ((fnmatch ("nvdcve-2.0-*.json.gz", cve_path, 0) == 0 || + fnmatch ("nvdcve-2.0-*.json", cve_path, 0) == 0) && read_json) { if (update_cve_json (cve_path, hashed_cpes)) From 64983cac2ae8d8cc66234ab078e159c5236b35e6 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Mon, 4 Nov 2024 14:13:16 +0100 Subject: [PATCH 23/64] Minor code changes and adjusting formatting --- src/gmp.c | 64 ++++--- src/manage_pg.c | 4 + src/manage_sql.c | 17 +- src/manage_sql_secinfo.c | 267 +++++++++++++++++------------- src/schema_formats/XML/GMP.xml.in | 8 + 5 files changed, 218 insertions(+), 142 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 9857f9825..833434055 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13261,15 +13261,17 @@ handle_get_groups (gmp_parser_t *gmp_parser, GError **error) * @param[in] buffer Buffer into which to print match node. */ static void -print_cpe_match_nodes_xml(resource_t node, GString *buffer) +print_cpe_match_nodes_xml (resource_t node, GString *buffer) { iterator_t cpe_match_nodes, cpe_match_ranges; - const char *operator = NULL; - int negate = 0; init_iterator (&cpe_match_nodes, - "SELECT operator, negate FROM scap.cpe_match_nodes WHERE id = %llu;", + "SELECT operator, negate" + " FROM scap.cpe_match_nodes WHERE id = %llu;", node); + + const char *operator = NULL; + int negate = 0; while (next (&cpe_match_nodes)) { operator = iterator_string (&cpe_match_nodes, 0); @@ -13286,17 +13288,23 @@ print_cpe_match_nodes_xml(resource_t node, GString *buffer) const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *match_string; xml_string_append (buffer, ""); - match_criteria_id = cpe_match_range_iterator_match_criteria_id (&cpe_match_ranges); + match_criteria_id + = cpe_match_range_iterator_match_criteria_id (&cpe_match_ranges); match_string = cpe_match_range_iterator_cpe (&cpe_match_ranges); - xml_string_append (buffer, "%s", match_string?: ""); - xml_string_append (buffer, "%s", + + xml_string_append (buffer, + "%s", + match_string?: ""); + xml_string_append (buffer, + "%s", cpe_match_range_iterator_vulnerable (&cpe_match_ranges) != 0 ? "1" : "0"); - vsi = cpe_match_range_iterator_version_start_incl(&cpe_match_ranges); - vse = cpe_match_range_iterator_version_start_excl(&cpe_match_ranges); - vei = cpe_match_range_iterator_version_end_incl(&cpe_match_ranges); - vee = cpe_match_range_iterator_version_end_excl(&cpe_match_ranges); + + vsi = cpe_match_range_iterator_version_start_incl (&cpe_match_ranges); + vse = cpe_match_range_iterator_version_start_excl (&cpe_match_ranges); + vei = cpe_match_range_iterator_version_end_incl (&cpe_match_ranges); + vee = cpe_match_range_iterator_version_end_excl (&cpe_match_ranges); xml_string_append (buffer, "%s", @@ -13335,7 +13343,7 @@ print_cpe_match_nodes_xml(resource_t node, GString *buffer) xml_string_append (buffer, "", cpe?: ""); xml_string_append (buffer, - "%s", + "%s", deprecated ? "1" : "0"); if (deprecated) { @@ -13366,7 +13374,7 @@ print_cpe_match_nodes_xml(resource_t node, GString *buffer) * */ static void -print_cve_affected_software_configs_xml (gchar *cve_uuid, GString *result) +print_cve_configurations_xml (const gchar *cve_uuid, GString *result) { iterator_t cpe_match_root_nodes; xml_string_append (result, ""); @@ -13377,14 +13385,15 @@ print_cve_affected_software_configs_xml (gchar *cve_uuid, GString *result) iterator_t cpe_match_node_childs; root_node = cpe_match_nodes_iterator_root_id (&cpe_match_root_nodes); xml_string_append (result, ""); - print_cpe_match_nodes_xml(root_node, result); + print_cpe_match_nodes_xml (root_node, result); init_cpe_match_node_childs_iterator (&cpe_match_node_childs, root_node); while (next (&cpe_match_node_childs)) { resource_t child_node; - child_node = cpe_match_node_childs_iterator_id (&cpe_match_node_childs); + child_node = + cpe_match_node_childs_iterator_id (&cpe_match_node_childs); xml_string_append (result, ""); - print_cpe_match_nodes_xml(child_node, result); + print_cpe_match_nodes_xml (child_node, result); xml_string_append (result, ""); } xml_string_append (result, ""); @@ -13402,7 +13411,7 @@ print_cve_affected_software_configs_xml (gchar *cve_uuid, GString *result) * */ static void -print_cve_references_xml (gchar *cve_uuid, GString *result) +print_cve_references_xml (const gchar *cve_uuid, GString *result) { iterator_t references; init_cve_reference_iterator (&references, cve_uuid); @@ -13410,20 +13419,26 @@ print_cve_references_xml (gchar *cve_uuid, GString *result) while (next (&references)) { xml_string_append (result, ""); - xml_string_append (result, "%s", cve_reference_iterator_url (&references)); + xml_string_append (result, + "%s", + cve_reference_iterator_url (&references)); xml_string_append (result, ""); const char * tags_array = cve_reference_iterator_tags (&references); - if(tags_array && strlen(tags_array) > 2) + if(tags_array && strlen (tags_array) > 2) { - char *trimmed_array = g_strndup (tags_array + 1, strlen (tags_array) - 2); + char *trimmed_array + = g_strndup (tags_array + 1, strlen (tags_array) - 2); gchar **tags, **current_tag; tags = g_strsplit (trimmed_array, ",", -1); current_tag = tags; while (*current_tag) { - if (strlen (*current_tag) > 2 && (*current_tag)[0] == '"' && (*current_tag)[strlen (*current_tag) - 1] == '"') + if (strlen (*current_tag) > 2 + && (*current_tag)[0] == '"' + && (*current_tag)[strlen (*current_tag) - 1] == '"') { - char *trimmed_tag = g_strndup (*current_tag + 1, strlen (*current_tag) - 2); + char *trimmed_tag = g_strndup (*current_tag + 1, + strlen (*current_tag) - 2); xml_string_append (result, "%s", trimmed_tag); g_free (trimmed_tag); } @@ -13816,10 +13831,9 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error) } g_string_append (result, ""); - gchar *cve_uuid = g_strdup(get_iterator_uuid (&info)); - print_cve_affected_software_configs_xml (cve_uuid, result); + const gchar *cve_uuid = get_iterator_uuid (&info); + print_cve_configurations_xml (cve_uuid, result); print_cve_references_xml (cve_uuid, result); - g_free(cve_uuid); } } else if (g_strcmp0 ("cert_bund_adv", get_info_data->type) == 0) diff --git a/src/manage_pg.c b/src/manage_pg.c index 893d3e240..da79adb05 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3649,6 +3649,10 @@ manage_db_add_constraints (const gchar *name) sql ("ALTER TABLE scap2.cpe_match_range" " ADD UNIQUE (match_criteria_id);"); + sql ("ALTER TABLE scap2.cpe_matches" + " ALTER match_criteria_id SET NOT NULL," + " ALTER cpe_name_id SET NOT NULL," + " ADD UNIQUE (match_criteria_id, cpe_name_id);"); } else { diff --git a/src/manage_sql.c b/src/manage_sql.c index 71461dc00..ef9cb24e4 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20511,10 +20511,12 @@ init_cpe_match_nodes_iterator (iterator_t* iterator, const char *cpe) gchar *quoted_cpe; quoted_cpe = sql_quote (cpe); init_iterator (iterator, - " SELECT DISTINCT n.root_id" + "SELECT DISTINCT n.root_id" " FROM scap.cpe_match_nodes n" - " JOIN scap.cpe_nodes_match_criteria c ON n.id = c.node_id" - " JOIN scap.cpe_match_range r ON c.match_criteria = r.match_criteria_id" + " JOIN scap.cpe_nodes_match_criteria c" + " ON n.id = c.node_id" + " JOIN scap.cpe_match_range r" + " ON c.match_criteria = r.match_criteria_id" " WHERE cpe like '%s%%';", quoted_cpe); g_free (quoted_cpe); @@ -20534,7 +20536,8 @@ init_cve_cpe_match_nodes_iterator (iterator_t* iterator, const char *cve) init_iterator (iterator, "SELECT DISTINCT root_id" " FROM scap.cpe_match_nodes" - " WHERE cve_id = (SELECT id from scap.cves where uuid = '%s');", + " WHERE cve_id = (SELECT id FROM scap.cves" + " WHERE uuid = '%s');", quoted_cve); g_free (quoted_cve); } @@ -20553,7 +20556,8 @@ init_cve_reference_iterator (iterator_t* iterator, const char *cve) init_iterator (iterator, "SELECT url, array_length(tags, 1), tags" " FROM scap.cve_references" - " WHERE cve_id = (SELECT id from scap.cves where uuid = '%s');", + " WHERE cve_id = (SELECT id FROM scap.cves" + " WHERE uuid = '%s');", quoted_cve); g_free (quoted_cve); } @@ -20736,7 +20740,8 @@ DEF_ACCESS (cpe_match_range_iterator_version_end_excl, 7); * @param[in] match_criteria_id The match criteria id to get the matches for. */ void -init_cpe_match_range_matches_iterator (iterator_t* iterator, const char *match_criteria_id) +init_cpe_match_range_matches_iterator (iterator_t* iterator, + const char *match_criteria_id) { init_iterator (iterator, "SELECT cpe_name_id" diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 19bea8b35..b7b421ce6 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3289,7 +3289,7 @@ insert_cve_from_entry (element_t entry, element_t last_modified, * * @param[in] cve_id The id of the CVE to which the tree belongs. * @param[in] operator The operator for the match rules. - * @param[in] negate Whether the match rules are negated. + * @param[in] negate Whether the operator is negated. * * @return The (database) id of the node. */ @@ -3332,75 +3332,80 @@ set_root_id (long int id, long int root_id) * @return 0 on success, -1 on error. */ static int -handle_cve_references (resource_t cve_db_id, char * cve_id, cJSON* reference_json) +handle_cve_references (resource_t cve_db_id, char * cve_id, + cJSON* reference_json) { cJSON *reference_data; cJSON *tags; - cJSON_ArrayForEach(reference_data, reference_json) - { - GString *tags_string; - char *url_value = json_object_item_string (reference_data, "url"); - if (url_value == NULL) + cJSON_ArrayForEach (reference_data, reference_json) { - g_warning("%s: url missing in reference for %s.", __func__, cve_id); - return -1; - } - - tags = cJSON_GetObjectItemCaseSensitive(reference_data, "tags"); - if (cJSON_IsArray(tags)) + GString *tags_string; + char *url_value = json_object_item_string (reference_data, "url"); + if (url_value == NULL) { - array_t *tags_array = make_array (); - tags_string = g_string_new ("{"); - - for (int i = 0; i < cJSON_GetArraySize(tags); i++) - { - cJSON *tag = cJSON_GetArrayItem(tags, i); - if (!cJSON_IsString(tag)) - { - g_warning("%s: tag for %s is NULL or not a string.", __func__, cve_id); - return -1; - } - if ((strcmp (tag->valuestring, "(null)") == 0) || strlen(tag->valuestring) == 0) - { - g_warning("%s: tag for %s is an empty string or has value (null).", __func__, cve_id); - return -1; - } - array_add (tags_array, tag->valuestring); - } - - for (int i = 0; i < tags_array->len; i++) - { - gchar *tag = g_ptr_array_index (tags_array, i); - gchar *quoted_tag = sql_quote (tag); - - g_string_append (tags_string, quoted_tag); - - if (i < tags_array->len - 1) - g_string_append (tags_string, ","); - - g_free (quoted_tag); - } - g_string_append (tags_string, "}"); - g_ptr_array_free (tags_array, TRUE); + g_warning ("%s: url missing in reference for %s.", + __func__, cve_id); + return -1; } - gchar *quoted_url = sql_quote (url_value); - - sql("INSERT INTO scap2.cve_references" - " (cve_id, url, tags)" - " VALUES" - " (%llu, '%s', '%s')" - " ON CONFLICT (cve_id, url) DO UPDATE" - " SET tags = EXCLUDED.tags;", - cve_db_id, - quoted_url, - tags_string->str ?: "{}"); + tags = cJSON_GetObjectItemCaseSensitive (reference_data, "tags"); + if (cJSON_IsArray (tags)) + { + array_t *tags_array = make_array (); + tags_string = g_string_new ("{"); + + for (int i = 0; i < cJSON_GetArraySize (tags); i++) + { + cJSON *tag = cJSON_GetArrayItem (tags, i); + if (!cJSON_IsString (tag)) + { + g_warning ("%s: tag for %s is NULL or not a string.", + __func__, cve_id); + return -1; + } + if ((strcmp (tag->valuestring, "(null)") == 0) + || strlen (tag->valuestring) == 0) + { + g_warning ("%s: tag for %s is empty string or NULL.", + __func__, cve_id); + return -1; + } + array_add (tags_array, tag->valuestring); + } + + for (int i = 0; i < tags_array->len; i++) + { + gchar *tag = g_ptr_array_index (tags_array, i); + gchar *quoted_tag = sql_quote (tag); + + g_string_append (tags_string, quoted_tag); + + if (i < tags_array->len - 1) + g_string_append (tags_string, ","); + + g_free (quoted_tag); + } + g_string_append (tags_string, "}"); + g_ptr_array_free (tags_array, TRUE); + } - g_free (quoted_url); - if (tags_string) - g_string_free (tags_string, TRUE); - } + gchar *quoted_url = sql_quote (url_value); + + sql ("INSERT INTO scap2.cve_references" + " (cve_id, url, tags)" + " VALUES" + " (%llu, '%s', '%s')" + " ON CONFLICT (cve_id, url) DO UPDATE" + " SET tags = EXCLUDED.tags;", + cve_db_id, + quoted_url, + tags_string->str ?: "{}"); + + g_free (quoted_url); + if (tags_string) + g_string_free (tags_string, TRUE); + } return 0; } @@ -3414,7 +3419,8 @@ handle_cve_references (resource_t cve_db_id, char * cve_id, cJSON* reference_jso * @return 0 on success, -1 on error. */ static int -handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configurations_json) +handle_cve_configurations (resource_t cve_db_id, char * cve_id, + cJSON* configurations_json) { cJSON *configuration_item; @@ -3425,16 +3431,18 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configura char *config_operator; int negate; - nodes_array = cJSON_GetObjectItemCaseSensitive (configuration_item, "nodes"); + nodes_array = cJSON_GetObjectItemCaseSensitive (configuration_item, + "nodes"); if (!cJSON_IsArray (nodes_array)) { - g_warning("%s: 'nodes' field missing or not an array for %s.", + g_warning ("%s: 'nodes' field missing or not an array for %s.", __func__, cve_id); return -1; } root_id = -1; - config_operator = json_object_item_string (configuration_item, "operator"); + config_operator = json_object_item_string (configuration_item, + "operator"); if (config_operator) { negate = json_object_item_boolean (configuration_item, "negate", 0); @@ -3449,47 +3457,55 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configura node_operator = json_object_item_string (node_item, "operator"); if (node_operator == NULL) { - g_warning("%s: operator missing for %s.", __func__, cve_id); + g_warning ("%s: operator missing for %s.", __func__, cve_id); return -1; } negate = json_object_item_boolean (node_item, "negate", 0); cJSON *cpe_matches_array; - cpe_matches_array = cJSON_GetObjectItemCaseSensitive (node_item, "cpeMatch"); + cpe_matches_array = cJSON_GetObjectItemCaseSensitive (node_item, + "cpeMatch"); if (!cJSON_IsArray (cpe_matches_array)) { - g_warning("%s: cpeMatch missing or not an array for %s.", __func__, cve_id); + g_warning ("%s: cpeMatch missing or not an array for %s.", + __func__, cve_id); return -1; } id = save_node (cve_db_id, node_operator, negate); - if(root_id < 0) + + if (root_id < 0) root_id = id; + set_root_id (id, root_id); cJSON *cpe_match_item; - cJSON_ArrayForEach(cpe_match_item, cpe_matches_array) + cJSON_ArrayForEach (cpe_match_item, cpe_matches_array) { char *match_criteria_id; int vulnerable; gchar *quoted_match_criteria_id; - vulnerable = json_object_item_boolean (cpe_match_item, "vulnerable", -1); + vulnerable = json_object_item_boolean (cpe_match_item, + "vulnerable", -1); if (vulnerable == -1) { - g_warning("%s: vulnerable missing in cpeMatch for %s.", __func__, cve_id); + g_warning ("%s: vulnerable missing in cpeMatch for %s.", + __func__, cve_id); return -1; } - match_criteria_id = json_object_item_string (cpe_match_item, "matchCriteriaId"); + match_criteria_id = json_object_item_string (cpe_match_item, + "matchCriteriaId"); if (match_criteria_id == NULL) { - g_warning("%s: matchCriteriaId missing in cpeMatch for %s.", __func__, cve_id); + g_warning ("%s: matchCriteriaId missing in cpeMatch for %s.", + __func__, cve_id); return -1; } quoted_match_criteria_id = sql_quote (match_criteria_id); - sql("INSERT INTO scap2.cpe_nodes_match_criteria" + sql ("INSERT INTO scap2.cpe_nodes_match_criteria" " (node_id, vulnerable, match_criteria_id)" " VALUES" " (%llu, %d, '%s')", @@ -3523,13 +3539,13 @@ handle_json_cve_item (cJSON *item) cve_json = cJSON_GetObjectItemCaseSensitive (item, "cve"); if (!cJSON_IsObject (cve_json)) { - g_warning("%s: 'cve' field is missing or not an object.", __func__); + g_warning ("%s: 'cve' field is missing or not an object.", __func__); return -1; } cve_id = json_object_item_string (cve_json, "id"); if (cve_id == NULL) { - g_warning("%s: cve id missing.", __func__); + g_warning ("%s: cve id missing.", __func__); return -1; } @@ -3548,7 +3564,7 @@ handle_json_cve_item (cJSON *item) modified = json_object_item_string (cve_json, "lastModified"); if (modified == NULL) { - g_warning("%s: lastModifiedDate missing for %s.", __func__, cve_id); + g_warning ("%s: lastModifiedDate missing for %s.", __func__, cve_id); return -1; } modified_time = parse_iso_time (modified); @@ -3556,20 +3572,28 @@ handle_json_cve_item (cJSON *item) cJSON *metrics_json; cJSON *cvss_metric_array; - metrics_json = cJSON_GetObjectItemCaseSensitive(cve_json, "metrics"); + metrics_json = cJSON_GetObjectItemCaseSensitive (cve_json, "metrics"); if (!cJSON_IsObject (metrics_json)) { - g_warning("%s: Metrics missing or not an object for %s.", __func__, cve_id); + g_warning ("%s: Metrics missing or not an object for %s.", + __func__, cve_id); return -1; } gboolean cvss_metric_found = FALSE; - const char *cvss_metric_keys[] = {"cvssMetricV40", "cvssMetricV31", "cvssMetricV30", "cvssMetricV2"}; + const char *cvss_metric_keys[] = { + "cvssMetricV40", + "cvssMetricV31", + "cvssMetricV30", + "cvssMetricV2"}; + for (int i = 0; i < 4; i++) { - cvss_metric_array = cJSON_GetObjectItemCaseSensitive(metrics_json, cvss_metric_keys[i]); - if (cJSON_IsArray (cvss_metric_array) && cJSON_GetArraySize(cvss_metric_array) > 0) + cvss_metric_array + = cJSON_GetObjectItemCaseSensitive (metrics_json, cvss_metric_keys[i]); + if (cJSON_IsArray (cvss_metric_array) + && cJSON_GetArraySize (cvss_metric_array) > 0) { cvss_metric_found = TRUE; break; @@ -3587,28 +3611,33 @@ handle_json_cve_item (cJSON *item) source_type = json_object_item_string (cvss_metric_item, "type"); if (source_type == NULL) { - g_warning("%s: type missing in CVSS metric for %s.", __func__, cve_id); + g_warning ("%s: type missing in CVSS metric for %s.", + __func__, cve_id); return -1; } else if (strcmp (source_type, "Primary")) continue; - cvss_json = cJSON_GetObjectItemCaseSensitive(cvss_metric_item, "cvssData"); + cvss_json = cJSON_GetObjectItemCaseSensitive (cvss_metric_item, + "cvssData"); if (!cJSON_IsObject (cvss_json)) { - g_warning("%s: cvssData missing or not an object for %s.", __func__, cve_id); + g_warning ("%s: cvssData missing or not an object for %s.", + __func__, cve_id); return -1; } - score_dbl = json_object_item_double (cvss_json, "baseScore", SEVERITY_MISSING); + score_dbl = json_object_item_double (cvss_json, + "baseScore", + SEVERITY_MISSING); if (score_dbl == SEVERITY_MISSING) { - g_warning("%s: baseScore missing for %s.", __func__, cve_id); + g_warning ("%s: baseScore missing for %s.", __func__, cve_id); return -1; } vector = json_object_item_string (cvss_json, "vectorString"); if (vector == NULL) { - g_warning("%s: vectorString missing for %s.", __func__, cve_id); + g_warning ("%s: vectorString missing for %s.", __func__, cve_id); return -1; } } @@ -3623,17 +3652,20 @@ handle_json_cve_item (cJSON *item) cJSON *description_item_json; char *description_value; - descriptions_json = cJSON_GetObjectItemCaseSensitive(cve_json, "descriptions"); - if (!cJSON_IsArray(descriptions_json)) + descriptions_json = cJSON_GetObjectItemCaseSensitive (cve_json, + "descriptions"); + if (!cJSON_IsArray (descriptions_json)) { - g_warning("%s: descriptions for %s is missing or not an array.", __func__, cve_id); + g_warning ("%s: descriptions for %s is missing or not an array.", + __func__, cve_id); return -1; } cJSON_ArrayForEach (description_item_json, descriptions_json) { char *lang = json_object_item_string (description_item_json, "lang"); - if (lang != NULL && strcmp(lang, "en") == 0) - description_value = json_object_item_string (description_item_json, "value"); + if (lang != NULL && strcmp (lang, "en") == 0) + description_value = json_object_item_string (description_item_json, + "value"); } char *quoted_description = sql_quote (description_value); @@ -3666,10 +3698,12 @@ handle_json_cve_item (cJSON *item) g_free (quoted_description); cJSON *configurations_array; - configurations_array = cJSON_GetObjectItemCaseSensitive(cve_json, "configurations"); - if (! cJSON_IsArray(configurations_array)) + configurations_array = cJSON_GetObjectItemCaseSensitive (cve_json, + "configurations"); + if (!cJSON_IsArray (configurations_array)) { - g_warning("%s: configurations for %s is missing or not an array.", __func__, cve_id); + g_warning ("%s: configurations for %s is missing or not an array.", + __func__, cve_id); return -1; } @@ -3677,10 +3711,11 @@ handle_json_cve_item (cJSON *item) return -1; cJSON *references_array; - references_array = cJSON_GetObjectItemCaseSensitive(cve_json, "references"); - if (!cJSON_IsArray(references_array)) + references_array = cJSON_GetObjectItemCaseSensitive (cve_json, "references"); + if (!cJSON_IsArray (references_array)) { - g_warning("%s: references for %s is missing or not an array.", __func__, cve_id); + g_warning ("%s: references for %s is missing or not an array.", + __func__, cve_id); return -1; } @@ -4031,7 +4066,8 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, assert (inserts); assert (matches_inserts); - match_string = cJSON_GetObjectItemCaseSensitive (match_string_item, "matchString"); + match_string = cJSON_GetObjectItemCaseSensitive (match_string_item, + "matchString"); if (!cJSON_IsObject (match_string)) { g_warning ("%s: 'matchString' field is missing or not an object", @@ -4046,10 +4082,12 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, return -1; } - match_criteria_id = json_object_item_string (match_string, "matchCriteriaId"); + match_criteria_id = json_object_item_string (match_string, + "matchCriteriaId"); if (match_criteria_id == NULL) { - g_warning ("%s: 'matchCriteriaId' field missing or not a string", __func__); + g_warning ("%s: 'matchCriteriaId' field missing or not a string", + __func__); return -1; } @@ -4120,7 +4158,8 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, cpe_name_id = json_object_item_string (match_item, "cpeNameId"); if (cpe_name_id == NULL) { - g_warning ("%s: 'cpeNameId' field missing or not a string", __func__); + g_warning ("%s: 'cpeNameId' field missing or not a string", + __func__); g_free (quoted_match_criteria_id); return -1; } @@ -4235,7 +4274,8 @@ update_scap_cpe_match_strings () else if (event.type == GVM_JSON_PULL_EVENT_OBJECT_END && g_queue_is_empty (event.path)) { - g_warning ("%s: Unexpected json object end. Missing CPE matched strings field", __func__); + g_warning ("%s: Unexpected json object end. Missing matchStrings field", + __func__); gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); fclose (cpe_match_strings_file); @@ -4271,27 +4311,31 @@ update_scap_cpe_match_strings () while (event.type == GVM_JSON_PULL_EVENT_OBJECT_START) { gchar *error_message; - cJSON *cpe_match_string_item = gvm_json_pull_expand_container (&parser, &error_message); + cJSON *cpe_match_string_item + = gvm_json_pull_expand_container (&parser, &error_message); if (error_message) { - g_warning ("%s: Error expanding match string item: %s", __func__, error_message); + g_warning ("%s: Error expanding match string item: %s", + __func__, error_message); cJSON_Delete (cpe_match_string_item); inserts_free (&inserts); inserts_free (&matches_inserts); sql_commit (); - g_warning ("Update of cpe match strings failed"); + g_warning ("Update of CPE match strings failed"); gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); fclose (cpe_match_strings_file); return -1; } - if (handle_json_cpe_match_string (&inserts, &matches_inserts, cpe_match_string_item)) + if (handle_json_cpe_match_string (&inserts, + &matches_inserts, + cpe_match_string_item)) { cJSON_Delete (cpe_match_string_item); inserts_free (&inserts); inserts_free (&matches_inserts); sql_commit (); - g_warning ("Update of cpe match strings failed"); + g_warning ("Update of CPE match strings failed"); gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); fclose (cpe_match_strings_file); @@ -4311,7 +4355,8 @@ update_scap_cpe_match_strings () } else { - g_warning ("%s: CVE affected products file is not a JSON object.", __func__); + g_warning ("%s: CVE match strings file is not a JSON object.", + __func__); gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); fclose (cpe_match_strings_file); diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 216f603d5..17b1381f5 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -13262,6 +13262,7 @@ END:VCALENDAR A configuration node for the CVE operator + negate match_criteria node @@ -13272,6 +13273,13 @@ END:VCALENDAR text + + negate + A true or false value, whether the operator is negated + + text + + match_criteria The match criteria for the node From 6ff3d18c121a928b406a02b43ca3159d8641bb85 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Tue, 5 Nov 2024 11:44:09 +0100 Subject: [PATCH 24/64] Code refactoring - Rename scap.cpe_match_range to scap.cpe_match_strings - Rename cpe in cpe_match_range to criteria - Add cpe_name to scap.cpe_matches - Add status to the configuration nodes in the response of get_info command --- src/gmp.c | 44 ++++++++------- src/manage.c | 14 ++--- src/manage.h | 23 ++++---- src/manage_pg.c | 9 +-- src/manage_sql.c | 93 ++++++++++++++++++------------- src/manage_sql_secinfo.c | 29 +++++++--- src/schema_formats/XML/GMP.xml.in | 12 ++-- 7 files changed, 128 insertions(+), 96 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 833434055..462a7ed07 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13282,29 +13282,31 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) xml_string_append (buffer, "%s", operator?: ""); xml_string_append (buffer, "%s", negate? "1" : "0"); - init_cpe_match_range_iterator (&cpe_match_ranges, node); + init_cpe_match_string_iterator (&cpe_match_ranges, node); while (next (&cpe_match_ranges)) { - const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *match_string; + const gchar *vsi, *vse, *vei, *vee, *match_criteria_id, *criteria, *status; - xml_string_append (buffer, ""); + xml_string_append (buffer, ""); match_criteria_id - = cpe_match_range_iterator_match_criteria_id (&cpe_match_ranges); - match_string = cpe_match_range_iterator_cpe (&cpe_match_ranges); + = cpe_match_string_iterator_match_criteria_id (&cpe_match_ranges); + criteria = cpe_match_string_iterator_criteria (&cpe_match_ranges); + status = cpe_match_string_iterator_status (&cpe_match_ranges); xml_string_append (buffer, - "%s", - match_string?: ""); - xml_string_append (buffer, - "%s", - cpe_match_range_iterator_vulnerable (&cpe_match_ranges) != 0 + "%s" + "%s" + "%s", + criteria?: "", + cpe_match_string_iterator_vulnerable (&cpe_match_ranges) != 0 ? "1" - : "0"); + : "0", + status?: ""); - vsi = cpe_match_range_iterator_version_start_incl (&cpe_match_ranges); - vse = cpe_match_range_iterator_version_start_excl (&cpe_match_ranges); - vei = cpe_match_range_iterator_version_end_incl (&cpe_match_ranges); - vee = cpe_match_range_iterator_version_end_excl (&cpe_match_ranges); + vsi = cpe_match_string_iterator_version_start_incl (&cpe_match_ranges); + vse = cpe_match_string_iterator_version_start_excl (&cpe_match_ranges); + vei = cpe_match_string_iterator_version_end_incl (&cpe_match_ranges); + vee = cpe_match_string_iterator_version_end_excl (&cpe_match_ranges); xml_string_append (buffer, "%s", @@ -13320,7 +13322,7 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) vee ?: ""); iterator_t cpe_matches; - init_cpe_match_range_matches_iterator (&cpe_matches, match_criteria_id); + init_cpe_match_string_matches_iterator (&cpe_matches, match_criteria_id); xml_string_append (buffer, ""); while (next (&cpe_matches)) @@ -13328,16 +13330,16 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) iterator_t cpes; init_iterator (&cpes, - "SELECT name, deprecated FROM scap.cpes" + "SELECT deprecated FROM scap.cpes" " WHERE cpe_name_id = '%s';", cpe_matches_cpe_name_id(&cpe_matches)); - const char* cpe = NULL; + const char* cpe = cpe_matches_cpe_name (&cpe_matches); + int deprecated = 0; while (next (&cpes)) { - cpe = iterator_string (&cpes, 0); - deprecated = iterator_int (&cpes, 1); + deprecated = iterator_int (&cpes, 0); } cleanup_iterator (&cpes); @@ -13361,7 +13363,7 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) xml_string_append (buffer, ""); } xml_string_append (buffer, ""); - xml_string_append (buffer, ""); + xml_string_append (buffer, ""); cleanup_iterator (&cpe_matches); } cleanup_iterator (&cpe_match_ranges); diff --git a/src/manage.c b/src/manage.c index fca82209f..f61426986 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3180,7 +3180,7 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, return; } - init_cpe_match_range_iterator (&cpe_match_ranges, node); + init_cpe_match_string_iterator (&cpe_match_ranges, node); while (next (&cpe_match_ranges)) { iterator_t cpe_host_details_products; @@ -3188,11 +3188,11 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, gchar *range_uri_product; gchar *vsi, *vse, *vei, *vee; range_fs_cpe = vsi = vse = vei = vee = NULL; - range_fs_cpe = g_strdup (cpe_match_range_iterator_cpe (&cpe_match_ranges)); - vsi = g_strdup (cpe_match_range_iterator_version_start_incl (&cpe_match_ranges)); - vse = g_strdup (cpe_match_range_iterator_version_start_excl (&cpe_match_ranges)); - vei = g_strdup (cpe_match_range_iterator_version_end_incl (&cpe_match_ranges)); - vee = g_strdup (cpe_match_range_iterator_version_end_excl (&cpe_match_ranges)); + range_fs_cpe = g_strdup (cpe_match_string_iterator_criteria (&cpe_match_ranges)); + vsi = g_strdup (cpe_match_string_iterator_version_start_incl (&cpe_match_ranges)); + vse = g_strdup (cpe_match_string_iterator_version_start_excl (&cpe_match_ranges)); + vei = g_strdup (cpe_match_string_iterator_version_end_incl (&cpe_match_ranges)); + vee = g_strdup (cpe_match_string_iterator_version_end_excl (&cpe_match_ranges)); range_uri_product = fs_cpe_to_uri_product (range_fs_cpe); init_host_details_cpe_product_iterator (&cpe_host_details_products, range_uri_product, report_host); while (next (&cpe_host_details_products)) @@ -3216,7 +3216,7 @@ check_cpe_match_rule (long long int node, gboolean *match, gboolean *vulnerable, cpe_struct_free (&source); cpe_struct_free (&target); } - if (*match && cpe_match_range_iterator_vulnerable (&cpe_match_ranges) == 1) + if (*match && cpe_match_string_iterator_vulnerable (&cpe_match_ranges) == 1) { cpe_struct_t source, target; cpe_struct_init (&source); diff --git a/src/manage.h b/src/manage.h index 93cbb01e2..2930789b9 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1724,38 +1724,41 @@ long long int cpe_match_node_childs_iterator_id (iterator_t*); void -init_cpe_match_range_iterator (iterator_t*, long long int); +init_cpe_match_string_iterator (iterator_t*, long long int); const char* -cpe_match_range_iterator_cpe (iterator_t*); +cpe_match_string_iterator_criteria (iterator_t*); const char* -cpe_match_range_iterator_match_criteria_id (iterator_t*); +cpe_match_string_iterator_match_criteria_id (iterator_t*); const char* -cpe_match_range_iterator_status (iterator_t*); +cpe_match_string_iterator_status (iterator_t*); const char* -cpe_match_range_iterator_version_start_incl (iterator_t*); +cpe_match_string_iterator_version_start_incl (iterator_t*); const char* -cpe_match_range_iterator_version_start_excl (iterator_t*); +cpe_match_string_iterator_version_start_excl (iterator_t*); const char* -cpe_match_range_iterator_version_end_incl (iterator_t*); +cpe_match_string_iterator_version_end_incl (iterator_t*); const char* -cpe_match_range_iterator_version_end_excl (iterator_t*); +cpe_match_string_iterator_version_end_excl (iterator_t*); int -cpe_match_range_iterator_vulnerable (iterator_t*); +cpe_match_string_iterator_vulnerable (iterator_t*); void -init_cpe_match_range_matches_iterator (iterator_t*, const char *); +init_cpe_match_string_matches_iterator (iterator_t*, const char *); const char* cpe_matches_cpe_name_id (iterator_t*); +const char* +cpe_matches_cpe_name (iterator_t*); + void init_host_details_cpe_product_iterator (iterator_t*, const char *, report_host_t); diff --git a/src/manage_pg.c b/src/manage_pg.c index da79adb05..43e031b99 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3557,10 +3557,10 @@ manage_db_init (const gchar *name) " vulnerable integer DEFAULT 0," " match_criteria_id text);"); - sql ("CREATE TABLE scap2.cpe_match_range" + sql ("CREATE TABLE scap2.cpe_match_strings" " (id SERIAL PRIMARY KEY," " match_criteria_id text," - " cpe text DEFAULT NULL," + " criteria text DEFAULT NULL," " version_start_incl text DEFAULT NULL," " version_start_excl text DEFAULT NULL," " version_end_incl text DEFAULT NULL," @@ -3570,7 +3570,8 @@ manage_db_init (const gchar *name) sql ("CREATE TABLE scap2.cpe_matches" " (id SERIAL PRIMARY KEY," " match_criteria_id text," - " cpe_name_id text);"); + " cpe_name_id text," + " cpe_name text);"); sql ("CREATE TABLE scap2.cpe_details" " (id SERIAL PRIMARY KEY," @@ -3646,7 +3647,7 @@ manage_db_add_constraints (const gchar *name) " ALTER url SET NOT NULL," " ADD UNIQUE (cve_id, url);"); - sql ("ALTER TABLE scap2.cpe_match_range" + sql ("ALTER TABLE scap2.cpe_match_strings" " ADD UNIQUE (match_criteria_id);"); sql ("ALTER TABLE scap2.cpe_matches" diff --git a/src/manage_sql.c b/src/manage_sql.c index ef9cb24e4..3f47b535a 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20503,23 +20503,23 @@ DEF_ACCESS (host_details_cpe_product_iterator_value, 0); * @brief Initialize an iterator of root_ids of CPE match nodes. * * @param[in] iterator Iterator. - * @param[in] cpe The cpe contained in the match nodes. + * @param[in] criteria The criteria for the match nodes. */ void -init_cpe_match_nodes_iterator (iterator_t* iterator, const char *cpe) +init_cpe_match_nodes_iterator (iterator_t* iterator, const char *criteria) { - gchar *quoted_cpe; - quoted_cpe = sql_quote (cpe); + gchar *quoted_criteria; + quoted_criteria = sql_quote (criteria); init_iterator (iterator, "SELECT DISTINCT n.root_id" " FROM scap.cpe_match_nodes n" " JOIN scap.cpe_nodes_match_criteria c" " ON n.id = c.node_id" - " JOIN scap.cpe_match_range r" + " JOIN scap.cpe_match_strings r" " ON c.match_criteria = r.match_criteria_id" - " WHERE cpe like '%s%%';", - quoted_cpe); - g_free (quoted_cpe); + " WHERE criteria like '%s%%';", + quoted_criteria); + g_free (quoted_criteria); } /** @@ -20632,19 +20632,19 @@ cpe_match_node_childs_iterator_id (iterator_t* iterator) } /** - * @brief Initialize an iterator of match ranges of an CPE match node. + * @brief Initialize an iterator of match strings of an CPE match node. * * @param[in] iterator Iterator. - * @param[in] node The match node with match ranges. + * @param[in] node The match node with match strings. */ void -init_cpe_match_range_iterator (iterator_t* iterator, long long int node) +init_cpe_match_string_iterator (iterator_t* iterator, long long int node) { init_iterator (iterator, - "SELECT n.vulnerable, r.cpe, r.match_criteria_id, r.status," + "SELECT n.vulnerable, r.criteria, r.match_criteria_id, r.status," " r.version_start_incl, r.version_start_excl," " r.version_end_incl, r.version_end_excl" - " FROM scap.cpe_match_range r" + " FROM scap.cpe_match_strings r" " JOIN scap.cpe_nodes_match_criteria n" " ON r.match_criteria_id = n.match_criteria_id" " WHERE n.node_id = %llu;", @@ -20652,106 +20652,106 @@ init_cpe_match_range_iterator (iterator_t* iterator, long long int node) } /** - * @brief Return if the CPE of the actual match node is vulnerable. + * @brief Return if the match criteria is vulnerable. * * @param[in] iterator Iterator. * - * @return 1 if the match node is vulnerable, 0 otherwise. + * @return 1 if the match criteria is vulnerable, 0 otherwise. */ int -cpe_match_range_iterator_vulnerable (iterator_t* iterator) +cpe_match_string_iterator_vulnerable (iterator_t* iterator) { return iterator_int64 (iterator, 0); } /** - * @brief Return the CPE of the actual match node. + * @brief Return the criteria of the CPE match string. * * @param[in] iterator Iterator. * - * @return The CPE of the actual match node. + * @return The criteria of the match string. */ -DEF_ACCESS (cpe_match_range_iterator_cpe, 1); +DEF_ACCESS (cpe_match_string_iterator_criteria, 1); /** - * @brief Return the match criteria id of the CPE match range. + * @brief Return the match criteria id of the CPE match string. * * @param[in] iterator Iterator. * * @return The match criteria id, if any. NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_match_criteria_id, 2); +DEF_ACCESS (cpe_match_string_iterator_match_criteria_id, 2); /** - * @brief Return the status of the CPE match range. + * @brief Return the status of the CPE match criteria. * * @param[in] iterator Iterator. * - * @return The status of the CPE match range, if any. + * @return The status of the CPE match criteria, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_status, 3); +DEF_ACCESS (cpe_match_string_iterator_status, 3); /** - * @brief Return the start included version of the match range. + * @brief Return the start included version of the match criteria. * * @param[in] iterator Iterator. * - * @return The start included version of the match range, if any. + * @return The start included version of the match criteria, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_start_incl, 4); +DEF_ACCESS (cpe_match_string_iterator_version_start_incl, 4); /** - * @brief Return the start excluded version of the match range. + * @brief Return the start excluded version of the match criteria. * * @param[in] iterator Iterator. * - * @return The start excluded version of the match range, if any. + * @return The start excluded version of the match criteria, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_start_excl, 5); +DEF_ACCESS (cpe_match_string_iterator_version_start_excl, 5); /** - * @brief Return the end included version of the match range. + * @brief Return the end included version of the match criteria. * * @param[in] iterator Iterator. * - * @return The end included version of the match range, if any. + * @return The end included version of the match criteria, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_end_incl, 6); +DEF_ACCESS (cpe_match_string_iterator_version_end_incl, 6); /** - * @brief Return the end excluded version of the match range. + * @brief Return the end excluded version of the match criteria. * * @param[in] iterator Iterator. * - * @return The end excluded version of the match range, if any. + * @return The end excluded version of the match criteria, if any. * NULL otherwise. */ -DEF_ACCESS (cpe_match_range_iterator_version_end_excl, 7); +DEF_ACCESS (cpe_match_string_iterator_version_end_excl, 7); /** - * @brief Initialize an iterator of CPE matches for a match range + * @brief Initialize an iterator of CPE matches for a match string * given a match criteria id. * * @param[in] iterator Iterator. * @param[in] match_criteria_id The match criteria id to get the matches for. */ void -init_cpe_match_range_matches_iterator (iterator_t* iterator, +init_cpe_match_string_matches_iterator (iterator_t* iterator, const char *match_criteria_id) { init_iterator (iterator, - "SELECT cpe_name_id" + "SELECT cpe_name_id, cpe_name" " FROM scap.cpe_matches" " WHERE match_criteria_id = '%s'", match_criteria_id); } /** - * @brief Get the CPE name id from a CPE match range matches iterator. + * @brief Get the CPE name id from a CPE match string matches iterator. * * @param[in] iterator Iterator. * @@ -20763,6 +20763,19 @@ cpe_matches_cpe_name_id (iterator_t* iterator) return iterator_string (iterator, 0); } +/** + * @brief Get the CPE name from a CPE match string matches iterator. + * + * @param[in] iterator Iterator. + * + * @return The CPE name id. + */ +const char * +cpe_matches_cpe_name (iterator_t* iterator) +{ + return iterator_string (iterator, 1); +} + /** * @brief Initialise a report host prognosis iterator. * diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index b7b421ce6..4e6d3d6fc 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -4060,7 +4060,7 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, char *criteria, *match_criteria_id, *status, *ver_se; gchar *quoted_version_start_incl, *quoted_version_start_excl; gchar *quoted_version_end_incl, *quoted_version_end_excl; - gchar *quoted_criteria, *quoted_match_criteria_id, *quoted_cpe_name_id; + gchar *quoted_criteria, *quoted_match_criteria_id; int first; assert (inserts); @@ -4153,7 +4153,8 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, cJSON *match_item; cJSON_ArrayForEach (match_item, matches_array) { - char *cpe_name_id; + char *cpe_name_id, *cpe_name; + gchar *quoted_cpe_name_id, *quoted_cpe_name; cpe_name_id = json_object_item_string (match_item, "cpeNameId"); if (cpe_name_id == NULL) @@ -4164,19 +4165,31 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, return -1; } + cpe_name = json_object_item_string (match_item, "cpeName"); + if (cpe_name == NULL) + { + g_warning ("%s: 'cpe_name' field missing or not a string", + __func__); + g_free (quoted_match_criteria_id); + return -1; + } + quoted_cpe_name_id = sql_quote (cpe_name_id); + quoted_cpe_name = fs_to_uri_convert_and_quote_cpe_name (cpe_name); first = inserts_check_size (matches_inserts); g_string_append_printf (matches_inserts->statement, - "%s ('%s', '%s')", + "%s ('%s', '%s', '%s')", first ? "" : ",", quoted_match_criteria_id, - quoted_cpe_name_id); + quoted_cpe_name_id, + quoted_cpe_name); matches_inserts->current_chunk_size++; g_free (quoted_cpe_name_id); + g_free (quoted_cpe_name); } } @@ -4287,13 +4300,13 @@ update_scap_cpe_match_strings () inserts_init (&inserts, CPE_MAX_CHUNK_SIZE, setting_secinfo_sql_buffer_threshold_bytes (), - "INSERT INTO scap2.cpe_match_range" - " (match_criteria_id, cpe, version_start_incl," + "INSERT INTO scap2.cpe_match_strings" + " (match_criteria_id, criteria, version_start_incl," " version_start_excl, version_end_incl, version_end_excl," " status)" " VALUES ", " ON CONFLICT (match_criteria_id) DO UPDATE" - " SET cpe = EXCLUDED.cpe," + " SET criteria = EXCLUDED.criteria," " version_start_incl = EXCLUDED.version_start_incl," " version_start_excl = EXCLUDED.version_start_excl," " version_end_incl = EXCLUDED.version_end_incl," @@ -4303,7 +4316,7 @@ update_scap_cpe_match_strings () inserts_init (&matches_inserts, 10, setting_secinfo_sql_buffer_threshold_bytes (), "INSERT INTO scap2.cpe_matches" - " (match_criteria_id, cpe_name_id)" + " (match_criteria_id, cpe_name_id, cpe_name)" " VALUES ", ""); diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 17b1381f5..5bb6e166d 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -13263,7 +13263,7 @@ END:VCALENDAR operator negate - match_criteria + match_string node @@ -13281,10 +13281,10 @@ END:VCALENDAR - match_criteria - The match criteria for the node + match_string + The match string for the node - match_string + criteria vulnerable version_start_including version_start_excluding @@ -13293,8 +13293,8 @@ END:VCALENDAR matched_cpes - match_string - A CPE Match string + criteria + A CPE match criteria text From 9b43edec2328de3b6b9f8ac564bc64d6c1f8b343 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 28 Oct 2024 09:49:26 +0100 Subject: [PATCH 25/64] Remove: Removed feature toggle for compliance report views. Removed the feature toggle for the dedicated compliance report views. --- CMakeLists.txt | 13 - src/gmp.c | 49 +-- src/gvmd.c | 2 - src/manage_sql.c | 910 +++++++++++++++++++++++------------------------ 4 files changed, 456 insertions(+), 518 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb6b215d2..d5c958a34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,25 +247,12 @@ if (NOT CVSS3_RATINGS) endif (NOT CVSS3_RATINGS) add_definitions (-DCVSS3_RATINGS=${CVSS3_RATINGS}) -if (NOT COMPLIANCE_REPORTS) - set (COMPLIANCE_REPORTS 1) -endif (NOT COMPLIANCE_REPORTS) -add_definitions (-DCOMPLIANCE_REPORTS=${COMPLIANCE_REPORTS}) - message ("-- Install prefix: ${CMAKE_INSTALL_PREFIX}") ## Version set (GVMD_VERSION "${PROJECT_VERSION_STRING}") -if (COMPLIANCE_REPORTS EQUAL 1) - set(IF_COMPLIANCE_REPORTS "") - set(ENDIF_COMPLIANCE_REPORTS "") -elseif (COMPLIANCE_REPORTS EQUAL 0) - set(IF_COMPLIANCE_REPORTS "") -endif() - # Configure Doxyfile with version number configure_file (doc/Doxyfile.in doc/Doxyfile) configure_file (doc/Doxyfile_full.in doc/Doxyfile_full) diff --git a/src/gmp.c b/src/gmp.c index b90c1ff54..ae84d3e58 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -12956,11 +12956,6 @@ handle_get_features (gmp_parser_t *gmp_parser, GError **error) " status=\"" STATUS_OK "\"" " status_text=\"" STATUS_OK_TEXT "\">"); - SENDF_TO_CLIENT_OR_FAIL ("" - "COMPLIANCE_REPORTS" - "", - COMPLIANCE_REPORTS ? 1 : 0); - SENDF_TO_CLIENT_OR_FAIL ("" "CVSS3_RATINGS" "", @@ -14925,31 +14920,23 @@ handle_get_reports (gmp_parser_t *gmp_parser, GError **error) overrides = filter_term_apply_overrides (filter ? filter : get->filter); min_qod = filter_term_min_qod (filter ? filter : get->filter); levels = filter_term_value (filter ? filter : get->filter, "levels"); - #if COMPLIANCE_REPORTS == 1 - gchar *compliance_levels; - compliance_levels = filter_term_value (filter - ? filter - : get->filter, - "compliance_levels"); - - /* Setup result filter from overrides. */ - get_reports_data->get.filter - = g_strdup_printf - ("apply_overrides=%i min_qod=%i levels=%s compliance_levels=%s", - overrides, - min_qod, - levels ? levels : "hmlgdf", - compliance_levels ? compliance_levels : "yniu"); - g_free (compliance_levels); - #else - /* Setup result filter from overrides. */ - get_reports_data->get.filter - = g_strdup_printf - ("apply_overrides=%i min_qod=%i levels=%s", - overrides, - min_qod, - levels ? levels : "hmlgdf"); - #endif + + gchar *compliance_levels; + compliance_levels = filter_term_value (filter + ? filter + : get->filter, + "compliance_levels"); + + /* Setup result filter from overrides. */ + get_reports_data->get.filter + = g_strdup_printf + ("apply_overrides=%i min_qod=%i levels=%s compliance_levels=%s", + overrides, + min_qod, + levels ? levels : "hmlgdf", + compliance_levels ? compliance_levels : "yniu"); + g_free (compliance_levels); + g_free (filter); g_free (levels); } @@ -15997,7 +15984,6 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, else if (g_strcmp0 ("report", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_iterator; -#if COMPLIANCE_REPORTS == 1 get_data_set_extra (&resource_names_data->get, "usage_type", g_strdup ("scan")); @@ -16008,7 +15994,6 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, get_data_set_extra (&resource_names_data->get, "usage_type", g_strdup ("audit")); -#endif } else if (g_strcmp0 ("report_config", resource_names_data->type) == 0) { diff --git a/src/gvmd.c b/src/gvmd.c index 0fbe8051b..722ea2022 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -2325,9 +2325,7 @@ gvmd (int argc, char** argv, char *env[]) #if CVSS3_RATINGS == 1 printf ("CVSS3 severity ratings enabled\n"); #endif -#if COMPLIANCE_REPORTS == 1 printf ("Compliance reports enabled\n"); -#endif printf ("Copyright (C) 2009-2021 Greenbone AG\n"); printf ("License: AGPL-3.0-or-later\n"); printf diff --git a/src/manage_sql.c b/src/manage_sql.c index fc1bf3905..9e33f3277 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -2221,7 +2221,7 @@ manage_report_filter_controls (const gchar *filter, int *first, int *max, else *apply_overrides = val; } - + if (compliance_levels) { if (filter_control_str ((keyword_t **) split->pdata, @@ -3980,14 +3980,9 @@ valid_type (const char* type) int valid_subtype (const char* type) { - #if COMPLIANCE_REPORTS == 1 return (strcasecmp (type, "audit_report") == 0) || (strcasecmp (type, "audit") == 0) || (strcasecmp (type, "policy") == 0); - #else - return (strcasecmp (type, "audit") == 0) - || (strcasecmp (type, "policy") == 0); - #endif } /** @@ -14406,7 +14401,7 @@ manage_test_alert (const char *alert_id, gchar **script_message) NULL); if (result) report_add_result (report, result); - + result = make_result ( task, "127.0.0.1", "localhost", "general/tcp", @@ -18335,7 +18330,7 @@ task_usage_type (task_t task, char ** usage_type) task); if (usage_type == NULL) return -1; - + return 0; } @@ -22230,7 +22225,6 @@ report_iterator_opts_table (int override, int min_qod) min_qod); } -#if COMPLIANCE_REPORTS == 1 /** * @brief Return SQL WHERE for restricting a SELECT to compliance statuses. * @@ -22288,7 +22282,6 @@ where_compliance_status (const char *compliance) return g_string_free (compliance_sql, FALSE);; } -#endif /** * @brief Generate an extra WHERE clause for selecting reports @@ -22323,32 +22316,30 @@ reports_extra_where (int trash, const gchar *filter, const char *usage_type) g_string_append_printf(extra_where, "%s", trash_clause); g_free (trash_clause); - #if COMPLIANCE_REPORTS == 1 - gchar *usage_type_clause, *compliance_clause = NULL; - gchar *compliance_filter = NULL; - if (usage_type && strcmp (usage_type, "")) - { - gchar *quoted_usage_type; - quoted_usage_type = sql_quote (usage_type); - usage_type_clause = g_strdup_printf (" AND task in (SELECT id from tasks" - " WHERE usage_type='%s')", - quoted_usage_type); + gchar *usage_type_clause, *compliance_clause = NULL; + gchar *compliance_filter = NULL; + if (usage_type && strcmp (usage_type, "")) + { + gchar *quoted_usage_type; + quoted_usage_type = sql_quote (usage_type); + usage_type_clause = g_strdup_printf (" AND task in (SELECT id from tasks" + " WHERE usage_type='%s')", + quoted_usage_type); - g_free (quoted_usage_type); - } - else - usage_type_clause = NULL; + g_free (quoted_usage_type); + } + else + usage_type_clause = NULL; - if (filter) - compliance_filter = filter_term_value(filter, "report_compliance_levels"); + if (filter) + compliance_filter = filter_term_value(filter, "report_compliance_levels"); - compliance_clause = where_compliance_status (compliance_filter ?: "yniu"); + compliance_clause = where_compliance_status (compliance_filter ?: "yniu"); - g_string_append_printf (extra_where, "%s%s", usage_type_clause ?: "", compliance_clause ?: ""); - g_free (compliance_filter); - g_free (compliance_clause); - g_free (usage_type_clause); - #endif + g_string_append_printf (extra_where, "%s%s", usage_type_clause ?: "", compliance_clause ?: ""); + g_free (compliance_filter); + g_free (compliance_clause); + g_free (usage_type_clause); return g_string_free (extra_where, FALSE); } @@ -22370,7 +22361,7 @@ report_count (const get_data_t *get) int ret; extra_tables = report_iterator_opts_table (0, MIN_QOD_DEFAULT); - + const gchar *usage_type = get_data_get_extra (get, "usage_type"); extra_where = reports_extra_where(get->trash, get->filter, usage_type); @@ -23797,7 +23788,7 @@ result_count (const get_data_t *get, report_t report, const char* host) dynamic_severity, "results", "nvts"); - + extra_tables = g_strdup_printf (" LEFT OUTER JOIN result_vt_epss" " ON results.nvt = result_vt_epss.vt_id" " LEFT OUTER JOIN nvts" @@ -26167,7 +26158,6 @@ report_counts_id_full (report_t report, int* holes, int* infos, return 0; } -#if COMPLIANCE_REPORTS == 1 /** * @brief Get the compliance state from compliance counts. * @@ -26312,8 +26302,6 @@ report_compliance_counts (report_t report, return 0; } -#endif - /** * @brief Get only the filtered message counts for a report. @@ -28052,7 +28040,7 @@ print_report_host_tls_certificates_xml (report_host_t report_host, " AND (source_description = 'SSL/TLS Certificate'" " OR source_description = 'SSL Certificate')", report_host); - + while (next (&tls_certs)) { const char *certificate_prefixed, *certificate_b64; @@ -28636,54 +28624,53 @@ print_report_host_xml (FILE *stream, host_iterator_asset_uuid (hosts)); else if (lean == 0) PRINT (stream, - ""); + ""); - #if COMPLIANCE_REPORTS == 1 - if (strcmp (usage_type, "audit") == 0) - { - int yes_count, no_count, incomplete_count, undefined_count; - - yes_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_compliant, current_host)); - no_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_notcompliant, current_host)); - incomplete_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_incomplete, current_host)); - undefined_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_undefined, current_host)); - - PRINT (stream, - "%s" - "%s" - "%d" - "" - "%d" - "%d" - "%d" - "%d" - "%d" - "" - "%s", - host_iterator_start_time (hosts), - host_iterator_end_time (hosts) - ? host_iterator_end_time (hosts) - : "", - ports_count, - (yes_count + no_count + incomplete_count + undefined_count), - yes_count, - no_count, - incomplete_count, - undefined_count, - report_compliance_from_counts (&yes_count, - &no_count, - &incomplete_count, - &undefined_count)); - } else - #endif + if (strcmp (usage_type, "audit") == 0) + { + int yes_count, no_count, incomplete_count, undefined_count; + + yes_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_compliant, current_host)); + no_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_notcompliant, current_host)); + incomplete_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_incomplete, current_host)); + undefined_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_undefined, current_host)); + + PRINT (stream, + "%s" + "%s" + "%d" + "" + "%d" + "%d" + "%d" + "%d" + "%d" + "" + "%s", + host_iterator_start_time (hosts), + host_iterator_end_time (hosts) + ? host_iterator_end_time (hosts) + : "", + ports_count, + (yes_count + no_count + incomplete_count + undefined_count), + yes_count, + no_count, + incomplete_count, + undefined_count, + report_compliance_from_counts (&yes_count, + &no_count, + &incomplete_count, + &undefined_count)); + } + else { int holes_count, warnings_count, infos_count; int logs_count, false_positives_count; @@ -28703,7 +28690,7 @@ print_report_host_xml (FILE *stream, false_positives_count = GPOINTER_TO_INT (g_hash_table_lookup ( f_host_false_positives, - current_host)); + current_host)); PRINT (stream, "%s" @@ -29855,30 +29842,29 @@ print_v2_report_delta_xml (FILE *out, iterator_t *results, if (strchr (delta_states, state[0]) == NULL) continue; - #if COMPLIANCE_REPORTS == 1 - if (strcmp (usage_type, "audit") == 0) - { - const char* compliance; - compliance = result_iterator_compliance (results); - (*f_compliance_count)++; - if (strcasecmp (compliance, "yes") == 0) - { - (*f_compliance_yes)++; - } - else if (strcasecmp (compliance, "no") == 0) - { - (*f_compliance_no)++; - } - else if (strcasecmp (compliance, "incomplete") == 0) - { - (*f_compliance_incomplete)++; - } - else if (strcasecmp (compliance, "undefined") == 0) - { - (*f_compliance_undefined)++; - } - } else - #endif + if (strcmp (usage_type, "audit") == 0) + { + const char* compliance; + compliance = result_iterator_compliance (results); + (*f_compliance_count)++; + if (strcasecmp (compliance, "yes") == 0) + { + (*f_compliance_yes)++; + } + else if (strcasecmp (compliance, "no") == 0) + { + (*f_compliance_no)++; + } + else if (strcasecmp (compliance, "incomplete") == 0) + { + (*f_compliance_incomplete)++; + } + else if (strcasecmp (compliance, "undefined") == 0) + { + (*f_compliance_undefined)++; + } + } + else { const char *level; /* Increase the result count. */ @@ -29943,7 +29929,7 @@ print_v2_report_delta_xml (FILE *out, iterator_t *results, } g_string_free (buffer, TRUE); g_free (usage_type); - + if (fprintf (out, "") < 0) { g_tree_destroy (ports); @@ -30260,9 +30246,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (report) { /* Get total counts of full results. */ - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit")) - #endif + if (strcmp (tsk_usage_type, "audit")) { if (delta == 0) { @@ -30400,22 +30384,20 @@ print_report_xml_start (report_t report, report_t delta, task_t task, filters_extra_buffer = g_string_new (""); - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit") == 0) - { - compliance_levels = compliance_levels ? compliance_levels : g_strdup ("yniu"); - - if (strchr (compliance_levels, 'y')) - g_string_append (filters_extra_buffer, "Yes"); - if (strchr (compliance_levels, 'n')) - g_string_append (filters_extra_buffer, "No"); - if (strchr (compliance_levels, 'i')) - g_string_append (filters_extra_buffer, "Incomplete"); - if (strchr (compliance_levels, 'u')) - g_string_append (filters_extra_buffer, "Undefined"); - } - else - #endif + if (strcmp (tsk_usage_type, "audit") == 0) + { + compliance_levels = compliance_levels ? compliance_levels : g_strdup ("yniu"); + + if (strchr (compliance_levels, 'y')) + g_string_append (filters_extra_buffer, "Yes"); + if (strchr (compliance_levels, 'n')) + g_string_append (filters_extra_buffer, "No"); + if (strchr (compliance_levels, 'i')) + g_string_append (filters_extra_buffer, "Incomplete"); + if (strchr (compliance_levels, 'u')) + g_string_append (filters_extra_buffer, "Undefined"); + } + else { if (strchr (levels, 'h')) g_string_append (filters_extra_buffer, "High"); @@ -30692,41 +30674,40 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } /* Prepare result counts. */ - #if COMPLIANCE_REPORTS == 1 - int compliance_yes, compliance_no; - int compliance_incomplete, compliance_undefined; - int total_compliance_count = 0; + int compliance_yes, compliance_no; + int compliance_incomplete, compliance_undefined; + int total_compliance_count = 0; - if (strcmp (tsk_usage_type, "audit") == 0) - { - report_compliance_counts (report, get, &compliance_yes, &compliance_no, - &compliance_incomplete, &compliance_undefined); + if (strcmp (tsk_usage_type, "audit") == 0) + { + report_compliance_counts (report, get, &compliance_yes, &compliance_no, + &compliance_incomplete, &compliance_undefined); - total_compliance_count = compliance_yes - + compliance_no - + compliance_incomplete - + compliance_undefined; + total_compliance_count = compliance_yes + + compliance_no + + compliance_incomplete + + compliance_undefined; - f_compliance_yes = f_compliance_no = 0; - f_compliance_incomplete = f_compliance_undefined = 0; + f_compliance_yes = f_compliance_no = 0; + f_compliance_incomplete = f_compliance_undefined = 0; - if (count_filtered == 0) - { - report_compliance_f_counts (report, - get, - &f_compliance_yes, - &f_compliance_no, - &f_compliance_incomplete, - &f_compliance_undefined); + if (count_filtered == 0) + { + report_compliance_f_counts (report, + get, + &f_compliance_yes, + &f_compliance_no, + &f_compliance_incomplete, + &f_compliance_undefined); - f_compliance_count = f_compliance_yes - + f_compliance_no - + f_compliance_incomplete - + f_compliance_undefined; - } - } else - #endif - { + f_compliance_count = f_compliance_yes + + f_compliance_no + + f_compliance_incomplete + + f_compliance_undefined; + } + } + else + { if (count_filtered) { /* We're getting all the filtered results, so we can count them as we @@ -30740,12 +30721,12 @@ print_report_xml_start (report_t report, report_t delta, task_t task, f_false_positives = f_severity = 0; } else - report_counts_id_full (report, &holes, &infos, &logs, - &warnings, &false_positives, &severity, - get, NULL, - &f_holes, &f_infos, &f_logs, &f_warnings, - &f_false_positives, &f_severity); - } + report_counts_id_full (report, &holes, &infos, &logs, + &warnings, &false_positives, &severity, + get, NULL, + &f_holes, &f_infos, &f_logs, &f_warnings, + &f_false_positives, &f_severity); + } /* Results. */ @@ -30810,31 +30791,30 @@ print_report_xml_start (report_t report, report_t delta, task_t task, /* Quiet erroneous compiler warning. */ result_hosts = NULL; - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit") == 0) - { - f_host_compliant = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - f_host_notcompliant = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - f_host_incomplete = g_hash_table_new_full (g_str_hash, g_str_equal, + if (strcmp (tsk_usage_type, "audit") == 0) + { + f_host_compliant = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + f_host_notcompliant = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - f_host_undefined = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - } else - #endif - { - f_host_holes = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - f_host_warnings = g_hash_table_new_full (g_str_hash, g_str_equal, + f_host_incomplete = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + f_host_undefined = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + } + else + { + f_host_holes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - f_host_infos = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - f_host_logs = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - f_host_false_positives = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - } + f_host_warnings = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + f_host_infos = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + f_host_logs = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + f_host_false_positives = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + } if (delta && get->details) { @@ -30918,109 +30898,107 @@ print_report_xml_start (report_t report, report_t delta, task_t task, array_add_new_string (result_hosts, result_iterator_host (&results)); - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit") == 0) - { - const char* compliance; - compliance = result_iterator_compliance (&results); - - if (strcasecmp (compliance, "yes") == 0) - { - f_host_result_counts = f_host_compliant; - if (count_filtered) - f_compliance_yes++; - } - else if (strcasecmp (compliance, "no") == 0) - { - f_host_result_counts = f_host_notcompliant; - if (count_filtered) - f_compliance_no++; - } - else if (strcasecmp (compliance, "incomplete") == 0) - { - f_host_result_counts = f_host_incomplete; - if (count_filtered) - f_compliance_incomplete++; - } - else if (strcasecmp (compliance, "undefined") == 0) - { - f_host_result_counts = f_host_undefined; - if (count_filtered) - f_compliance_undefined++; - } - else - { - f_host_result_counts = NULL; - } + if (strcmp (tsk_usage_type, "audit") == 0) + { + const char* compliance; + compliance = result_iterator_compliance (&results); - if (f_host_result_counts) - { - const char *result_host = result_iterator_host (&results); - int result_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_result_counts, - result_host)); - - g_hash_table_replace (f_host_result_counts, - g_strdup (result_host), - GINT_TO_POINTER (result_count + 1)); + if (strcasecmp (compliance, "yes") == 0) + { + f_host_result_counts = f_host_compliant; + if (count_filtered) + f_compliance_yes++; + } + else if (strcasecmp (compliance, "no") == 0) + { + f_host_result_counts = f_host_notcompliant; + if (count_filtered) + f_compliance_no++; + } + else if (strcasecmp (compliance, "incomplete") == 0) + { + f_host_result_counts = f_host_incomplete; + if (count_filtered) + f_compliance_incomplete++; + } + else if (strcasecmp (compliance, "undefined") == 0) + { + f_host_result_counts = f_host_undefined; + if (count_filtered) + f_compliance_undefined++; + } + else + { + f_host_result_counts = NULL; } - } else - #endif - { - double result_severity; - result_severity = result_iterator_severity_double (&results); - if (result_severity > f_severity) - f_severity = result_severity; - - level = result_iterator_level (&results); - if (strcasecmp (level, "log") == 0) - { - f_host_result_counts = f_host_logs; - if (count_filtered) - f_logs++; - } - else if (strcasecmp (level, "high") == 0) - { - f_host_result_counts = f_host_holes; - if (count_filtered) - f_holes++; - } - else if (strcasecmp (level, "medium") == 0) - { - f_host_result_counts = f_host_warnings; - if (count_filtered) - f_warnings++; - } - else if (strcasecmp (level, "low") == 0) - { - f_host_result_counts = f_host_infos; - if (count_filtered) - f_infos++; - } - else if (strcasecmp (level, "false positive") == 0) - { - f_host_result_counts = f_host_false_positives; - if (count_filtered) - f_false_positives++; + if (f_host_result_counts) + { + const char *result_host = result_iterator_host (&results); + int result_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_result_counts, + result_host)); + + g_hash_table_replace (f_host_result_counts, + g_strdup (result_host), + GINT_TO_POINTER (result_count + 1)); } - else - f_host_result_counts = NULL; + } + else + { + double result_severity; + result_severity = result_iterator_severity_double (&results); + if (result_severity > f_severity) + f_severity = result_severity; - if (f_host_result_counts) - { - const char *result_host = result_iterator_host (&results); - int result_count - = GPOINTER_TO_INT - (g_hash_table_lookup (f_host_result_counts, result_host)); - - g_hash_table_replace (f_host_result_counts, - g_strdup (result_host), - GINT_TO_POINTER (result_count + 1)); - } - } + level = result_iterator_level (&results); + if (strcasecmp (level, "log") == 0) + { + f_host_result_counts = f_host_logs; + if (count_filtered) + f_logs++; + } + else if (strcasecmp (level, "high") == 0) + { + f_host_result_counts = f_host_holes; + if (count_filtered) + f_holes++; + } + else if (strcasecmp (level, "medium") == 0) + { + f_host_result_counts = f_host_warnings; + if (count_filtered) + f_warnings++; + } + else if (strcasecmp (level, "low") == 0) + { + f_host_result_counts = f_host_infos; + if (count_filtered) + f_infos++; + } + else if (strcasecmp (level, "false positive") == 0) + { + f_host_result_counts = f_host_false_positives; + if (count_filtered) + f_false_positives++; + } + else + f_host_result_counts = NULL; + + if (f_host_result_counts) + { + const char *result_host = result_iterator_host (&results); + int result_count + = GPOINTER_TO_INT + (g_hash_table_lookup (f_host_result_counts, result_host)); + + g_hash_table_replace (f_host_result_counts, + g_strdup (result_host), + GINT_TO_POINTER (result_count + 1)); + } + } } PRINT (out, ""); } @@ -31031,131 +31009,130 @@ print_report_xml_start (report_t report, report_t delta, task_t task, /* Print result counts and severity. */ - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit") == 0) - { - if (delta) + if (strcmp (tsk_usage_type, "audit") == 0) + { + if (delta) + PRINT (out, + "" + "%i" + "%i" + "%i" + "%i" + "%i" + "", + f_compliance_count, + (strchr (compliance_levels, 'y') ? f_compliance_yes : 0), + (strchr (compliance_levels, 'n') ? f_compliance_no : 0), + (strchr (compliance_levels, 'i') ? f_compliance_incomplete : 0), + (strchr (compliance_levels, 'u') ? f_compliance_undefined : 0)); + else + { + if (count_filtered) + f_compliance_count = f_compliance_yes + + f_compliance_no + + f_compliance_incomplete + + f_compliance_undefined; PRINT (out, - "" - "%i" - "%i" - "%i" - "%i" - "%i" - "", - f_compliance_count, - (strchr (compliance_levels, 'y') ? f_compliance_yes : 0), - (strchr (compliance_levels, 'n') ? f_compliance_no : 0), - (strchr (compliance_levels, 'i') ? f_compliance_incomplete : 0), - (strchr (compliance_levels, 'u') ? f_compliance_undefined : 0)); - else - { - if (count_filtered) - f_compliance_count = f_compliance_yes - + f_compliance_no - + f_compliance_incomplete - + f_compliance_undefined; - PRINT (out, - "" - "%i" - "%i" - "%i" - "%i%i" - "%i%i" - "%i%i" - "%i%i" - "", - total_compliance_count, - total_compliance_count, - f_compliance_count, - compliance_yes, - (strchr (compliance_levels, 'y') ? f_compliance_yes : 0), - compliance_no, - (strchr (compliance_levels, 'n') ? f_compliance_no : 0), - compliance_incomplete, - (strchr (compliance_levels, 'i') ? f_compliance_incomplete : 0), - compliance_undefined, - (strchr (compliance_levels, 'i') ? f_compliance_undefined : 0)); - - PRINT (out, - "" - "%s" - "%s" - "", - report_compliance_from_counts (&compliance_yes, - &compliance_no, - &compliance_incomplete, - &compliance_undefined), - report_compliance_from_counts (&f_compliance_yes, - &f_compliance_no, - &f_compliance_incomplete, - &f_compliance_undefined)); - } - } else - #endif - { - if (delta) - /** @todo The f_holes, etc. vars are setup to give the page count. */ - PRINT (out, - "" - "%i" - "%i" - "%i" - "%i" - "%i" - "" - "%i" - "" - "", - orig_filtered_result_count, - (strchr (levels, 'h') ? orig_f_holes : 0), - (strchr (levels, 'l') ? orig_f_infos : 0), - (strchr (levels, 'g') ? orig_f_logs : 0), - (strchr (levels, 'm') ? orig_f_warnings : 0), - (strchr (levels, 'f') ? orig_f_false_positives : 0)); - else - { - if (count_filtered) - filtered_result_count = f_holes + f_infos + f_logs - + f_warnings + false_positives; + "" + "%i" + "%i" + "%i" + "%i%i" + "%i%i" + "%i%i" + "%i%i" + "", + total_compliance_count, + total_compliance_count, + f_compliance_count, + compliance_yes, + (strchr (compliance_levels, 'y') ? f_compliance_yes : 0), + compliance_no, + (strchr (compliance_levels, 'n') ? f_compliance_no : 0), + compliance_incomplete, + (strchr (compliance_levels, 'i') ? f_compliance_incomplete : 0), + compliance_undefined, + (strchr (compliance_levels, 'i') ? f_compliance_undefined : 0)); + PRINT (out, + "" + "%s" + "%s" + "", + report_compliance_from_counts (&compliance_yes, + &compliance_no, + &compliance_incomplete, + &compliance_undefined), + report_compliance_from_counts (&f_compliance_yes, + &f_compliance_no, + &f_compliance_incomplete, + &f_compliance_undefined)); + } + } + else + { + if (delta) + /** @todo The f_holes, etc. vars are setup to give the page count. */ PRINT (out, "" - "%i" - "%i" "%i" - "%i%i" - "%i%i" - "%i%i" - "%i%i" + "%i" + "%i" + "%i" + "%i" "" - "%i" "%i" "" "", - total_result_count, - total_result_count, - filtered_result_count, - holes, - (strchr (levels, 'h') ? f_holes : 0), - infos, - (strchr (levels, 'l') ? f_infos : 0), - logs, - (strchr (levels, 'g') ? f_logs : 0), - warnings, - (strchr (levels, 'm') ? f_warnings : 0), - false_positives, - (strchr (levels, 'f') ? f_false_positives : 0)); + orig_filtered_result_count, + (strchr (levels, 'h') ? orig_f_holes : 0), + (strchr (levels, 'l') ? orig_f_infos : 0), + (strchr (levels, 'g') ? orig_f_logs : 0), + (strchr (levels, 'm') ? orig_f_warnings : 0), + (strchr (levels, 'f') ? orig_f_false_positives : 0)); + else + { + if (count_filtered) + filtered_result_count = f_holes + f_infos + f_logs + + f_warnings + false_positives; - PRINT (out, - "" - "%1.1f" - "%1.1f" - "", - severity, - f_severity); - } - } + PRINT (out, + "" + "%i" + "%i" + "%i" + "%i%i" + "%i%i" + "%i%i" + "%i%i" + "" + "%i" + "%i" + "" + "", + total_result_count, + total_result_count, + filtered_result_count, + holes, + (strchr (levels, 'h') ? f_holes : 0), + infos, + (strchr (levels, 'l') ? f_infos : 0), + logs, + (strchr (levels, 'g') ? f_logs : 0), + warnings, + (strchr (levels, 'm') ? f_warnings : 0), + false_positives, + (strchr (levels, 'f') ? f_false_positives : 0)); + + PRINT (out, + "" + "%1.1f" + "%1.1f" + "", + severity, + f_severity); + } + } if (host_summary) { @@ -31236,22 +31213,21 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } cleanup_iterator (&hosts); } - #if COMPLIANCE_REPORTS == 1 - if (strcmp (tsk_usage_type, "audit") == 0) - { - g_hash_table_destroy (f_host_compliant); - g_hash_table_destroy (f_host_notcompliant); - g_hash_table_destroy (f_host_incomplete); - g_hash_table_destroy (f_host_undefined); - } else - #endif - { - g_hash_table_destroy (f_host_holes); - g_hash_table_destroy (f_host_warnings); - g_hash_table_destroy (f_host_infos); - g_hash_table_destroy (f_host_logs); - g_hash_table_destroy (f_host_false_positives); - } + if (strcmp (tsk_usage_type, "audit") == 0) + { + g_hash_table_destroy (f_host_compliant); + g_hash_table_destroy (f_host_notcompliant); + g_hash_table_destroy (f_host_incomplete); + g_hash_table_destroy (f_host_undefined); + } + else + { + g_hash_table_destroy (f_host_holes); + g_hash_table_destroy (f_host_warnings); + g_hash_table_destroy (f_host_infos); + g_hash_table_destroy (f_host_logs); + g_hash_table_destroy (f_host_false_positives); + } g_hash_table_destroy (f_host_ports); /* Print TLS certificates */ @@ -31349,36 +31325,36 @@ print_report_xml_start (report_t report, report_t delta, task_t task, return 0; failed_delta_report: - fclose (out); - g_free (sort_field); - g_free (levels); - g_free (search_phrase); - g_free (min_qod); - g_free (delta_states); - cleanup_iterator (&results); - cleanup_iterator (&delta_results); + fclose (out); + g_free (sort_field); + g_free (levels); + g_free (search_phrase); + g_free (min_qod); + g_free (delta_states); + cleanup_iterator (&results); + cleanup_iterator (&delta_results); failed_print_report_host: if (host_summary_buffer) g_string_free (host_summary_buffer, TRUE); tz_revert (zone, tz, old_tz_override); g_hash_table_destroy (f_host_ports); - #if COMPLIANCE_REPORTS == 1 - g_free (compliance_levels); - if (strcmp (tsk_usage_type, "audit") == 0) + + g_free (compliance_levels); + if (strcmp (tsk_usage_type, "audit") == 0) { g_hash_table_destroy (f_host_compliant); g_hash_table_destroy (f_host_notcompliant); g_hash_table_destroy (f_host_incomplete); g_hash_table_destroy (f_host_undefined); - } else - #endif - { - g_hash_table_destroy (f_host_holes); - g_hash_table_destroy (f_host_warnings); - g_hash_table_destroy (f_host_infos); - g_hash_table_destroy (f_host_logs); - g_hash_table_destroy (f_host_false_positives); - } + } + else + { + g_hash_table_destroy (f_host_holes); + g_hash_table_destroy (f_host_warnings); + g_hash_table_destroy (f_host_infos); + g_hash_table_destroy (f_host_logs); + g_hash_table_destroy (f_host_false_positives); + } return -1; } @@ -53686,10 +53662,8 @@ modify_setting (const gchar *uuid, const gchar *name, setting_name = g_strdup ("Alerts Filter"); else if (strcmp (uuid, "0f040d06-abf9-43a2-8f94-9de178b0e978") == 0) setting_name = g_strdup ("Assets Filter"); - #if COMPLIANCE_REPORTS == 1 - else if (strcmp (uuid, "45414da7-55f0-44c1-abbb-6b7d1126fbdf") == 0) - setting_name = g_strdup ("Audit Reports Filter"); - #endif + else if (strcmp (uuid, "45414da7-55f0-44c1-abbb-6b7d1126fbdf") == 0) + setting_name = g_strdup ("Audit Reports Filter"); else if (strcmp (uuid, "1a9fbd91-0182-44cd-bc88-a13a9b3b1bef") == 0) setting_name = g_strdup ("Configs Filter"); else if (strcmp (uuid, "186a5ac8-fe5a-4fb1-aa22-44031fb339f3") == 0) @@ -53813,10 +53787,8 @@ modify_setting (const gchar *uuid, const gchar *name, setting_name = g_strdup ("Reports Top Dashboard Configuration"); /* Audit Reports dashboard settings */ - #if COMPLIANCE_REPORTS == 1 - else if (strcmp (uuid, "8083d77b-05bb-4b17-ab39-c81175cb512c") == 0) - setting_name = g_strdup ("Audit Reports Top Dashboard Configuration"); - #endif + else if (strcmp (uuid, "8083d77b-05bb-4b17-ab39-c81175cb512c") == 0) + setting_name = g_strdup ("Audit Reports Top Dashboard Configuration"); /* Results dashboard settings */ else if (strcmp (uuid, "0b8ae70d-d8fc-4418-8a72-e65ac8d2828e") == 0) setting_name = g_strdup ("Results Top Dashboard Configuration"); @@ -57579,18 +57551,16 @@ tag_add_resources_filter (tag_t tag, const char *type, const char *filter) { get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); } - #if COMPLIANCE_REPORTS == 1 - else if (strcasecmp (type, "audit_report") == 0) - { - type = g_strdup ("report"); - resources_get.type = g_strdup (type); - get_data_set_extra (&resources_get, "usage_type", g_strdup ("audit")); - } - else if (strcasecmp (type, "report") == 0) - { - get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); - } - #endif + else if (strcasecmp (type, "audit_report") == 0) + { + type = g_strdup ("report"); + resources_get.type = g_strdup (type); + get_data_set_extra (&resources_get, "usage_type", g_strdup ("audit")); + } + else if (strcasecmp (type, "report") == 0) + { + get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); + } gchar *columns; @@ -57762,20 +57732,18 @@ tag_remove_resources_filter (tag_t tag, const char *type, const char *filter) { get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); } - #if COMPLIANCE_REPORTS == 1 - else if (strcasecmp (type, "audit_report") == 0) - { - type = g_strdup ("report"); - resources_get.type = g_strdup (type); - get_data_set_extra (&resources_get, - "usage_type", - g_strdup ("audit")); - } - else if (strcasecmp (type, "report") == 0) - { - get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); - } - #endif + else if (strcasecmp (type, "audit_report") == 0) + { + type = g_strdup ("report"); + resources_get.type = g_strdup (type); + get_data_set_extra (&resources_get, + "usage_type", + g_strdup ("audit")); + } + else if (strcasecmp (type, "report") == 0) + { + get_data_set_extra (&resources_get, "usage_type", g_strdup ("scan")); + } gchar *columns; From 4e12e124e8a5d81e4a378d6db788f9f225bb1c1c Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 4 Nov 2024 17:48:21 +0100 Subject: [PATCH 26/64] Dropped the dump that compliance reports are enabled. Removed the dump that compliance reports are enabled, because that is alway the case from now on. --- src/gvmd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gvmd.c b/src/gvmd.c index 722ea2022..99f8e1fa1 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -2325,7 +2325,6 @@ gvmd (int argc, char** argv, char *env[]) #if CVSS3_RATINGS == 1 printf ("CVSS3 severity ratings enabled\n"); #endif - printf ("Compliance reports enabled\n"); printf ("Copyright (C) 2009-2021 Greenbone AG\n"); printf ("License: AGPL-3.0-or-later\n"); printf From fcb7397ab49be6026d37a7349f30a2ba99312d5e Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Tue, 5 Nov 2024 10:37:54 +0100 Subject: [PATCH 27/64] Removed variables @IF_COMPLIANCE_REPORTS@, @ENDIF_COMPLIANCE_REPORTS@. --- src/schema_formats/XML/GMP.xml.in | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index eb2feaf73..5f2ca6573 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -68,7 +68,6 @@ along with this program. If not, see . xsd:token { pattern = "y?n?i?u?" } - @IF_COMPLIANCE_REPORTS@ compliance_status A compliance status @@ -76,7 +75,6 @@ along with this program. If not, see . xsd:token { pattern = "yes|no|incomplete|undefined" } - @ENDIF_COMPLIANCE_REPORTS@ ctime A date and time, in the C `ctime' format @@ -2025,16 +2023,12 @@ along with this program. If not, see . permissions user_tags scan_run_status - @IF_COMPLIANCE_REPORTS@ - @ENDIF_COMPLIANCE_REPORTS@ result_count severity - @IF_COMPLIANCE_REPORTS@ compliance_count compliance - @ENDIF_COMPLIANCE_REPORTS@ task ports results @@ -2468,7 +2462,6 @@ along with this program. If not, see . - @IF_COMPLIANCE_REPORTS@ compliance_count Counts of compliance results. Only for reports of an audit task. @@ -2577,7 +2570,6 @@ along with this program. If not, see . - @ENDIF_COMPLIANCE_REPORTS@ severity @@ -2595,7 +2587,6 @@ along with this program. If not, see . Maximum severity of the report after filtering - @IF_COMPLIANCE_REPORTS@ compliance @@ -2613,7 +2604,6 @@ along with this program. If not, see . Compliance of the report after filtering ("yes", "no", "incomplete" or "undefined") - @ENDIF_COMPLIANCE_REPORTS@ task @@ -2875,15 +2865,11 @@ along with this program. If not, see . start end port_count - @IF_COMPLIANCE_REPORTS@ - @ENDIF_COMPLIANCE_REPORTS@ result_count - @IF_COMPLIANCE_REPORTS@ compliance_count host_compliance - @ENDIF_COMPLIANCE_REPORTS@ detail @@ -3001,7 +2987,6 @@ along with this program. If not, see . - @IF_COMPLIANCE_REPORTS@ compliance_count Only for audit reports @@ -3071,7 +3056,6 @@ along with this program. If not, see . Only for audit reports. Host compliance compliance_status - @ENDIF_COMPLIANCE_REPORTS@ detail A detail associated with the host @@ -18029,13 +18013,11 @@ END:VCALENDAR integer Minimum QoD of the results - @IF_COMPLIANCE_REPORTS@ - @ENDIF_COMPLIANCE_REPORTS@ tag text @@ -18181,7 +18163,6 @@ END:VCALENDAR iso_time Scan end time - @IF_COMPLIANCE_REPORTS@ compliance_yes integer @@ -18202,7 +18183,6 @@ END:VCALENDAR compliance_status Compliance state of the report. Can be yes, no, incomplete or undefined - @ENDIF_COMPLIANCE_REPORTS@ @@ -18272,7 +18252,6 @@ END:VCALENDAR boolean - @IF_COMPLIANCE_REPORTS@ usage_type Optional usage type to limit the reports to. Affects total count unlike filter @@ -18284,7 +18263,6 @@ END:VCALENDAR - @ENDIF_COMPLIANCE_REPORTS@ @@ -23005,15 +22983,11 @@ END:VCALENDAR timestamp scan_end - @IF_COMPLIANCE_REPORTS@ - @ENDIF_COMPLIANCE_REPORTS@ result_count severity - @IF_COMPLIANCE_REPORTS@ compliance_count - @ENDIF_COMPLIANCE_REPORTS@ timestamp @@ -23059,7 +23033,6 @@ END:VCALENDAR severity Maximum severity of the report - @IF_COMPLIANCE_REPORTS@ compliance_count Complaince counts. Only for audit tasks @@ -23086,7 +23059,6 @@ END:VCALENDAR integer - @ENDIF_COMPLIANCE_REPORTS@ From fc1ed180fcb82b29b93129dacde6f7c10ce70ee7 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Tue, 5 Nov 2024 14:55:20 +0100 Subject: [PATCH 28/64] Small optimization of setting the log file. --- CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec0d19b3b..17f6af582 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,12 +165,10 @@ endif (NOT GVMD_STATE_DIR) if (NOT GVMD_LOG_FILE) if (GVM_LOG_DIR) - set (GVMD_LOG_FILE "${GVM_LOG_DIR}/gvmd.log") + set (GVMD_LOG_FILE "${GVM_LOG_DIR}/gvmd.log") else (GVM_LOG_DIR) - set (GVMD_LOG_FILE "-") - endif (GVMD_LOG_DIR) -else (NOT GVMD_LOG_FILE) - set (GVMD_LOG_FILE "${GVMD_LOG_FILE}") + set (GVMD_LOG_FILE "-") + endif (GVM_LOG_DIR) endif (NOT GVMD_LOG_FILE) set (GVM_SCAP_RES_DIR "${GVM_DATA_DIR}/scap") From c86349ac666ff3c038422dcff421b1f84bcd6cb8 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Thu, 7 Nov 2024 11:27:46 +0100 Subject: [PATCH 29/64] Remove: Remove delta reports non-default code and feature toggle --- src/manage_sql.c | 1623 +--------------------------------------- src/manage_sql.h | 5 - src/manage_sql_tests.c | 104 --- 3 files changed, 28 insertions(+), 1704 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index be266c79a..a70d9068f 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -340,9 +340,6 @@ setting_dynamic_severity_int (); static char * setting_timezone (); -static int -setting_delta_reports_version_int (); - static double task_severity_double (task_t, int, int, int); @@ -6537,82 +6534,6 @@ set_current_encryption_key_uid (const char *new_uid) g_free (quoted_new_uid); } - - -/* Collation. */ - -/** - * @brief Compare two number strings for collate_ip. - * - * @param[in] one_arg First string. - * @param[in] two_arg Second string. - * - * @return -1, 0 or 1 if first is less than, equal to or greater than second. - */ -static int -collate_ip_compare (const char *one_arg, const char *two_arg) -{ - int one = atoi (one_arg); - int two = atoi (two_arg); - return one == two ? 0 : (one < two ? -1 : 1); -} - -/** - * @brief Collate two IP addresses. - * - * For example, 127.0.0.2 is less than 127.0.0.3 and 127.0.0.10. - * - * Only works correctly for IPv4 addresses. - * - * @param[in] data Dummy for callback. - * @param[in] one_len Length of first IP (a string). - * @param[in] arg_one First string. - * @param[in] two_len Length of second IP (a string). - * @param[in] arg_two Second string. - * - * @return -1, 0 or 1 if first is less than, equal to or greater than second. - */ -static int -collate_ip (void* data, - int one_len, const void* arg_one, - int two_len, const void* arg_two) -{ - int ret, one_dot, two_dot; - char one_a[4], one_b[4], one_c[4], one_d[4]; - char two_a[4], two_b[4], two_c[4], two_d[4]; - const char* one = (const char*) arg_one; - const char* two = (const char*) arg_two; - - if ((sscanf (one, "%3[0-9].%3[0-9].%3[0-9].%n%3[0-9]", - one_a, one_b, one_c, &one_dot, one_d) - == 4) - && (sscanf (two, "%3[0-9].%3[0-9].%3[0-9].%n%3[0-9]", - two_a, two_b, two_c, &two_dot, two_d) - == 4)) - { - ret = collate_ip_compare (one_a, two_a); - if (ret) return ret < 0 ? -1 : 1; - - ret = collate_ip_compare (one_b, two_b); - if (ret) return ret < 0 ? -1 : 1; - - ret = collate_ip_compare (one_c, two_c); - if (ret) return ret < 0 ? -1 : 1; - - /* Ensure that the last number is limited to digits in the arg. */ - one_d[one_len - one_dot] = '\0'; - two_d[two_len - two_dot] = '\0'; - - ret = collate_ip_compare (one_d, two_d); - if (ret) return ret < 0 ? -1 : 1; - - return 0; - } - - ret = strncmp (one, two, MIN (one_len, two_len)); - return ret == 0 ? 0 : (ret < 0 ? -1 : 1); -} - /* Task subject iterators. */ @@ -16093,17 +16014,6 @@ check_db_settings () " 'Roles given access to new resources from feed.'," " '" ROLE_UUID_ADMIN "," ROLE_UUID_USER "');"); - if (sql_int ("SELECT count(*) FROM settings" - " WHERE uuid = '" SETTING_UUID_DELTA_REPORTS_VERSION "'" - " AND " ACL_IS_GLOBAL () ";") - == 0) - sql ("INSERT into settings (uuid, owner, name, comment, value)" - " VALUES" - " ('" SETTING_UUID_DELTA_REPORTS_VERSION "', NULL," - " 'Delta Reports Version'," - " 'Version of the generation of the Delta Reports.'," - " '2' );"); - if (sql_int ("SELECT count(*) FROM settings" " WHERE uuid = '" SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD "'" " AND " ACL_IS_GLOBAL () ";") @@ -23998,37 +23908,6 @@ DEF_ACCESS (result_iterator_port, GET_ITERATOR_COLUMN_COUNT + 1); */ DEF_ACCESS (result_iterator_nvt_oid, GET_ITERATOR_COLUMN_COUNT + 2); -/** - * @brief Get the original type from a result iterator. - * - * This is the column 'type'. - * - * @param[in] iterator Iterator. - * - * @return The original type of the result. Caller must only use before calling - * cleanup_iterator. - */ -static -DEF_ACCESS (result_iterator_original_type, GET_ITERATOR_COLUMN_COUNT + 3); - -/** - * @brief Get the type from a result iterator. - * - * This is the overridden type. - * - * @param[in] iterator Iterator. - * - * @return The type of the result. Caller must only use before calling - * cleanup_iterator. - */ -static const char* -result_iterator_type (iterator_t *iterator) -{ - if (iterator->done) return NULL; - /* new_type */ - return iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 4); -} - /** * @brief Get the descr from a result iterator. * @@ -26978,492 +26857,6 @@ void buffer_results_xml (GString *, iterator_t *, task_t, int, int, int, int, int, int, int, const char *, iterator_t *, int, int, int, int); -/** - * @brief Comparison returns. - */ -typedef enum -{ - COMPARE_RESULTS_CHANGED, - COMPARE_RESULTS_ERROR, - COMPARE_RESULTS_GONE, - COMPARE_RESULTS_NEW, - COMPARE_RESULTS_SAME -} compare_results_t; - -/** - * @brief Return the sort order of two results. - * - * @param[in] results Iterator containing first result. - * @param[in] delta_results Iterator containing second result. - * @param[in] sort_order Whether to sort ascending or descending. - * @param[in] sort_field Field to sort on, or NULL for "type". - * - * @return < 0 if first comes before second, 0 if equal, > 0 if first comes - * after second. - */ -static compare_results_t -result_cmp (iterator_t *results, iterator_t *delta_results, int sort_order, - const char* sort_field) -{ - const char *host, *delta_host, *port, *delta_port; - const char *nvt, *delta_nvt, *name, *delta_name, *descr, *delta_descr; - int ret; - double severity, delta_severity; - - if (sort_field == NULL) - sort_field = "type"; - - g_debug (" delta: %s: sort_order: %i", __func__, sort_order); - g_debug (" delta: %s: sort_field: %s", __func__, sort_field); - - host = result_iterator_host (results); - delta_host = result_iterator_host (delta_results); - - port = result_iterator_port (results); - delta_port = result_iterator_port (delta_results); - - severity = result_iterator_severity_double (results); - delta_severity = result_iterator_severity_double (delta_results); - - nvt = result_iterator_nvt_oid (results); - delta_nvt = result_iterator_nvt_oid (delta_results); - - name = result_iterator_nvt_name (results); - delta_name = result_iterator_nvt_name (delta_results); - - descr = result_iterator_descr (results); - delta_descr = result_iterator_descr (delta_results); - - /* For delta reports to work correctly, the order must be the same as in - * init_delta_iterators, except that description should not be checked - * unless it is the sort_field. - * - * If description is not the sort_field it is checked after the result_cmp - * in compare_results. */ - - /* Check sort_field first, also using sort_order (0 is descending). */ - if (strcmp (sort_field, "host") == 0) - { - ret = collate_ip (NULL, - strlen (host), host, strlen (delta_host), delta_host); - if (sort_order == 0) - ret = -ret; - g_debug (" delta: %s: host (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - host, delta_host, ret); - if (ret) - return ret; - } - else if (strcmp (sort_field, "port") == 0 - || strcmp (sort_field, "location") == 0) - { - ret = strcmp (port, delta_port); - if (sort_order == 0) - ret = -ret; - g_debug (" delta: %s: port (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - port, delta_port, ret); - if (ret) - return ret; - } - else if (strcmp (sort_field, "severity") == 0) - { - if (severity > delta_severity) - ret = sort_order ? 1 : -1; - else if (severity < delta_severity) - ret = sort_order ? -1 : 1; - else - ret = 0; - g_debug (" delta: %s: severity (%s): %f VS %f (%i)", - __func__, sort_order ? "desc" : "asc", - severity, delta_severity, ret); - if (ret) - return ret; - } - /* NVT OID, not name/vulnerability. */ - else if (strcmp (sort_field, "nvt") == 0) - { - ret = strcmp (nvt, delta_nvt); - if (sort_order) - ret = -ret; - g_debug (" delta: %s: nvt (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - nvt, delta_nvt, ret); - if (ret) - return ret; - } - else if (strcmp (sort_field, "description") == 0) - { - ret = strcmp (descr, delta_descr); - if (sort_order == 0) - ret = -ret; - g_debug (" delta: %s: description (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - descr, delta_descr, ret); - if (ret) - return ret; - } - else if (strcmp (sort_field, "type") == 0) - { - const char *type, *delta_type; - - type = result_iterator_type (results); - delta_type = result_iterator_type (delta_results); - - ret = strcmp (type, delta_type); - if (sort_order == 0) - ret = -ret; - g_debug (" delta: %s: type (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - descr, delta_descr, ret); - if (ret) - return ret; - } - else if (strcmp (sort_field, "original_type") == 0) - { - const char *type, *delta_type; - - type = result_iterator_original_type (results); - delta_type = result_iterator_original_type (delta_results); - - ret = strcmp (type, delta_type); - if (sort_order == 0) - ret = -ret; - g_debug (" delta: %s: original_type (%s): %s VS %s (%i)", - __func__, sort_order ? "desc" : "asc", - descr, delta_descr, ret); - if (ret) - return ret; - } - else - { - /* Default to "vulnerability" (a.k.a "name") for unknown sort fields. - * - * Also done in print_report_xml_start, so this is just a safety check. */ - ret = strcmp (name ? name : "", delta_name ? delta_name : ""); - if (sort_order == 0) - ret = -ret; - if (ret) - return ret; - } - - /* Check remaining fields */ - if (strcmp (sort_field, "host")) - { - ret = collate_ip (NULL, - strlen (host), host, strlen (delta_host), delta_host); - g_debug (" delta: %s: host: %s VS %s (%i)", - __func__, host, delta_host, ret); - if (ret) - return ret; - } - if (strcmp (sort_field, "port") - && strcmp (sort_field, "location")) - { - ret = strcmp (port, delta_port); - g_debug (" delta: %s: port: %s VS %s (%i)", - __func__, port, delta_port, ret); - if (ret) - return ret; - } - if (strcmp (sort_field, "severity")) - { - if (severity > delta_severity) - ret = 1; - else if (severity < delta_severity) - ret = -1; - else - ret = 0; - g_debug (" delta: %s: severity: %f VS %f (%i)", - __func__, severity, delta_severity, ret); - if (ret) - return ret; - } - if (strcmp (sort_field, "nvt")) - { - ret = strcmp (nvt, delta_nvt); - g_debug (" delta: %s: nvt: %s VS %s (%i)", - __func__, nvt, delta_nvt, ret); - if (ret) - return ret; - } - - return 0; -} - -/** - * @brief Test if two strings are equal, ignoring whitespace. - * - * @param[in] one First string. - * @param[in] two Second string. - * - * @return 1 if equal, else 0. - */ -static int -streq_ignore_ws (const gchar *one, const gchar *two) -{ - if (one == NULL) - return two == NULL; - if (two == NULL) - return 0; - - while (1) - { - /* Skip space in both. */ - while (isspace (*one)) - one++; - while (isspace (*two)) - two++; - - /* Check for end. */ - if (*one == '\0') - break; - if (*two == '\0') - return 0; - - /* Compare. */ - if (*one != *two) - return 0; - - /* Next. */ - one++; - two++; - } - if (*two) - return 0; - return 1; -} - -/** - * @brief Compare two results. - * - * @param[in] results Iterator containing first result. - * @param[in] delta_results Iterator containing second result. - * @param[in] sort_order Whether to sort ascending or descending. - * @param[in] sort_field Field to sort on, or NULL for "type". - * - * @return Result of comparison. - */ -static compare_results_t -compare_results (iterator_t *results, iterator_t *delta_results, int sort_order, - const char* sort_field) -{ - int ret; - const char *descr, *delta_descr; - - g_debug (" delta: %s", __func__); - - ret = result_cmp (results, delta_results, sort_order, sort_field); - if (ret > 0) - /* The delta result sorts first, so it is new. */ - return COMPARE_RESULTS_NEW; - if (ret < 0) - /* The 'results' result sorts first, so it has gone. */ - return COMPARE_RESULTS_GONE; - - descr = result_iterator_descr (results); - delta_descr = result_iterator_descr (delta_results); - - g_debug (" delta: %s: descr: %s VS %s (%i)", - __func__, - descr ? descr : "NULL", - delta_descr ? delta_descr : "NULL", - (descr && delta_descr) ? strcmp (descr, delta_descr) : 0); - - /* This comparison ignores whitespace to match the diff output created by - * strdiff in gmp.c. The down side of this is that the comparison may be - * affected by the locale. - * - * An alternate would be to use the strdiff result as the comparison, but - * strdiff is only called for the results on the page (and not for the - * rest of the results, which must also be compared for the counts). - * Using strdiff for all results could also be slow, because it's running - * the diff command. */ - if (descr && delta_descr && (streq_ignore_ws (descr, delta_descr) == 0)) - return COMPARE_RESULTS_CHANGED; - - return COMPARE_RESULTS_SAME; -} - -/** - * @brief Compare two results, optionally writing associated XML to a buffer. - * - * This is called with buffer NULL to compare results after the page limit - * (filter keyword "max") is reached. These results need to be compared to be - * included in the counts. - * - * @param[in] buffer Buffer. NULL to skip writing to buffer. - * @param[in] results Iterator containing first result. - * @param[in] delta_results Iterator containing second result. - * @param[in] task Task associated with report. - * @param[in] notes Whether to include notes. - * @param[in] notes_details If notes, Whether to include details. - * @param[in] overrides Whether to include overrides. - * @param[in] overrides_details If overrides, Whether to include details. - * @param[in] sort_order Whether to sort ascending or descending. - * @param[in] sort_field Field to sort on, or NULL for "type". - * @param[in] changed Whether to include changed results. - * @param[in] gone Whether to include gone results. - * @param[in] new Whether to include new results. - * @param[in] same Whether to include same results. - * @param[in] max_results Value to decrement if result is buffered. - * @param[in] first_result Skip result and decrement if positive. - * @param[in] used 0 if used, 1 if skipped. - * @param[in] would_use 0 if would use (first_result aside), 1 if skipped. - * - * @return Result of comparison. - */ -static compare_results_t -compare_and_buffer_results (GString *buffer, iterator_t *results, - iterator_t *delta_results, task_t task, int notes, - int notes_details, int overrides, - int overrides_details, int sort_order, - const char* sort_field, int changed, int gone, - int new, int same, int *max_results, - int *first_result, int *used, int *would_use) -{ - compare_results_t state; - state = compare_results (results, delta_results, sort_order, sort_field); - *used = 0; - *would_use = 0; - switch (state) - { - case COMPARE_RESULTS_CHANGED: - if (changed) - { - *would_use = 1; - if (*first_result) - { - g_debug (" delta: skip"); - (*first_result)--; - break; - } - *used = 1; - (*max_results)--; - if (buffer) - buffer_results_xml (buffer, - results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "changed", - delta_results, - /* This is the only case that uses 1. */ - 1, /* Whether result is "changed". */ - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - } - break; - - case COMPARE_RESULTS_GONE: - if (gone) - { - *would_use = 1; - if (*first_result) - { - g_debug (" delta: skip"); - (*first_result)--; - break; - } - *used = 1; - (*max_results)--; - if (buffer) - buffer_results_xml (buffer, - results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "gone", - delta_results, - 0, - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - } - break; - - case COMPARE_RESULTS_NEW: - if (new) - { - *would_use = 1; - if (*first_result) - { - g_debug (" delta: skip"); - (*first_result)--; - break; - } - *used = 1; - (*max_results)--; - if (buffer) - buffer_results_xml (buffer, - delta_results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "new", - delta_results, - 0, - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - } - break; - - case COMPARE_RESULTS_SAME: - if (same) - { - *would_use = 1; - if (*first_result) - { - g_debug (" delta: skip"); - (*first_result)--; - break; - } - *used = 1; - (*max_results)--; - if (buffer) - buffer_results_xml (buffer, - results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "same", - delta_results, - 0, - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - } - break; - - default: - return COMPARE_RESULTS_ERROR; - } - - return state; -} - /** * @brief Write XML to a file or close stream and return. * @@ -28868,114 +28261,6 @@ print_report_host_xml (FILE *stream, return 0; } -/** - * @brief Init delta iterators for print_report_xml. - * - * @param[in] report The report. - * @param[in] results Report result iterator. - * @param[in] delta Delta report. - * @param[in] delta_results Delta report result iterator. - * @param[in] get GET command data. - * @param[in] term Filter term. - * @param[out] sort_field Sort field. - * - * @return 0 on success, -1 error. - */ -static int -init_delta_iterators (report_t report, iterator_t *results, report_t delta, - iterator_t *delta_results, const get_data_t *get, - const char *term, const char *sort_field) -{ - int res; - gchar *order; - get_data_t delta_get; - - /* - * Order must be the same as in result_cmp, except for description - * which isn't checked there. - */ - if ((strcmp (sort_field, "name") == 0) - || (strcmp (sort_field, "vulnerability") == 0)) - order = g_strdup (", host, port, severity, nvt, description"); - else if (strcmp (sort_field, "host") == 0) - order = g_strdup (", port, severity, nvt, description"); - else if ((strcmp (sort_field, "port") == 0) - || (strcmp (sort_field, "location") == 0)) - order = g_strdup (", host, severity, nvt, description"); - else if (strcmp (sort_field, "severity") == 0) - order = g_strdup (", host, port, nvt, description"); - else if (strcmp (sort_field, "nvt") == 0) - order = g_strdup (", host, port, severity, description"); - else - order = g_strdup (", host, port, severity, nvt, description"); - - delta_get = *get; - delta_get.filt_id = NULL; - delta_get.filter = g_strdup_printf ("rows=-1 first=1 sort=%s %s", - sort_field, term); - ignore_max_rows_per_page = 1; - -#if 0 - /* For debugging. */ - - iterator_t results2; - - res = init_result_get_iterator (results, &delta_get, report, NULL, order); - if (res) - return -1; - - res = init_result_get_iterator (&results2, &delta_get, delta, NULL, order); - if (res) - return -1; - - g_debug (" delta: %s: REPORT 1:", __func__); - while (next (results)) - g_debug (" delta: %s: %s %s %s %s %.30s", - __func__, - result_iterator_nvt_name (results), - result_iterator_host (results), - result_iterator_type (results), - result_iterator_port (results), - result_iterator_descr (results)); - cleanup_iterator (results); - g_debug (" delta: %s: REPORT 1 END", __func__); - - g_debug (" delta: %s: REPORT 2:", __func__); - while (next (&results2)) - g_debug (" delta: %s: %s %s %s %s %.30s", - __func__, - result_iterator_nvt_name (&results2), - result_iterator_host (&results2), - result_iterator_type (&results2), - result_iterator_port (&results2), - result_iterator_descr (&results2)); - cleanup_iterator (&results2); - g_debug (" delta: %s: REPORT 2 END", __func__); -#endif - - res = init_result_get_iterator (results, &delta_get, report, NULL, order); - if (res) - { - ignore_max_rows_per_page = 0; - g_free (order); - return -1; - } - - res = init_result_get_iterator (delta_results, &delta_get, delta, NULL, order); - if (res) - { - ignore_max_rows_per_page = 0; - g_free (order); - return -1; - } - - g_free (delta_get.filter); - ignore_max_rows_per_page = 0; - g_free (order); - - return 0; -} - /** * @brief Init v2 delta iterator for print_report_xml. * @@ -29179,726 +28464,6 @@ init_v2_delta_iterator (report_t report, iterator_t *results, report_t delta, return ret; } -/** - * @brief Print delta results for print_report_xml. - * - * @param[in] out File stream to write to. - * @param[in] results Report result iterator. - * @param[in] delta_results Delta report result iterator. - * @param[in] delta_states String describing delta states to include in count - * (for example, "sngc" Same, New, Gone and Changed). - * All levels if NULL. - * @param[in] first_result First result. - * @param[in] max_results Max results. - * @param[in] task The task. - * @param[in] notes Whether to include notes. - * @param[in] notes_details Whether to include note details. - * @param[in] overrides Whether to include overrides. - * @param[in] overrides_details Whether to include override details. - * @param[in] sort_order Sort order. - * @param[in] sort_field Sort field. - * @param[in] result_hosts_only Whether to only include hosts with results. - * @param[in] orig_filtered_result_count Result count. - * @param[in] filtered_result_count Result count. - * @param[in] orig_f_holes Result count. - * @param[in] f_holes Result count. - * @param[in] orig_f_infos Result count. - * @param[in] f_infos Result count. - * @param[in] orig_f_logs Result count. - * @param[in] f_logs Result count. - * @param[in] orig_f_warnings Result count. - * @param[in] f_warnings Result count. - * @param[in] orig_f_false_positives Result count. - * @param[in] f_false_positives Result count. - * @param[in] result_hosts Result hosts. - * - * @return 0 on success, -1 error. - */ -static int -print_report_delta_xml (FILE *out, iterator_t *results, - iterator_t *delta_results, const char *delta_states, - int first_result, int max_results, task_t task, - int notes, int notes_details, int overrides, - int overrides_details, int sort_order, - const char *sort_field, int result_hosts_only, - int *orig_filtered_result_count, - int *filtered_result_count, - int *orig_f_holes, int *f_holes, - int *orig_f_infos, int *f_infos, - int *orig_f_logs, int *f_logs, - int *orig_f_warnings, int *f_warnings, - int *orig_f_false_positives, int *f_false_positives, - array_t *result_hosts) -{ - gboolean done, delta_done; - int changed, gone, new, same; - /* A tree of host, tree pairs, where the inner tree is a sorted tree - * of port, threat pairs. */ - GTree *ports; - gchar *msg; - - *orig_f_holes = *f_holes; - *orig_f_infos = *f_infos; - *orig_f_logs = *f_logs; - *orig_f_warnings = *f_warnings; - *orig_f_false_positives = *f_false_positives; - *orig_filtered_result_count = *filtered_result_count; - - changed = (strchr (delta_states, 'c') != NULL); - gone = (strchr (delta_states, 'g') != NULL); - new = (strchr (delta_states, 'n') != NULL); - same = (strchr (delta_states, 's') != NULL); - - ports = g_tree_new_full ((GCompareDataFunc) strcmp, NULL, g_free, - (GDestroyNotify) free_host_ports); - - /* Compare the results in the two iterators, which are sorted. */ - - g_debug (" delta: %s: start", __func__); - g_debug (" delta: %s: sort_field: %s", __func__, sort_field); - g_debug (" delta: %s: sort_order: %i", __func__, sort_order); - g_debug (" delta: %s: max_results: %i", __func__, max_results); - done = !next (results); - delta_done = !next (delta_results); - while (1) - { - GString *buffer; - compare_results_t state; - int used, would_use; - - if (max_results == 0) - break; - - if (done) - { - if (delta_done) - break; - if (new) - /* Extra results in 'delta_results'. */ - do - { - const char *level; - - g_debug (" delta: %s: extra from report 2: %s", - __func__, - result_iterator_nvt_oid (results)); - - if (first_result) - { - g_debug (" delta: skip"); - first_result--; - continue; - } - - /* Increase the result count. */ - level = result_iterator_level (delta_results); - (*orig_filtered_result_count)++; - (*filtered_result_count)++; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)++; - (*f_holes)++; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)++; - (*f_warnings)++; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)++; - (*f_infos)++; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)++; - (*f_logs)++; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)++; - (*f_false_positives)++; - } - - g_debug (" delta: %s: extra from report 2: %s", - __func__, - result_iterator_nvt_oid (delta_results)); - buffer = g_string_new (""); - buffer_results_xml (buffer, - delta_results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "new", - NULL, - 0, - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - if (fprintf (out, "%s", buffer->str) < 0) - return -1; - g_string_free (buffer, TRUE); - if (result_hosts_only) - array_add_new_string (result_hosts, - result_iterator_host (delta_results)); - add_port (ports, delta_results); - max_results--; - if (max_results == 0) - break; - } - while (next (delta_results)); - delta_done = TRUE; - break; - } - - if (delta_done) - { - /* Extra results in 'results'. */ - if (gone) - do - { - g_debug (" delta: %s: extra from report 1: %s", - __func__, - result_iterator_nvt_oid (results)); - if (first_result) - { - g_debug (" delta: skip"); - first_result--; - continue; - } - buffer = g_string_new (""); - buffer_results_xml (buffer, - results, - task, - notes, - notes_details, - overrides, - overrides_details, - 0, - 0, - 0, - "gone", - NULL, - 0, - -1, - 0, /* Lean. */ - 0); /* Delta fields. */ - if (fprintf (out, "%s", buffer->str) < 0) - return -1; - g_string_free (buffer, TRUE); - if (result_hosts_only) - array_add_new_string (result_hosts, - result_iterator_host (results)); - add_port (ports, results); - max_results--; - if (max_results == 0) - break; - } - while (next (results)); - else - do - { - const char *level; - - /* Decrease the result count. */ - level = result_iterator_level (results); - (*orig_filtered_result_count)--; - (*filtered_result_count)--; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)--; - (*f_holes)--; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)--; - (*f_warnings)--; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)--; - (*f_infos)--; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)--; - (*f_logs)--; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)--; - (*f_false_positives)--; - } - } - while (next (results)); - done = TRUE; - break; - } - - /* Compare the two results. */ - - buffer = g_string_new (""); - state = compare_and_buffer_results (buffer, - results, - delta_results, - task, - notes, - notes_details, - overrides, - overrides_details, - sort_order, - sort_field, - changed, - gone, - new, - same, - &max_results, - &first_result, - &used, - &would_use); - if (state == COMPARE_RESULTS_ERROR) - { - g_warning ("%s: compare_and_buffer_results failed", - __func__); - return -1; - } - if (fprintf (out, "%s", buffer->str) < 0) - return -1; - g_string_free (buffer, TRUE); - - if ((used == 0) - && ((state == COMPARE_RESULTS_GONE) - || (state == COMPARE_RESULTS_SAME) - || (state == COMPARE_RESULTS_CHANGED))) - { - const char *level; - - /* Decrease the result count. */ - level = result_iterator_level (results); - (*filtered_result_count)--; - if (strcmp (level, "High") == 0) - { - (*f_holes)--; - } - else if (strcmp (level, "Medium") == 0) - { - (*f_warnings)--; - } - else if (strcmp (level, "Low") == 0) - { - (*f_infos)--; - } - else if (strcmp (level, "Log") == 0) - { - (*f_logs)--; - } - else if (strcmp (level, "False Positive") == 0) - { - (*f_false_positives)--; - } - } - - if ((would_use == 0) - && ((state == COMPARE_RESULTS_GONE) - || (state == COMPARE_RESULTS_SAME) - || (state == COMPARE_RESULTS_CHANGED))) - { - const char *level; - - /* Decrease the result count. */ - level = result_iterator_level (results); - (*orig_filtered_result_count)--; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)--; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)--; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)--; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)--; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)--; - } - } - - /* Move on to the next. */ - - if (state == COMPARE_RESULTS_GONE) - { - /* "Used" just the 'results' result. */ - if (used) - { - if (result_hosts_only) - array_add_new_string (result_hosts, - result_iterator_host (results)); - add_port (ports, results); - } - done = !next (results); - } - else if ((state == COMPARE_RESULTS_SAME) - || (state == COMPARE_RESULTS_CHANGED)) - { - /* "Used" both results. */ - if (used) - { - if (result_hosts_only) - array_add_new_string (result_hosts, - result_iterator_host (results)); - add_port (ports, results); - } - done = !next (results); - delta_done = !next (delta_results); - } - else if (state == COMPARE_RESULTS_NEW) - { - if (would_use) - { - const char *level; - - /* Would have "used" just the 'delta_results' result, on - * an earlier page. */ - - /* Increase the result count. */ - level = result_iterator_level (delta_results); - (*orig_filtered_result_count)++; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)++; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)++; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)++; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)++; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)++; - } - } - - if (used) - { - const char *level; - - /* "Used" just the 'delta_results' result. */ - - /* Increase the result count. */ - level = result_iterator_level (delta_results); - (*filtered_result_count)++; - if (strcmp (level, "High") == 0) - { - (*f_holes)++; - } - else if (strcmp (level, "Medium") == 0) - { - (*f_warnings)++; - } - else if (strcmp (level, "Low") == 0) - { - (*f_infos)++; - } - else if (strcmp (level, "Log") == 0) - { - (*f_logs)++; - } - else if (strcmp (level, "False Positive") == 0) - { - (*f_false_positives)++; - } - - if (result_hosts_only) - array_add_new_string (result_hosts, - result_iterator_host - (delta_results)); - - add_port (ports, delta_results); - } - delta_done = !next (delta_results); - } - else - assert (0); - } - - /* Compare remaining results, for the filtered report counts. */ - - g_debug (" delta: %s: counting rest", __func__); - while (1) - { - compare_results_t state; - int used, would_use; - - if (done) - { - if (delta_done) - break; - if (new) - /* Extra results in 'delta_results'. */ - do - { - const char *level; - - g_debug (" delta: %s: extra from report 2: %s", - __func__, - result_iterator_nvt_oid (delta_results)); - - /* Increase the result count. */ - level = result_iterator_level (delta_results); - (*orig_filtered_result_count)++; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)++; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)++; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)++; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)++; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)++; - } - } - while (next (delta_results)); - break; - } - - if (delta_done) - { - /* Extra results in 'results'. */ - if (gone) - do - { - g_debug (" delta: %s: extra from report 1: %s", - __func__, - result_iterator_nvt_oid (results)); - - /* It's in the count already. */ - } - while (next (results)); - else - do - { - const char *level; - - /* Decrease the result count. */ - level = result_iterator_level (results); - (*orig_filtered_result_count)--; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)--; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)--; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)--; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)--; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)--; - } - } - while (next (results)); - break; - } - - /* Compare the two results. */ - - state = compare_and_buffer_results (NULL, - results, - delta_results, - task, - notes, - notes_details, - overrides, - overrides_details, - sort_order, - sort_field, - changed, - gone, - new, - same, - &max_results, - &first_result, - &used, - &would_use); - if (state == COMPARE_RESULTS_ERROR) - { - g_warning ("%s: compare_and_buffer_results failed", - __func__); - return -1; - } - - if (state == COMPARE_RESULTS_NEW) - { - if (used) - { - const char *level; - - /* "Used" just the 'delta_results' result. */ - - /* Increase the result count. */ - level = result_iterator_level (delta_results); - (*orig_filtered_result_count)++; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)++; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)++; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)++; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)++; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)++; - } - } - } - else if (used) - { - /* It's in the count already. */ - } - else - { - const char *level; - - /* Decrease the result count. */ - level = result_iterator_level (results); - (*orig_filtered_result_count)--; - if (strcmp (level, "High") == 0) - { - (*orig_f_holes)--; - } - else if (strcmp (level, "Medium") == 0) - { - (*orig_f_warnings)--; - } - else if (strcmp (level, "Low") == 0) - { - (*orig_f_infos)--; - } - else if (strcmp (level, "Log") == 0) - { - (*orig_f_logs)--; - } - else if (strcmp (level, "False Positive") == 0) - { - (*orig_f_false_positives)--; - } - } - - /* Move on to the next. */ - - if (state == COMPARE_RESULTS_GONE) - { - /* "Used" just the 'results' result. */ - done = !next (results); - } - else if ((state == COMPARE_RESULTS_SAME) - || (state == COMPARE_RESULTS_CHANGED)) - { - /* "Used" both results. */ - done = !next (results); - delta_done = !next (delta_results); - } - else if (state == COMPARE_RESULTS_NEW) - { - /* "Used" just the 'delta_results' result. */ - delta_done = !next (delta_results); - } - else - assert (0); - } - msg = g_markup_printf_escaped (""); - if (fprintf (out, "%s", msg) < 0) - { - g_free (msg); - fclose (out); - return -1; - } - g_free (msg); - - /* Write ports to file. */ - - msg = g_markup_printf_escaped ("", - /* Add 1 for 1 indexing. */ - first_result + 1, - max_results); - if (fprintf (out, "%s", msg) < 0) - { - g_free (msg); - fclose (out); - return -1; - } - g_free (msg); - if (sort_field == NULL || strcmp (sort_field, "port")) - { - if (sort_order) - g_tree_foreach (ports, print_host_ports_by_severity_asc, out); - else - g_tree_foreach (ports, print_host_ports_by_severity_desc, out); - } - else if (sort_order) - g_tree_foreach (ports, print_host_ports, out); - else - g_tree_foreach (ports, print_host_ports_desc, out); - g_tree_destroy (ports); - msg = g_markup_printf_escaped (""); - if (fprintf (out, "%s", msg) < 0) - { - g_free (msg); - fclose (out); - return -1; - } - g_free (msg); - - return 0; -} - /** * @brief Print v2 delta results for print_report_xml. * @@ -29953,7 +28518,7 @@ print_v2_report_delta_xml (FILE *out, iterator_t *results, int *orig_f_warnings, int *f_warnings, int *orig_f_false_positives, int *f_false_positives, int *f_compliance_yes, int *f_compliance_no, - int *f_compliance_incomplete, + int *f_compliance_incomplete, int *f_compliance_undefined, int *f_compliance_count, array_t *result_hosts) { @@ -30171,8 +28736,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, int f_compliance_incomplete, f_compliance_undefined; int f_compliance_count; - int delta_reports_version = 0; - /* Init some vars to prevent warnings from older compilers. */ max_results = -1; levels = NULL; @@ -30264,11 +28827,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, &apply_overrides, &zone); } - if (delta) { - delta_reports_version = setting_delta_reports_version_int (); - g_debug ("%s: delta reports version %d", __func__, delta_reports_version); - } - max_results = manage_max_rows (max_results); levels = levels ? levels : g_strdup ("hmlgdf"); @@ -30378,8 +28936,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, ""); } - count_filtered = (delta == 0 && ignore_pagination && get->details) - || (delta_reports_version == 2); + count_filtered = (delta || (ignore_pagination && get->details)); if (report) { @@ -30461,56 +29018,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, g_free (term); term = clean; - if (delta - && sort_field - && (delta_reports_version == 1) - /* These are all checked in result_cmp. */ - && strcmp (sort_field, "name") - && strcmp (sort_field, "vulnerability") - && strcmp (sort_field, "host") - && strcmp (sort_field, "port") - && strcmp (sort_field, "location") - && strcmp (sort_field, "severity") - && strcmp (sort_field, "nvt") - && strcmp (sort_field, "description") - && strcmp (sort_field, "type") - && strcmp (sort_field, "original_type")) - { - gchar *new_term; - - if ((strcmp (sort_field, "task") == 0) - || (strcmp (sort_field, "task_id") == 0) - || (strcmp (sort_field, "report_id") == 0)) - { - /* These don't affect delta report, so sort by vulnerability. */ - g_free (sort_field); - sort_field = g_strdup ("vulnerability"); - } - else - { - /* The remaining filterable fields for the result iterator, all of - * which may be used as a sort field. These could be added to - * result_cmp. For now sort by vulnerability. */ -#if 0 - "uuid", "comment", "created", "modified", "_owner", - "cvss_base", "nvt_version", "original_severity", "date", - "solution_type", "qod", "qod_type", "cve", "hostname", "path" -#endif - g_free (sort_field); - sort_field = g_strdup ("vulnerability"); - } - - /* Adjust "term" to match sort_field, because "term" will be used in the - * REPORT XML FILTERS (sent by buffer_get_filter_xml below). */ - new_term = g_strdup_printf ("sort=%s %s", - sort_field, - term); - g_free (term); - term = new_term; - /* Similarly, the order will now be ascending. */ - sort_order = 1; - } - if (filter_term_return) *filter_term_return = g_strdup (term); @@ -30873,27 +29380,12 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (delta && get->details) { - if (delta_reports_version == 1) + if (init_v2_delta_iterator (report, &results, delta, + get, term, sort_field)) { - if (init_delta_iterators (report, &results, delta, - &delta_results, get, - term, sort_field)) - { - g_free (term); - g_hash_table_destroy (f_host_ports); - return -1; - } g_free (term); - } - else - { - if (init_v2_delta_iterator (report, &results, delta, - get, term, sort_field)) - { - g_free (term); - g_hash_table_destroy (f_host_ports); - return -1; - } + g_hash_table_destroy (f_host_ports); + return -1; } } else if (get->details) @@ -30956,52 +29448,28 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (delta && get->details) { - if (delta_reports_version == 1) - { - if (print_report_delta_xml (out, &results, &delta_results, - delta_states, - ignore_pagination ? 0 : first_result, - ignore_pagination ? -1 : max_results, - task, notes, - notes_details, overrides, - overrides_details, sort_order, - sort_field, result_hosts_only, - &orig_filtered_result_count, - &filtered_result_count, - &orig_f_holes, &f_holes, - &orig_f_infos, &f_infos, - &orig_f_logs, &f_logs, - &orig_f_warnings, &f_warnings, - &orig_f_false_positives, - &f_false_positives, - result_hosts)) - goto failed_delta_report; - } - else - { - if (print_v2_report_delta_xml (out, &results, delta_states, - ignore_pagination ? 0 : first_result, - ignore_pagination ? -1 : max_results, - task, notes, - notes_details, overrides, - overrides_details, sort_order, - sort_field, result_hosts_only, - &orig_filtered_result_count, - &filtered_result_count, - &orig_f_holes, &f_holes, - &orig_f_infos, &f_infos, - &orig_f_logs, &f_logs, - &orig_f_warnings, &f_warnings, - &orig_f_false_positives, - &f_false_positives, - &f_compliance_yes, - &f_compliance_no, - &f_compliance_incomplete, - &f_compliance_undefined, - &f_compliance_count, - result_hosts)) - goto failed_delta_report; - } + if (print_v2_report_delta_xml (out, &results, delta_states, + ignore_pagination ? 0 : first_result, + ignore_pagination ? -1 : max_results, + task, notes, + notes_details, overrides, + overrides_details, sort_order, + sort_field, result_hosts_only, + &orig_filtered_result_count, + &filtered_result_count, + &orig_f_holes, &f_holes, + &orig_f_infos, &f_infos, + &orig_f_logs, &f_logs, + &orig_f_warnings, &f_warnings, + &orig_f_false_positives, + &f_false_positives, + &f_compliance_yes, + &f_compliance_no, + &f_compliance_incomplete, + &f_compliance_undefined, + &f_compliance_count, + result_hosts)) + goto failed_delta_report; } else if (get->details) { @@ -31142,8 +29610,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } if (get->details) cleanup_iterator (&results); - if (delta && get->details && delta_reports_version == 1) - cleanup_iterator (&delta_results); /* Print result counts and severity. */ @@ -31293,12 +29759,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, iterator_t hosts; init_report_host_iterator (&hosts, report, result_host, 0); present = next (&hosts); - if (delta && (present == FALSE) && delta_reports_version == 1) - { - cleanup_iterator (&hosts); - init_report_host_iterator (&hosts, delta, result_host, 0); - present = next (&hosts); - } if (present) { if (print_report_host_xml (out, @@ -53190,21 +51650,6 @@ setting_auto_cache_rebuild_int () current_credentials.uuid); } -/** - * @brief Return user setting as int. - * - * @return User setting. - */ -static int -setting_delta_reports_version_int () -{ - int version; - - setting_value_int (SETTING_UUID_DELTA_REPORTS_VERSION, &version); - - return version; -} - /** * @brief Initialise a setting iterator, including observed settings. * @@ -54108,8 +52553,6 @@ setting_name (const gchar *uuid) return "Feed Import Owner"; if (strcmp (uuid, SETTING_UUID_FEED_IMPORT_ROLES) == 0) return "Feed Import Roles"; - if (strcmp (uuid, SETTING_UUID_DELTA_REPORTS_VERSION) == 0) - return "Delta Reports Version"; if (strcmp (uuid, SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD) == 0) return "SecInfo SQL Buffer Threshold"; @@ -54149,8 +52592,6 @@ setting_description (const gchar *uuid) return "User who is given ownership of new resources from feed."; if (strcmp (uuid, SETTING_UUID_FEED_IMPORT_ROLES) == 0) return "Roles given access to new resources from feed."; - if (strcmp (uuid, SETTING_UUID_DELTA_REPORTS_VERSION) == 0) - return "Version of the generation of the Delta Reports."; if (strcmp (uuid, SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD) == 0) return "Buffer size threshold in MiB for running buffered SQL statements" " in SecInfo updates before the end of the file being processed."; @@ -54241,12 +52682,6 @@ setting_verify (const gchar *uuid, const gchar *value, const gchar *user) g_strfreev (split); } - if (strcmp (uuid, SETTING_UUID_DELTA_REPORTS_VERSION) == 0) - { - if (strcmp(value, "1") != 0 && strcmp(value, "2") != 0) - return 1; - } - if (strcmp (uuid, SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD) == 0) { int threshold; @@ -54349,7 +52784,6 @@ manage_modify_setting (GSList *log_config, const db_conn_info_t *database, && strcmp (uuid, SETTING_UUID_LSC_DEB_MAINTAINER) && strcmp (uuid, SETTING_UUID_FEED_IMPORT_OWNER) && strcmp (uuid, SETTING_UUID_FEED_IMPORT_ROLES) - && strcmp (uuid, SETTING_UUID_DELTA_REPORTS_VERSION) && strcmp (uuid, SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD)) { fprintf (stderr, "Error in setting UUID.\n"); @@ -54377,7 +52811,6 @@ manage_modify_setting (GSList *log_config, const db_conn_info_t *database, if ((strcmp (uuid, SETTING_UUID_DEFAULT_CA_CERT) == 0) || (strcmp (uuid, SETTING_UUID_FEED_IMPORT_OWNER) == 0) || (strcmp (uuid, SETTING_UUID_FEED_IMPORT_ROLES) == 0) - || (strcmp (uuid, SETTING_UUID_DELTA_REPORTS_VERSION) == 0) || (strcmp (uuid, SETTING_UUID_SECINFO_SQL_BUFFER_THRESHOLD) == 0)) { sql_rollback (); diff --git a/src/manage_sql.h b/src/manage_sql.h index b9db9cb99..c98e15adc 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -137,11 +137,6 @@ */ #define SETTING_UUID_FEED_IMPORT_ROLES "ff000362-338f-11ea-9051-28d24461215b" -/** - * @brief UUID of 'Delta Reports Version' setting. - */ -#define SETTING_UUID_DELTA_REPORTS_VERSION "985a0c05-2140-4e66-9989-ce9a0906a5a9" - /** * @brief UUID of 'SecInfo SQL Buffer Threshold' setting. */ diff --git a/src/manage_sql_tests.c b/src/manage_sql_tests.c index d6b5e4e1a..a547b983c 100644 --- a/src/manage_sql_tests.c +++ b/src/manage_sql_tests.c @@ -61,104 +61,6 @@ Ensure (manage_sql, validate_results_port_validates) FAIL ("udp"); } -#define CMP(one, two, ret) assert_that (streq_ignore_ws (one, two), is_equal_to (ret)) - -#define EQ2(one, two) CMP(one, two, 1); CMP(two, one, 1) -#define EQ(string) CMP(string, string, 1) - -Ensure (manage_sql, streq_ignore_ws_finds_equal) -{ - EQ ("abc"); - EQ (" abc"); - EQ ("abc "); - EQ ("ab c"); - EQ (""); - EQ ("."); - EQ (" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-=_)(*&^%$#@!~\"':}{<>?"); - EQ ("three little words"); -} - -Ensure (manage_sql, streq_ignore_ws_finds_equal_despite_ws) -{ - EQ2 ("abc", " abc"); - EQ2 ("abc", "abc "); - EQ2 ("abc", "ab c"); - EQ2 ("abc", " a b c "); - - EQ2 ("abc", "\nabc"); - EQ2 ("abc", "abc\n"); - EQ2 ("abc", "ab\nc"); - EQ2 ("abc", "\na\nb\n\n\n\nc\n"); - - EQ2 ("abc", "\tabc"); - EQ2 ("abc", "abc\t"); - EQ2 ("abc", "ab\tc"); - EQ2 ("abc", "\ta\tb\t\t\t\tc\t"); - - EQ2 ("abcd", "\ta\nb \t\nc \t\t\n\nd\t\n "); - - EQ2 ("", " "); - EQ2 ("", "\t"); - EQ2 ("", "\n"); - EQ2 ("", " "); - EQ2 ("", "\t\t"); - EQ2 ("", "\n\n"); - EQ2 ("", " \n\t \n\n\t\t"); - - EQ2 (" \n\t \n\n\t\t", " \n\t \n\n\t\t"); -} - -#define DIFF(one, two) CMP(one, two, 0); CMP(two, one, 0) - -Ensure (manage_sql, streq_ignore_ws_finds_diff) -{ - DIFF ("abc", "abcd"); - DIFF ("abc", "dabc"); - DIFF ("abc", "abdc"); - DIFF ("abc", "xyz"); - DIFF ("abc", ""); - DIFF ("abc", "."); - DIFF ("abc", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-=_)(*&^%$#@!~\"':}{<>?"); -} - -Ensure (manage_sql, streq_ignore_ws_finds_diff_incl_ws) -{ - DIFF ("zabc", " abc"); - DIFF ("zabc", "abc "); - DIFF ("zabc", "ab c"); - DIFF ("zabc", " a b c "); - - DIFF ("zabc", "\nabc"); - DIFF ("zabc", "abc\n"); - DIFF ("zabc", "ab\nc"); - DIFF ("zabc", "\na\nb\n\n\n\nc\n"); - - DIFF ("zabc", "\tabc"); - DIFF ("zabc", "abc\t"); - DIFF ("zabc", "ab\tc"); - DIFF ("zabc", "\ta\tb\t\t\t\tc\t"); - - DIFF ("zabcd", "\ta\nb \t\nc \t\t\n\nd\t\n "); - - DIFF ("a", " "); - DIFF ("a", "\t"); - DIFF ("a", "\n"); - DIFF ("a", " "); - DIFF ("a", "\t\t"); - DIFF ("a", "\n\n"); - DIFF ("a", " \n\t \n\n\t\t"); - - DIFF ("a \n\t \n\n\t\t", " \n\t \n\n\t\t"); - DIFF (" \n\t \na\n\t\t", " \n\t \n\n\t\t"); - DIFF (" \n\t \n\n\t\ta", " \n\t \n\n\t\t"); -} - -Ensure (manage_sql, streq_ignore_ws_handles_null) -{ - EQ (NULL); - DIFF ("abc", NULL); -} - /* Test suite. */ int @@ -170,12 +72,6 @@ main (int argc, char **argv) add_test_with_context (suite, manage_sql, validate_results_port_validates); - add_test_with_context (suite, manage_sql, streq_ignore_ws_finds_equal); - add_test_with_context (suite, manage_sql, streq_ignore_ws_finds_equal_despite_ws); - add_test_with_context (suite, manage_sql, streq_ignore_ws_finds_diff); - add_test_with_context (suite, manage_sql, streq_ignore_ws_finds_diff_incl_ws); - add_test_with_context (suite, manage_sql, streq_ignore_ws_handles_null); - if (argc > 1) return run_single_test (suite, argv[1], create_text_reporter ()); From 93b3c8f7a68f66cf56cb2dfecea4c6a7d48e62ce Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Thu, 7 Nov 2024 11:40:07 +0100 Subject: [PATCH 30/64] Rename functions with v2 delta in their name to delta --- src/manage_sql.c | 56 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index a70d9068f..2a9482e74 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -28262,7 +28262,7 @@ print_report_host_xml (FILE *stream, } /** - * @brief Init v2 delta iterator for print_report_xml. + * @brief Init delta iterator for print_report_xml. * * @param[in] report The report. * @param[in] results Report result iterator. @@ -28274,9 +28274,9 @@ print_report_host_xml (FILE *stream, * @return 0 on success, -1 error. */ static int -init_v2_delta_iterator (report_t report, iterator_t *results, report_t delta, - const get_data_t *get, const char *term, - const char *sort_field) +init_delta_iterator (report_t report, iterator_t *results, report_t delta, + const get_data_t *get, const char *term, + const char *sort_field) { int ret; static const char *filter_columns[] = RESULT_ITERATOR_FILTER_COLUMNS; @@ -28465,7 +28465,7 @@ init_v2_delta_iterator (report_t report, iterator_t *results, report_t delta, } /** - * @brief Print v2 delta results for print_report_xml. + * @brief Print delta results for print_report_xml. * * @param[in] out File stream to write to. * @param[in] results Report result iterator. @@ -28504,7 +28504,7 @@ init_v2_delta_iterator (report_t report, iterator_t *results, report_t delta, * @return 0 on success, -1 error. */ static int -print_v2_report_delta_xml (FILE *out, iterator_t *results, +print_report_delta_xml (FILE *out, iterator_t *results, const char *delta_states, int first_result, int max_results, task_t task, int notes, int notes_details, int overrides, @@ -29380,7 +29380,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (delta && get->details) { - if (init_v2_delta_iterator (report, &results, delta, + if (init_delta_iterator (report, &results, delta, get, term, sort_field)) { g_free (term); @@ -29448,27 +29448,27 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (delta && get->details) { - if (print_v2_report_delta_xml (out, &results, delta_states, - ignore_pagination ? 0 : first_result, - ignore_pagination ? -1 : max_results, - task, notes, - notes_details, overrides, - overrides_details, sort_order, - sort_field, result_hosts_only, - &orig_filtered_result_count, - &filtered_result_count, - &orig_f_holes, &f_holes, - &orig_f_infos, &f_infos, - &orig_f_logs, &f_logs, - &orig_f_warnings, &f_warnings, - &orig_f_false_positives, - &f_false_positives, - &f_compliance_yes, - &f_compliance_no, - &f_compliance_incomplete, - &f_compliance_undefined, - &f_compliance_count, - result_hosts)) + if (print_report_delta_xml (out, &results, delta_states, + ignore_pagination ? 0 : first_result, + ignore_pagination ? -1 : max_results, + task, notes, + notes_details, overrides, + overrides_details, sort_order, + sort_field, result_hosts_only, + &orig_filtered_result_count, + &filtered_result_count, + &orig_f_holes, &f_holes, + &orig_f_infos, &f_infos, + &orig_f_logs, &f_logs, + &orig_f_warnings, &f_warnings, + &orig_f_false_positives, + &f_false_positives, + &f_compliance_yes, + &f_compliance_no, + &f_compliance_incomplete, + &f_compliance_undefined, + &f_compliance_count, + result_hosts)) goto failed_delta_report; } else if (get->details) From d22536008eb33e9f7b0a8a09209cfbf313c278f2 Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Thu, 7 Nov 2024 16:23:10 +0100 Subject: [PATCH 31/64] Add: The table scap.affected_products is filled for the new JSON feed. This commit contains the filling of the table scap.affected_products and a small bug-fix for the CVE scan. --- src/manage_sql.c | 2 +- src/manage_sql_secinfo.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index be266c79a..613775b10 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20511,7 +20511,7 @@ init_cpe_match_nodes_iterator (iterator_t* iterator, const char *criteria) " JOIN scap.cpe_nodes_match_criteria c" " ON n.id = c.node_id" " JOIN scap.cpe_match_strings r" - " ON c.match_criteria = r.match_criteria_id" + " ON c.match_criteria_id = r.match_criteria_id" " WHERE criteria like '%s%%';", quoted_criteria); g_free (quoted_criteria); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 4e6d3d6fc..ed4903771 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -4043,6 +4043,31 @@ update_scap_cves () return 0; } +/** + * @brief Update SCAP affected products. + * + * Assume that the databases are attached. + * + * @return 0 success, -1 error. + */ +static int +update_scap_affected_products () +{ + g_info ("Updating affected products"); + + sql ("INSERT INTO scap2.affected_products" + " SELECT DISTINCT scap2.cpe_match_nodes.cve_id, scap2.cpes.id" + " FROM scap2.cpe_match_nodes, scap2.cpe_nodes_match_criteria," + " scap2.cpe_matches, scap2.cpes" + " WHERE scap2.cpe_match_nodes.id = scap2.cpe_nodes_match_criteria.node_id" + " AND scap2.cpe_nodes_match_criteria.vulnerable = 1" + " AND scap2.cpe_nodes_match_criteria.match_criteria_id =" + " scap2.cpe_matches.match_criteria_id" + " AND scap2.cpe_matches.cpe_name_id = scap2.cpes.cpe_name_id;"); + + return 0; +} + /** * @brief Insert a SCAP CPE match string from JSON. * @@ -5606,6 +5631,15 @@ update_scap (gboolean reset_scap_db) return -1; } + g_debug ("%s: update affected_products", __func__); + setproctitle ("Syncing SCAP: Updating affected products"); + + if (update_scap_affected_products () == -1) + { + abort_scap_update (); + return -1; + } + g_debug ("%s: updating user defined data", __func__); g_debug ("%s: update epss", __func__); From b3ff0ab4d139f99cf8905d3bbaf4089661d1c2dd Mon Sep 17 00:00:00 2001 From: Johannes Helmold Date: Mon, 11 Nov 2024 10:03:19 +0100 Subject: [PATCH 32/64] Small amendment. --- src/manage_sql_secinfo.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index ed4903771..fead001e6 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -4047,10 +4047,8 @@ update_scap_cves () * @brief Update SCAP affected products. * * Assume that the databases are attached. - * - * @return 0 success, -1 error. */ -static int +static void update_scap_affected_products () { g_info ("Updating affected products"); @@ -4064,8 +4062,6 @@ update_scap_affected_products () " AND scap2.cpe_nodes_match_criteria.match_criteria_id =" " scap2.cpe_matches.match_criteria_id" " AND scap2.cpe_matches.cpe_name_id = scap2.cpes.cpe_name_id;"); - - return 0; } /** @@ -5634,11 +5630,7 @@ update_scap (gboolean reset_scap_db) g_debug ("%s: update affected_products", __func__); setproctitle ("Syncing SCAP: Updating affected products"); - if (update_scap_affected_products () == -1) - { - abort_scap_update (); - return -1; - } + update_scap_affected_products (); g_debug ("%s: updating user defined data", __func__); From 7cb34b7d3b36f68f3164f20988a6aa5ffc4801f6 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 8 Nov 2024 15:18:40 +0100 Subject: [PATCH 33/64] Fix: Remove the insertion of unused deprecated-by-id from XML CPE feed files --- src/manage_sql_secinfo.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index fead001e6..70b819944 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -2081,7 +2081,7 @@ static int insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata, int modification_time) { - gchar *name, *status, *deprecated, *nvd_id; + gchar *name, *status, *nvd_id; gchar *quoted_name, *quoted_title, *quoted_status, *quoted_nvd_id; element_t title; int first; @@ -2103,27 +2103,12 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata return -1; } - deprecated = element_attribute (item_metadata, - "deprecated-by-nvd-id"); - if (deprecated - && (g_regex_match_simple ("^[0-9]+$", (gchar *) deprecated, 0, 0) - == 0)) - { - g_warning ("%s: invalid deprecated-by-nvd-id: %s", - __func__, - deprecated); - g_free (name); - g_free (status); - return -1; - } - nvd_id = element_attribute (item_metadata, "nvd-id"); if (nvd_id == NULL) { g_warning ("%s: nvd_id missing", __func__); g_free (name); g_free (status); - g_free (deprecated); return -1; } @@ -2163,7 +2148,7 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata first = inserts_check_size (inserts); g_string_append_printf (inserts->statement, - "%s ('%s', '%s', '%s', %i, %i, '%s', %s, '%s')", + "%s ('%s', '%s', '%s', %i, %i, '%s', '%s')", first ? "" : ",", quoted_name, quoted_name, @@ -2171,7 +2156,6 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata modification_time, modification_time, quoted_status, - deprecated ? deprecated : "NULL", quoted_nvd_id); inserts->current_chunk_size++; @@ -2180,7 +2164,6 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata g_free (quoted_name); g_free (quoted_status); g_free (quoted_nvd_id); - g_free (deprecated); return 0; } From 2ed6a1b7844c45c7dc3cab126994f5b4766d4bb7 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Mon, 11 Nov 2024 16:53:44 +0100 Subject: [PATCH 34/64] Change: Insert CVEs products from CPE matches table --- src/manage_sql_secinfo.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 70b819944..cf13bf215 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3406,6 +3406,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, cJSON* configurations_json) { cJSON *configuration_item; + GString *software = g_string_new (""); cJSON_ArrayForEach (configuration_item, configurations_json) { @@ -3495,11 +3496,30 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, id, vulnerable ? 1 : 0, quoted_match_criteria_id); - + + if (vulnerable) + { + iterator_t cpe_matches; + init_cpe_match_string_matches_iterator (&cpe_matches, quoted_match_criteria_id); + while (next (&cpe_matches)) + g_string_append_printf (software, "%s ", cpe_matches_cpe_name (&cpe_matches)); + cleanup_iterator (&cpe_matches); + } g_free (quoted_match_criteria_id); } } } + if (software->len > 0) + { + gchar *quoted_software = sql_quote (software->str); + sql ("UPDATE scap2.cves" + " SET products = '%s'" + " WHERE id = %llu;", + quoted_software, cve_db_id); + g_free (quoted_software); + } + g_string_free (software, TRUE); + return 0; } From 53f503efe9e12176e74d16e78534095e24b2ebd5 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Wed, 13 Nov 2024 23:42:57 +0200 Subject: [PATCH 35/64] Flush trailing whitespace --- src/gmp.c | 116 +++++++++++----------- src/gmp_report_configs.c | 10 +- src/gvmd.c | 2 +- src/manage.c | 16 +-- src/manage.h | 6 +- src/manage_configs.c | 2 +- src/manage_pg.c | 16 +-- src/manage_port_lists.c | 2 +- src/manage_report_configs.c | 2 +- src/manage_report_formats.c | 2 +- src/manage_sql.c | 156 +++++++++++++++--------------- src/manage_sql_report_configs.c | 10 +- src/manage_sql_report_formats.c | 6 +- src/manage_sql_secinfo.c | 40 ++++---- src/manage_sql_tls_certificates.c | 4 +- src/sql_pg.c | 6 +- src/utils.c | 4 +- src/utils_tests.c | 16 +-- 18 files changed, 208 insertions(+), 208 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 5fb9ec15b..2084b8a6a 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -5513,7 +5513,7 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, append_attribute (attribute_names, attribute_values, "config_id", &get_reports_data->config_id); - + append_attribute (attribute_names, attribute_values, "format_id", &get_reports_data->format_id); @@ -5604,7 +5604,7 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, "type", &typebuf)) get_resource_names_data->type = g_ascii_strdown (typebuf, -1); set_client_state (CLIENT_GET_RESOURCE_NAMES); - } + } else if (strcasecmp ("GET_RESULTS", element_name) == 0) { const gchar* attribute; @@ -8451,7 +8451,7 @@ buffer_override_xml (GString *buffer, iterator_t *overrides, buffer_xml_append_printf (buffer, "%s", iso_if_time (get_iterator_creation_time (overrides))); - + buffer_xml_append_printf (buffer, "%s", iso_if_time (get_iterator_modification_time (overrides))); @@ -9353,9 +9353,9 @@ results_xml_append_nvt (iterator_t *results, GString *buffer, int cert_loaded) * */ void -buffer_diff(GString *buffer, const char *descr, const char *delta_descr) +buffer_diff(GString *buffer, const char *descr, const char *delta_descr) { - + gchar *diff = strdiff (descr ? descr : "", delta_descr ? delta_descr : ""); if (diff) @@ -9428,7 +9428,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, report_t report; task_t selected_task; time_t creation_time; - + comment = get_iterator_comment (results); name = get_iterator_name (results); host = result_iterator_host (results); @@ -9503,7 +9503,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, { const char *owner_name; time_t modification_time; - + if (use_delta_fields) { owner_name = result_iterator_delta_owner_name (results); @@ -9545,7 +9545,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, { if (task == 0) selected_task = result_iterator_delta_task (results); - + result_task_name = task_name(result_iterator_delta_task (results)); result_report_id = report_uuid(result_iterator_delta_report (results)); } @@ -9553,7 +9553,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, { if (task == 0) selected_task = result_iterator_task (results); - + result_task_name = task_name (result_iterator_task (results)); result_report_id = report_uuid (result_iterator_report (results)); } @@ -9674,14 +9674,14 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, const char *nvt_version, *level; if (use_delta_fields) { - nvt_version = result_iterator_delta_nvt_version (results); + nvt_version = result_iterator_delta_nvt_version (results); level = result_iterator_delta_level (results); - } + } else { nvt_version = result_iterator_scan_nvt_version (results); level = result_iterator_level (results); - } + } buffer_xml_append_printf (buffer, "%s" @@ -9712,7 +9712,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, { /* Only send the original severity if it has changed. */ if (strncmp (original_severity, - severity, + severity, /* Avoid rounding differences. */ 3)) buffer_xml_append_printf (buffer, @@ -9749,7 +9749,7 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, if (delta_state) g_string_append_printf (buffer, "%s", delta_state); - if(delta_results) { + if(delta_results) { /* delta reports version 1 */ if (changed) { @@ -9768,8 +9768,8 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, g_free (delta_nl_descr); } } else { - /* delta reports version 2 */ - if (changed) + /* delta reports version 2 */ + if (changed) { gchar *delta_nl_descr; const char *delta_descr; @@ -9812,8 +9812,8 @@ buffer_results_xml (GString *buffer, iterator_t *results, task_t task, g_free (nl_descr_escaped); } - if (use_delta_fields - ? result_iterator_delta_may_have_tickets (results) + if (use_delta_fields + ? result_iterator_delta_may_have_tickets (results) : result_iterator_may_have_tickets (results)) buffer_result_tickets_xml (buffer, result); @@ -13304,7 +13304,7 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) vee = cpe_match_string_iterator_version_end_excl (&cpe_match_ranges); xml_string_append (buffer, - "%s", + "%s", vsi ?: ""); xml_string_append (buffer, "%s", @@ -15536,7 +15536,7 @@ print_report_config_params (gmp_parser_t *gmp_parser, GError **error, SENDF_TO_CLIENT_OR_FAIL ("%s", - report_config_param_iterator_using_default (¶ms), + report_config_param_iterator_using_default (¶ms), value ? value : ""); if (value) { @@ -15711,27 +15711,27 @@ handle_get_report_configs (gmp_parser_t *gmp_parser, GError **error) { SEND_TO_CLIENT_OR_FAIL ("1"); } - - SENDF_TO_CLIENT_OR_FAIL + + SENDF_TO_CLIENT_OR_FAIL ("", report_config_iterator_report_format_id (&report_configs) ); - + if (!orphan) { - SENDF_TO_CLIENT_OR_FAIL + SENDF_TO_CLIENT_OR_FAIL ("%s", report_config_iterator_report_format_name (&report_configs) ); - + if (report_config_iterator_report_format_readable (&report_configs) == 0) { SENDF_TO_CLIENT_OR_FAIL (""); } } - + SENDF_TO_CLIENT_OR_FAIL (""); - + print_report_config_params (gmp_parser, error, report_config_param_iterator_rowid ( &report_configs @@ -16114,16 +16114,16 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) } /** - * @brief Assign resource iterator with an init iterator based on the type + * @brief Assign resource iterator with an init iterator based on the type * in the get command data. * * @param[in] resource_names_data data for get_resource_names command. * @param[out] iterator address of iterator function pointer. - * + * * @return 1 if type is invalid, else 0. */ int -select_resource_iterator (get_resource_names_data_t *resource_names_data, +select_resource_iterator (get_resource_names_data_t *resource_names_data, int (**iterator) (iterator_t*, get_data_t *)) { if (g_strcmp0 ("cpe", resource_names_data->type) == 0) @@ -16173,7 +16173,7 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, else if (g_strcmp0 ("group", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_group_iterator; - } + } else if (g_strcmp0 ("note", resource_names_data->type) == 0) { *iterator = init_note_iterator_all; @@ -16181,41 +16181,41 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, else if (g_strcmp0 ("override", resource_names_data->type) == 0) { *iterator = init_override_iterator_all; - } + } else if (g_strcmp0 ("permission", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_permission_iterator; - } + } else if (g_strcmp0 ("port_list", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_port_list_iterator; - } + } else if (g_strcmp0 ("report", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_iterator; - get_data_set_extra (&resource_names_data->get, + get_data_set_extra (&resource_names_data->get, "usage_type", g_strdup ("scan")); - } + } else if (g_strcmp0 ("audit_report", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_iterator; - get_data_set_extra (&resource_names_data->get, + get_data_set_extra (&resource_names_data->get, "usage_type", g_strdup ("audit")); } else if (g_strcmp0 ("report_config", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_config_iterator; - } + } else if (g_strcmp0 ("report_format", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_format_iterator; - } + } else if (g_strcmp0 ("role", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_role_iterator; - } + } else if (g_strcmp0 ("config", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_config_iterator; @@ -16233,15 +16233,15 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, else if (g_strcmp0 ("scanner", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_scanner_iterator; - } + } else if (g_strcmp0 ("schedule", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_schedule_iterator; - } + } else if (g_strcmp0 ("target", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_target_iterator; - } + } else if (g_strcmp0 ("task", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_task_iterator; @@ -16259,11 +16259,11 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, else if (g_strcmp0 ("tls_certificate", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_tls_certificate_iterator; - } + } else if (g_strcmp0 ("user", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_user_iterator; - } + } else { return 1; @@ -16294,10 +16294,10 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) return; } - if ((((g_strcmp0 ("host", get_resource_names_data->type) == 0) + if ((((g_strcmp0 ("host", get_resource_names_data->type) == 0) ||(g_strcmp0 ("os", get_resource_names_data->type) == 0)) && (acl_user_may ("get_assets") == 0)) - || ((g_strcmp0 ("result", get_resource_names_data->type) == 0) + || ((g_strcmp0 ("result", get_resource_names_data->type) == 0) && (acl_user_may ("get_results") == 0)) || (((g_strcmp0 ("report", get_resource_names_data->type) == 0) || (g_strcmp0 ("audit_report", get_resource_names_data->type) == 0)) @@ -16345,9 +16345,9 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) get_resource_names_data_reset (get_resource_names_data); set_client_state (CLIENT_AUTHENTIC); return; - } + } - if (select_resource_iterator(get_resource_names_data, &init_resource_iterator)) + if (select_resource_iterator(get_resource_names_data, &init_resource_iterator)) { if (send_find_error_to_client ("get_resource_names", "type", get_resource_names_data->type, gmp_parser)) @@ -16372,7 +16372,7 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) error_send_to_client (error); return; } - break; + break; case 2: if (send_find_error_to_client ("get_resource_names", "filter", get_resource_names_data->get.filt_id, @@ -16391,7 +16391,7 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) set_client_state (CLIENT_AUTHENTIC); return; } - + SEND_GET_START ("resource_name"); SENDF_TO_CLIENT_OR_FAIL ("%s", get_resource_names_data->type); @@ -16399,8 +16399,8 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) { GString *result; result = g_string_new (""); - - if(g_strcmp0 ("tls_certificate", get_resource_names_data->type) == 0) + + if(g_strcmp0 ("tls_certificate", get_resource_names_data->type) == 0) { buffer_xml_append_printf (result, "" @@ -16410,8 +16410,8 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) : "", tls_certificate_iterator_subject_dn (&resource) ? tls_certificate_iterator_subject_dn (&resource) - : ""); - } + : ""); + } else if (g_strcmp0 ("override", get_resource_names_data->type) == 0) { buffer_xml_append_printf (result, @@ -16422,9 +16422,9 @@ handle_get_resource_names (gmp_parser_t *gmp_parser, GError **error) : "", override_iterator_nvt_name (&resource) ? override_iterator_nvt_name (&resource) - : ""); + : ""); } - else + else { buffer_xml_append_printf (result, "" @@ -20443,7 +20443,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, case CLIENT_GET_RESOURCE_NAMES: handle_get_resource_names (gmp_parser, error); - break; + break; case CLIENT_GET_RESULTS: handle_get_results (gmp_parser, error); diff --git a/src/gmp_report_configs.c b/src/gmp_report_configs.c index 5a471b05b..9fcb44c87 100644 --- a/src/gmp_report_configs.c +++ b/src/gmp_report_configs.c @@ -38,7 +38,7 @@ /** * @brief Collect params from entity. - * + * * @param[in] entity Entity to check for param elements. * * @return Array of params @@ -49,7 +49,7 @@ params_from_entity (entity_t entity) array_t *params; entities_t children; entity_t param_entity; - + params = make_array (); children = entity->entities; while ((param_entity = first_entity (children))) @@ -85,7 +85,7 @@ params_from_entity (entity_t entity) if (param_value) { const char *use_default_str; - + param->value = g_strdup (entity_text (param_value)); use_default_str = entity_attribute (param_value, "use_default"); if (use_default_str) @@ -100,7 +100,7 @@ params_from_entity (entity_t entity) report_config_param_data_free (param); continue; } - + array_add (params, param); } @@ -529,7 +529,7 @@ modify_report_config_run (gmp_parser_t *gmp_parser, GError **error) comment ? comment->text : NULL, params, &error_message); - + switch (ret) { case 0: diff --git a/src/gvmd.c b/src/gvmd.c index 99f8e1fa1..f5c0100b0 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -2474,7 +2474,7 @@ gvmd (int argc, char** argv, char *env[]) /* Set number of retries waiting for memory */ set_mem_wait_retries (mem_wait_retries); - + /* Set minimum memory for feed updates */ set_min_mem_feed_update (min_mem_feed_update); diff --git a/src/manage.c b/src/manage.c index f61426986..c194bae68 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3672,12 +3672,12 @@ fork_cve_scan_handler (task_t task, target_t target) gvm_hosts = gvm_hosts_new (hosts); free (hosts); - + if (gvm_hosts_exclude (gvm_hosts, exclude_hosts ?: "") < 0) { set_task_interrupted (task, "Failed to exclude hosts." - " Interrupting scan."); + " Interrupting scan."); set_report_scan_run_status (global_current_report, TASK_STATUS_INTERRUPTED); gvm_hosts_free (gvm_hosts); free (exclude_hosts); @@ -5480,12 +5480,12 @@ feed_sync_required () /** * @brief Wait for memory - * + * * @param[in] check_func Function to check memory, should return 1 if enough. * @param[in] retries Number of retries. * @param[in] min_mem Minimum memory in MiB, for logging only * @param[in] action Short descriptor of action waiting for memory. - * + * * @return 0 if enough memory is available, 1 gave up */ static int @@ -6462,7 +6462,7 @@ get_nvt_xml (iterator_t *nvts, int details, int pref_count, if (nvt_iterator_epss_cve (nvts)) { - buffer_xml_append_printf + buffer_xml_append_printf (buffer, "" "" @@ -6475,7 +6475,7 @@ get_nvt_xml (iterator_t *nvts, int details, int pref_count, if (nvt_iterator_has_epss_severity (nvts)) { - buffer_xml_append_printf + buffer_xml_append_printf (buffer, "%0.1f", nvt_iterator_epss_severity (nvts)); @@ -6495,7 +6495,7 @@ get_nvt_xml (iterator_t *nvts, int details, int pref_count, if (nvt_iterator_has_max_epss_severity (nvts)) { - buffer_xml_append_printf + buffer_xml_append_printf (buffer, "%0.1f", nvt_iterator_max_epss_severity (nvts)); @@ -6860,7 +6860,7 @@ set_mem_wait_retries (int new_retries) /** * @brief Check if the minimum memory for feed updates is available - * + * * @return 1 if minimum memory amount is available, 0 if not */ int diff --git a/src/manage.h b/src/manage.h index 2930789b9..0285d708d 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1416,7 +1416,7 @@ int init_result_get_iterator (iterator_t*, const get_data_t *, report_t, const char*, const gchar *); int -init_result_get_iterator_all (iterator_t* iterator, get_data_t *get); +init_result_get_iterator_all (iterator_t* iterator, get_data_t *get); gboolean next_report (iterator_t*, report_t*); @@ -1808,7 +1808,7 @@ manage_filter_controls (const gchar *, int *, int *, gchar **, int *); void manage_report_filter_controls (const gchar *, int *, int *, gchar **, int *, - int *, gchar **, gchar **, gchar **, gchar **, + int *, gchar **, gchar **, gchar **, gchar **, gchar **, int *, int *, int *, int *, gchar **); gchar * @@ -2664,7 +2664,7 @@ init_override_iterator (iterator_t*, const get_data_t*, nvt_t, result_t, task_t); int -init_override_iterator_all (iterator_t* iterator, get_data_t *get); +init_override_iterator_all (iterator_t* iterator, get_data_t *get); const char* override_iterator_nvt_oid (iterator_t*); diff --git a/src/manage_configs.c b/src/manage_configs.c index d7de250af..1eeba26f7 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -343,7 +343,7 @@ should_sync_config_from_path (const char *path, gboolean rebuild, if (resource_id_deprecated ("config", uuid)) { find_config_no_acl (uuid, config); - + if (rebuild) { g_free (uuid); diff --git a/src/manage_pg.c b/src/manage_pg.c index 43e031b99..56ea9f7e0 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -871,13 +871,13 @@ manage_create_sql_functions () " OR qod2 is null" " THEN RETURN 'new';" " WHEN description1 != description2" - " OR severity1 != severity2" + " OR severity1 != severity2" " OR qod1 != qod2" " OR hostname1 != hostname2" " OR path1 != path2" " THEN RETURN 'changed';" " ELSE RETURN 'same';" - " END CASE;" + " END CASE;" "END;" "$$ LANGUAGE plpgsql" " IMMUTABLE;"); @@ -890,7 +890,7 @@ manage_create_sql_functions () " WHEN port = 'package'" " THEN RETURN 'general/tcp';" " ELSE RETURN port;" - " END CASE;" + " END CASE;" "END;" "$$ LANGUAGE plpgsql" " IMMUTABLE;"); @@ -913,7 +913,7 @@ manage_create_sql_functions () " AND description LIKE 'Compliant:%%YES%%') > 0" " THEN RETURN 'yes';" " ELSE RETURN 'undefined';" - " END CASE;" + " END CASE;" "END;" "$$ LANGUAGE plpgsql" " IMMUTABLE;"); @@ -925,7 +925,7 @@ manage_create_sql_functions () " DECLARE count integer := 0;" " BEGIN" " WITH compliance_count AS" - " (SELECT count(*) AS total FROM results WHERE report = report_id" + " (SELECT count(*) AS total FROM results WHERE report = report_id" " AND description LIKE 'Compliant:%%' || compliance || '%%')" " SELECT total FROM compliance_count" " INTO count;" @@ -934,7 +934,7 @@ manage_create_sql_functions () " $$ LANGUAGE plpgsql" " IMMUTABLE;"); - /* Functions in SQL. */ + /* Functions in SQL. */ if (sql_int ("SELECT (EXISTS (SELECT * FROM information_schema.tables" " WHERE table_catalog = '%s'" @@ -1996,7 +1996,7 @@ create_indexes_nvt () " 'nvts', 'cvss_base');"); sql ("SELECT create_index ('nvts_by_solution_type'," " 'nvts', 'solution_type');"); - + sql ("SELECT create_index ('vt_refs_by_vt_oid'," " 'vt_refs', 'vt_oid');"); @@ -3569,7 +3569,7 @@ manage_db_init (const gchar *name) sql ("CREATE TABLE scap2.cpe_matches" " (id SERIAL PRIMARY KEY," - " match_criteria_id text," + " match_criteria_id text," " cpe_name_id text," " cpe_name text);"); diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 26f7c8cc5..2c66aadf5 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -280,7 +280,7 @@ should_sync_port_list_from_path (const char *path, gboolean rebuild, if (resource_id_deprecated ("port_list", uuid)) { find_port_list_no_acl (uuid, port_list); - + if (rebuild) { return 1; diff --git a/src/manage_report_configs.c b/src/manage_report_configs.c index 277f2592d..ff2c7add2 100644 --- a/src/manage_report_configs.c +++ b/src/manage_report_configs.c @@ -54,7 +54,7 @@ find_report_config_with_permission (const char *uuid, /** * @brief Free a report config parameter data struct. - * + * * @param[in] param The parameter to free. */ void diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 8cc94feb0..8e66ad395 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -645,7 +645,7 @@ should_sync_report_format_from_path (const char *path, if (resource_id_deprecated ("report_format", uuid)) { find_report_format_no_acl (uuid, report_format); - + if (rebuild) { g_free (uuid); diff --git a/src/manage_sql.c b/src/manage_sql.c index 32f797a13..945ae9aa0 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -294,7 +294,7 @@ cache_all_permissions_for_users (GArray*); static void report_cache_counts (report_t, int, int, const char*); -static gchar * +static gchar * reports_extra_where (int, const char *, const char *); static int @@ -2037,8 +2037,8 @@ filter_control_str (keyword_t **point, const char *column, gchar **string) * @param[out] compliance_levels String describing compliance levels * to include in count (for example, "yniu" for * "yes" (compliant), "n" for "no" (not compliant), - * "i" for "incomplete" and "u" for "undefined" - * (without compliance information). + * "i" for "incomplete" and "u" for "undefined" + * (without compliance information). * All levels if NULL. * @param[out] delta_states String describing delta states to include in count * (for example, "sngc" Same, New, Gone and Changed). @@ -2056,9 +2056,9 @@ manage_report_filter_controls (const gchar *filter, int *first, int *max, gchar **sort_field, int *sort_order, int *result_hosts_only, gchar **min_qod, gchar **levels, gchar **compliance_levels, - gchar **delta_states, gchar **search_phrase, - int *search_phrase_exact, int *notes, - int *overrides, int *apply_overrides, + gchar **delta_states, gchar **search_phrase, + int *search_phrase_exact, int *notes, + int *overrides, int *apply_overrides, gchar **zone) { keyword_t **point; @@ -16177,7 +16177,7 @@ check_db_versions () else { int supported; - + supported = manage_scap_db_supported_version (); if (scap_db_version != supported) { @@ -21863,7 +21863,7 @@ report_compliance_by_uuid (const char *report_id, " WHERE report = %llu" " AND description NOT LIKE 'Compliant:%%';", report); - } + } g_free (quoted_uuid); } @@ -22277,7 +22277,7 @@ report_iterator_opts_table (int override, int min_qod) * @brief Return SQL WHERE for restricting a SELECT to compliance statuses. * * @param[in] compliance String describing compliance statuses of reports - * to include (for example, "yniu" for yes (compliant), + * to include (for example, "yniu" for yes (compliant), * no (not compliant), i (incomplete) and u (undefined)) * All compliance statuses if NULL. * @@ -22351,7 +22351,7 @@ reports_extra_where (int trash, const gchar *filter, const char *usage_type) { trash_clause = g_strdup_printf (" AND (SELECT hidden FROM tasks" " WHERE tasks.id = task)" - " = 2"); + " = 2"); } else { @@ -22460,7 +22460,7 @@ init_report_iterator (iterator_t* iterator, const get_data_t *get) extra_tables = report_iterator_opts_table (overrides, min_qod); usage_type = get_data_get_extra (get, "usage_type"); - extra_where = reports_extra_where (get->trash, + extra_where = reports_extra_where (get->trash, filter ? filter : get->filter, usage_type); @@ -22616,7 +22616,7 @@ where_levels_auto (const char *levels, const char *new_severity_sql) /** * @brief Return SQL WHERE for restricting a SELECT to compliance levels. * - * @param[in] levels String describing compliance levels to include in + * @param[in] levels String describing compliance levels to include in * report (for example, "yniu" for "yes, "no", "incomplete" * and "undefined"). All levels if NULL. * @@ -23620,14 +23620,14 @@ init_result_get_iterator_severity (iterator_t* iterator, const get_data_t *get, * @param[in] apply_overrides Whether to apply overrides. * @param[in] dynamic_severity Whether to use dynamic severity. * @param[in] nvts_table NVTS table. - * @param[in] results_table Results table. + * @param[in] results_table Results table. * * @return SQL clause for FROM. */ static gchar * -result_iterator_lateral (int apply_overrides, - int dynamic_severity, - const char *results_table, +result_iterator_lateral (int apply_overrides, + int dynamic_severity, + const char *results_table, const char *nvts_table) { if (apply_overrides && dynamic_severity) @@ -23642,11 +23642,11 @@ result_iterator_lateral (int apply_overrides, " ov_old_severity)" " LIMIT 1)," " (SELECT curr_severity FROM curr LIMIT 1))" - " AS new_severity)", + " AS new_severity)", results_table, nvts_table, results_table, - results_table, + results_table, results_table); if (apply_overrides) @@ -23832,7 +23832,7 @@ result_count (const get_data_t *get, report_t report, const char* host) opts_tables = result_iterator_opts_table (apply_overrides, dynamic_severity); - lateral_clause = result_iterator_lateral (apply_overrides, + lateral_clause = result_iterator_lateral (apply_overrides, dynamic_severity, "results", "nvts"); @@ -26215,19 +26215,19 @@ report_compliance_from_counts (const int* yes_count, * @param[in] get Get data. * @param[out] f_compliance_yes Compliant results count after filtering. * @param[out] f_compliance_no Incompliant results count after filtering. - * @param[out] f_compliance_incomplete Incomplete results count + * @param[out] f_compliance_incomplete Incomplete results count * after filtering. - * @param[out] f_compliance_undefined Undefined results count + * @param[out] f_compliance_undefined Undefined results count * after filtering. * * @return 0 on success, -1 on error. */ static int -report_compliance_f_counts (report_t report, - const get_data_t* get, - int* f_compliance_yes, - int* f_compliance_no, - int* f_compliance_incomplete, +report_compliance_f_counts (report_t report, + const get_data_t* get, + int* f_compliance_yes, + int* f_compliance_no, + int* f_compliance_incomplete, int* f_compliance_undefined) { if (report == 0) @@ -26262,7 +26262,7 @@ report_compliance_f_counts (report_t report, else if (strcasecmp (compliance, "no") == 0) { no_count++; - } + } else if (strcasecmp (compliance, "incomplete") == 0) { incomplete_count++; @@ -26270,7 +26270,7 @@ report_compliance_f_counts (report_t report, else if (strcasecmp (compliance, "undefined") == 0) { undefined_count++; - } + } } @@ -26301,11 +26301,11 @@ report_compliance_f_counts (report_t report, * @return 0 on success, -1 on error. */ static int -report_compliance_counts (report_t report, +report_compliance_counts (report_t report, const get_data_t* get, - int* compliance_yes, + int* compliance_yes, int* compliance_no, - int* compliance_incomplete, + int* compliance_incomplete, int* compliance_undefined) { if (report == 0) @@ -26313,7 +26313,7 @@ report_compliance_counts (report_t report, report_compliance_by_uuid (report_uuid(report), compliance_yes, - compliance_no, + compliance_no, compliance_incomplete, compliance_undefined); @@ -27550,7 +27550,7 @@ print_report_host_details_xml (report_host_t report_host, FILE *stream, * @return 0 on success, -1 error. */ static int -print_report_host_tls_certificates_xml (report_host_t report_host, +print_report_host_tls_certificates_xml (report_host_t report_host, const char *host_ip, FILE *stream) { @@ -27572,14 +27572,14 @@ print_report_host_tls_certificates_xml (report_host_t report_host, " OR source_description = 'SSL Certificate')", report_host); - while (next (&tls_certs)) + while (next (&tls_certs)) { const char *certificate_prefixed, *certificate_b64; gsize certificate_size; unsigned char *certificate; const char *scanner_fpr_prefixed, *scanner_fpr; gchar *quoted_scanner_fpr; - char *ssldetails; + char *ssldetails; iterator_t ports; gboolean valid; time_t now; @@ -27642,7 +27642,7 @@ print_report_host_tls_certificates_xml (report_host_t report_host, now = time (NULL); - if((expiration_time >= now || expiration_time == -1) + if((expiration_time >= now || expiration_time == -1) && (activation_time <= now || activation_time == -1)) { valid = TRUE; @@ -27692,7 +27692,7 @@ print_report_host_tls_certificates_xml (report_host_t report_host, g_free (serial); free (hostname); - + init_iterator (&ports, "SELECT value FROM report_host_details" " WHERE report_host = %llu" @@ -27700,7 +27700,7 @@ print_report_host_tls_certificates_xml (report_host_t report_host, " AND value LIKE '%%:%%:%s'", report_host, quoted_scanner_fpr); - + PRINT (stream, ""); while (next (&ports)) @@ -27719,10 +27719,10 @@ print_report_host_tls_certificates_xml (report_host_t report_host, PRINT (stream, ""); PRINT (stream, ""); - + g_free (quoted_scanner_fpr); - cleanup_iterator (&ports); - + cleanup_iterator (&ports); + } cleanup_iterator (&tls_certs); @@ -28331,7 +28331,7 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, " ON results.nvt = nvts.oid %s," " LATERAL %s AS lateral_new_severity", opts_tables, - lateral_clause); + lateral_clause); g_free (lateral_clause); @@ -28355,24 +28355,24 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, extra_with = g_strdup_printf(" comparison AS (" " WITH r1a as (SELECT results.id, description, host, report, port," - " severity, nvt, results.qod, results.uuid, hostname," + " severity, nvt, results.qod, results.uuid, hostname," " path, r1_lateral.new_severity as new_severity " " FROM results " " LEFT JOIN (SELECT cvss_base, oid AS nvts_oid FROM nvts)" " AS nvts_cols" " ON nvts_cols.nvts_oid = results.nvt" - " %s, LATERAL %s AS r1_lateral" + " %s, LATERAL %s AS r1_lateral" " WHERE report = %llu)," - " r2a as (SELECT results.*, r2_lateral.new_severity AS new_severity" - " FROM results" + " r2a as (SELECT results.*, r2_lateral.new_severity AS new_severity" + " FROM results" " LEFT JOIN (SELECT cvss_base, oid AS nvts_oid FROM nvts)" - " AS nvts_cols" - " ON nvts_cols.nvts_oid = results.nvt" - " %s, LATERAL %s AS r2_lateral" + " AS nvts_cols" + " ON nvts_cols.nvts_oid = results.nvt" + " %s, LATERAL %s AS r2_lateral" " WHERE report = %llu)," " r1 as (SELECT DISTINCT ON (r1a.id) r1a.*, r2a.id as r2id, row_number() over w1 as r1_rank" " FROM r1a LEFT JOIN r2a ON r1a.host = r2a.host" - " AND normalize_port(r1a.port) = normalize_port(r2a.port)" + " AND normalize_port(r1a.port) = normalize_port(r2a.port)" " AND r1a.nvt = r2a.nvt " " AND (r1a.new_severity = 0) = (r2a.new_severity = 0)" " AND (r1a.description = r2a.description)" @@ -28381,15 +28381,15 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, " ORDER BY r1a.id)," " r2 as (SELECT DISTINCT ON (r2a.id) r2a.*, r1a.id as r1id, row_number() over w2 as r2_rank" " FROM r2a LEFT JOIN r1a ON r2a.host = r1a.host" - " AND normalize_port(r2a.port) = normalize_port(r1a.port)" + " AND normalize_port(r2a.port) = normalize_port(r1a.port)" " AND r2a.nvt = r1a.nvt " " AND (r2a.new_severity = 0) = (r1a.new_severity = 0)" " AND (r2a.description = r1a.description)" " WINDOW w2 AS (PARTITION BY r2a.host, normalize_port(r2a.port)," " r2a.nvt, r2a.new_severity = 0, r1a.id is null ORDER BY r1a.id)" " ORDER BY r2a.id)" - " (SELECT r1.id AS result1_id," - " r2.id AS result2_id," + " (SELECT r1.id AS result1_id," + " r2.id AS result2_id," " compare_results(" " r1.description," " r2.description," @@ -28413,13 +28413,13 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, " r2.owner AS delta_owner," " r2.path AS delta_path," " r2.host AS delta_host," - RESULT_HOSTNAME_SQL("r2.hostname", "r2.host", "r2.report") + RESULT_HOSTNAME_SQL("r2.hostname", "r2.host", "r2.report") " AS delta_hostname," " r2.nvt_version AS delta_nvt_version" " FROM r1" " FULL OUTER JOIN r2" " ON r1.host = r2.host" - " AND normalize_port(r1.port) = normalize_port(r2.port)" + " AND normalize_port(r1.port) = normalize_port(r2.port)" " AND r1.nvt = r2.nvt " " AND (r1.new_severity = 0) = (r2.new_severity = 0)" " AND ((r1id IS NULL AND r2id IS NULL) OR" @@ -28613,12 +28613,12 @@ print_report_delta_xml (FILE *out, iterator_t *results, 0, state, NULL, - (strcmp (state, "changed") == 0), + (strcmp (state, "changed") == 0), -1, 0, /* Lean. */ 0); /* Delta fields. */ - - if (fprintf (out, "%s", buffer->str) < 0) + + if (fprintf (out, "%s", buffer->str) < 0) { g_string_free (buffer, TRUE); g_tree_destroy (ports); @@ -28810,8 +28810,8 @@ print_report_xml_start (report_t report, report_t delta, task_t task, &first_result, &max_results, &sort_field, &sort_order, &result_hosts_only, &min_qod, &levels, &compliance_levels, - &delta_states, &search_phrase, - &search_phrase_exact, ¬es, + &delta_states, &search_phrase, + &search_phrase_exact, ¬es, &overrides, &apply_overrides, &zone); } else @@ -28822,7 +28822,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, &first_result, &max_results, &sort_field, &sort_order, &result_hosts_only, &min_qod, &levels, &compliance_levels, - &delta_states, &search_phrase, + &delta_states, &search_phrase, &search_phrase_exact, ¬es, &overrides, &apply_overrides, &zone); } @@ -28944,7 +28944,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (strcmp (tsk_usage_type, "audit")) { if (delta == 0) - { + { int total_holes, total_infos, total_logs; int total_warnings, total_false_positives; get_data_t *all_results_get; @@ -28980,7 +28980,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, filtered_result_count = holes + infos + logs + warnings + false_positives; - } + } } /* Get report run status. */ @@ -29845,7 +29845,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { report_host_t report_host = host_iterator_report_host(&hosts); - if (print_report_host_tls_certificates_xml(report_host, + if (print_report_host_tls_certificates_xml(report_host, result_host, out)) { @@ -29865,15 +29865,15 @@ print_report_xml_start (report_t report, report_t delta, task_t task, const char *host; iterator_t hosts; init_report_host_iterator (&hosts, report, NULL, 0); - + PRINT (out, ""); - + while (next (&hosts)) { report_host_t report_host = host_iterator_report_host(&hosts); host = host_iterator_host (&hosts); - if (print_report_host_tls_certificates_xml(report_host, + if (print_report_host_tls_certificates_xml(report_host, host, out)) { @@ -47631,7 +47631,7 @@ modify_filter (const char *filter_id, const char *name, const char *comment, return 4; db_type = type_db_name (type); - if (db_type && !((strcmp (db_type, "") == 0) || valid_type (db_type))) + if (db_type && !((strcmp (db_type, "") == 0) || valid_type (db_type))) { if (!valid_subtype (type)) return 3; @@ -56024,7 +56024,7 @@ tag_add_resources_list (tag_t tag, const char *type, array_t *uuids, resource_permission = g_strdup ("get_info"); else if (type_is_asset_subtype (type)) resource_permission = g_strdup ("get_assets"); - else if (type_is_report_subtype (type)) + else if (type_is_report_subtype (type)) { resource_permission = g_strdup ("get_reports"); type = g_strdup("report"); @@ -56336,7 +56336,7 @@ tag_remove_resources_filter (tag_t tag, const char *type, const char *filter) g_free (resources_get.filter); g_free (resources_get.type); if (resources_get.extra_params) - g_hash_table_destroy (resources_get.extra_params); + g_hash_table_destroy (resources_get.extra_params); return -1; } } @@ -56345,7 +56345,7 @@ tag_remove_resources_filter (tag_t tag, const char *type, const char *filter) g_free (resources_get.filter); g_free (resources_get.type); if (resources_get.extra_params) - g_hash_table_destroy (resources_get.extra_params); + g_hash_table_destroy (resources_get.extra_params); ret = 2; while (next (&resources)) @@ -56462,11 +56462,11 @@ create_tag (const char * name, const char * comment, const char * value, if (strcmp (lc_resource_type, "") && valid_db_resource_type (lc_resource_type) == 0) { - if (!valid_subtype (lc_resource_type)) + if (!valid_subtype (lc_resource_type)) { g_free (lc_resource_type); sql_rollback (); - return -1; + return -1; } } @@ -56700,7 +56700,7 @@ modify_tag (const char *tag_id, const char *name, const char *comment, if (!valid_subtype (lc_resource_type)) { sql_rollback (); - return -1; + return -1; } } @@ -57672,7 +57672,7 @@ type_extra_where (const char *type, int trash, const char *filter, usage_type = g_hash_table_lookup (extra_params, "usage_type"); else usage_type = NULL; - + extra_where = reports_extra_where (trash, filter, usage_type); } else if (strcasecmp (type, "RESULT") == 0) @@ -57809,9 +57809,9 @@ type_build_select (const char *type, const char *columns_str, original = opts_table; - lateral_clause = result_iterator_lateral (overrides, - dynamic, - "results", + lateral_clause = result_iterator_lateral (overrides, + dynamic, + "results", "nvts"); opts_table = g_strdup_printf (" LEFT OUTER JOIN result_vt_epss" diff --git a/src/manage_sql_report_configs.c b/src/manage_sql_report_configs.c index 88d8fc542..3599d3f3a 100644 --- a/src/manage_sql_report_configs.c +++ b/src/manage_sql_report_configs.c @@ -242,7 +242,7 @@ create_report_config (const char *name, const char *comment, g_free (quoted_comment); g_free (quoted_report_format_id); - for (int i = 0; g_ptr_array_index (params, i); i++) + for (int i = 0; g_ptr_array_index (params, i); i++) { report_config_param_data_t *param; param = g_ptr_array_index (params, i); @@ -266,7 +266,7 @@ create_report_config (const char *name, const char *comment, /** * @brief Modify a report config. - * + * * @param[in] report_config_id UUID of report config to modify. * @param[in] new_name Name of report config. * @param[in] new_comment Comment of report config. @@ -352,7 +352,7 @@ modify_report_config (const char *report_config_id, return 3; } - for (int i = 0; g_ptr_array_index (params, i); i++) + for (int i = 0; g_ptr_array_index (params, i); i++) { report_config_param_data_t *param; param = g_ptr_array_index (params, i); @@ -797,7 +797,7 @@ report_config_iterator_report_format_readable (iterator_t* iterator) if (iterator->done) return 0; - report_format_id + report_format_id = report_config_iterator_report_format_id (iterator); if (report_format_id) @@ -855,7 +855,7 @@ init_report_config_param_iterator (iterator_t *iterator, int trash) { report_format_t report_format; - + report_format = report_config_report_format (report_config); init_iterator (iterator, diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index 1579b3a71..becfcb4c5 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -2409,10 +2409,10 @@ report_format_param_type_min (report_format_t report_format, const char *name) /** * @brief Checks if the value of a report format param is a valid option. - * + * * @param[in] param The report format param to check. * @param[in] value The value to check. - * + * * @return 1 if the value is one of the allowed options, 0 if not. */ static int @@ -2983,7 +2983,7 @@ report_format_iterator_trust_time (iterator_t* iterator) * * @return Time report format was verified. */ -int +int report_format_iterator_configurable (iterator_t* iterator) { int ret; diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index cf13bf215..48cf21772 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -291,7 +291,7 @@ inserts_check_size (inserts_t *inserts) inserts->statements_size += inserts->statement->len; inserts->statement = NULL; inserts->current_chunk_size = 0; - + if (inserts->max_statements_size && inserts-> statements_size >= inserts->max_statements_size) { @@ -1019,7 +1019,7 @@ init_cert_bund_adv_info_iterator (iterator_t* iterator, get_data_t *get, } /** - * @brief Initialise an CERT-Bund advisory (cert_bund_adv) info iterator not + * @brief Initialise an CERT-Bund advisory (cert_bund_adv) info iterator not * limited to a name. * * @param[in] iterator Iterator. @@ -1243,7 +1243,7 @@ init_dfn_cert_adv_info_iterator (iterator_t* iterator, get_data_t *get, } /** - * @brief Initialise an DFN-CERT advisory (dfn_cert_adv) info iterator + * @brief Initialise an DFN-CERT advisory (dfn_cert_adv) info iterator * not limited to a name. * * @param[in] iterator Iterator. @@ -2389,7 +2389,7 @@ handle_json_cpe_item (inserts_t *inserts, inserts_t *deprecated_by_inserts, quoted_name, quoted_deprecated_by_id); - deprecated_by_inserts->current_chunk_size++; + deprecated_by_inserts->current_chunk_size++; g_free (quoted_deprecated_by_id); } } @@ -2473,7 +2473,7 @@ handle_json_cpe_refs (inserts_t *inserts, cJSON *product_item) type = json_object_item_string (refs_item, "type"); quoted_ref = sql_quote (ref ? ref : ""); quoted_type = sql_quote (type ? type : ""); - + first = inserts_check_size (inserts); g_string_append_printf (inserts->statement, @@ -2485,7 +2485,7 @@ handle_json_cpe_refs (inserts_t *inserts, cJSON *product_item) inserts->current_chunk_size++; g_free (quoted_ref); - g_free (quoted_type); + g_free (quoted_type); } g_free (quoted_name); @@ -3005,7 +3005,7 @@ insert_cve_products (element_t list, resource_t cve, product_element = element_next (product_element); } - + /* Add new CPEs. */ first_product = first_affected = 1; @@ -3031,7 +3031,7 @@ insert_cve_products (element_t list, resource_t cve, if (first_product == 0) { - /* Run the SQL for inserting new CPEs and add them to hashed_cpes + /* Run the SQL for inserting new CPEs and add them to hashed_cpes * so they can be looked up quickly when adding affected_products. */ iterator_t inserted_cpes; @@ -3414,7 +3414,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, resource_t id, root_id; char *config_operator; int negate; - + nodes_array = cJSON_GetObjectItemCaseSensitive (configuration_item, "nodes"); if (!cJSON_IsArray (nodes_array)) @@ -3444,7 +3444,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, g_warning ("%s: operator missing for %s.", __func__, cve_id); return -1; } - + negate = json_object_item_boolean (node_item, "negate", 0); cJSON *cpe_matches_array; @@ -3463,7 +3463,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, root_id = id; set_root_id (id, root_id); - + cJSON *cpe_match_item; cJSON_ArrayForEach (cpe_match_item, cpe_matches_array) { @@ -3505,7 +3505,7 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, g_string_append_printf (software, "%s ", cpe_matches_cpe_name (&cpe_matches)); cleanup_iterator (&cpe_matches); } - g_free (quoted_match_criteria_id); + g_free (quoted_match_criteria_id); } } } @@ -3584,7 +3584,7 @@ handle_json_cve_item (cJSON *item) } gboolean cvss_metric_found = FALSE; - + const char *cvss_metric_keys[] = { "cvssMetricV40", "cvssMetricV31", @@ -4127,7 +4127,7 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, quoted_version_start_incl = g_strdup ("NULL"); else quoted_version_start_incl = g_strdup_printf ("'%s'", ver_se); - + ver_se = json_object_item_string (match_string, "versionStartExcluding"); if (ver_se == NULL) quoted_version_start_excl = g_strdup ("NULL"); @@ -4171,7 +4171,7 @@ handle_json_cpe_match_string (inserts_t *inserts, inserts_t *matches_inserts, g_free (quoted_version_end_excl); matches_array = cJSON_GetObjectItemCaseSensitive (match_string, "matches"); - + if (cJSON_IsArray (matches_array) && cJSON_GetArraySize (matches_array) > 0) { cJSON *match_item; @@ -4339,9 +4339,9 @@ update_scap_cpe_match_strings () inserts_init (&matches_inserts, 10, setting_secinfo_sql_buffer_threshold_bytes (), - "INSERT INTO scap2.cpe_matches" + "INSERT INTO scap2.cpe_matches" " (match_criteria_id, cpe_name_id, cpe_name)" - " VALUES ", + " VALUES ", ""); gvm_json_pull_parser_next (&parser, &event); @@ -4376,7 +4376,7 @@ update_scap_cpe_match_strings () gvm_json_pull_event_cleanup (&event); gvm_json_pull_parser_cleanup (&parser); fclose (cpe_match_strings_file); - return -1; + return -1; } cJSON_Delete (cpe_match_string_item); gvm_json_pull_parser_next (&parser, &event); @@ -4447,7 +4447,7 @@ if (failure_condition) { \ /** * @brief Updates the base EPSS scores table in the SCAP database. - * + * * @return 0 success, -1 error. */ static int @@ -5311,7 +5311,7 @@ update_vt_scap_extra_data () " WHERE epss_candidates.vt_oid = nvts.oid" " AND epss_candidates.rank = 1;"); } - + /** * @brief Update CERT data that depends on SCAP. */ diff --git a/src/manage_sql_tls_certificates.c b/src/manage_sql_tls_certificates.c index e51f33eee..5fa63dcd6 100644 --- a/src/manage_sql_tls_certificates.c +++ b/src/manage_sql_tls_certificates.c @@ -1747,9 +1747,9 @@ cleanup_tls_certificate_encoding () if (g_utf8_validate (subject_dn, -1, NULL) == FALSE || g_utf8_validate (issuer_dn, -1, NULL) == FALSE) { - gchar *quoted_subject_dn + gchar *quoted_subject_dn = sql_ascii_escape_and_quote (subject_dn, NULL); - gchar *quoted_issuer_dn + gchar *quoted_issuer_dn = sql_ascii_escape_and_quote (issuer_dn, NULL); sql ("UPDATE tls_certificates" diff --git a/src/sql_pg.c b/src/sql_pg.c index cf8ed82c8..7f87cc1c9 100644 --- a/src/sql_pg.c +++ b/src/sql_pg.c @@ -607,7 +607,7 @@ sql_rollback () * * @param[in] table The table to lock. * @param[in] lock_timeout The lock timeout in milliseconds, 0 for unlimited. - * + * * @return 1 if locked, 0 if failed / timed out. */ int @@ -615,10 +615,10 @@ sql_table_lock_wait (const char *table, int lock_timeout) { int old_lock_timeout = sql_int ("SHOW lock_timeout;"); sql ("SET LOCAL lock_timeout = %d;", lock_timeout); - + // This requires the gvmd functions to be defined first. int ret = sql_int ("SELECT try_exclusive_lock_wait ('%s');", table); - + sql ("SET LOCAL lock_timeout = %d;", old_lock_timeout); return ret; } diff --git a/src/utils.c b/src/utils.c index 5db841129..32588497b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1029,7 +1029,7 @@ wait_for_pid (pid_t pid, const char *context) /** * @brief Get the available physical memory in bytes. - * + * * @return The available memory */ guint64 @@ -1041,7 +1041,7 @@ phys_mem_available () /** * @brief Get the total physical memory in bytes. - * + * * @return The total memory */ guint64 diff --git a/src/utils_tests.c b/src/utils_tests.c index ad6b8aa3f..46ff41bb4 100644 --- a/src/utils_tests.c +++ b/src/utils_tests.c @@ -109,25 +109,25 @@ Ensure (utils, gvm_sleep_sleep_for_1) assert_that (timespec_subtract (&end, &start), is_greater_than (NANOSECONDS - 1)); } -Ensure (utils, strescape_check_utf_8_no_exceptions) +Ensure (utils, strescape_check_utf_8_no_exceptions) { const char *utf8_input = "Äöü\n123\\UTF-8\x04"; const char *utf8_expected = "Äöü\\n123\\\\UTF-8\\004"; const char *cp850_input = "\x8E\x94\x81\n123\\CP850\x04"; const char *cp850_expected = "\\216\\224\\201\\n123\\\\CP850\\004"; - + assert_that (g_utf8_validate (utf8_input, -1, NULL), is_true); gchar *output = strescape_check_utf8 (utf8_input, NULL); - assert_that (output, is_equal_to_string (utf8_expected)); + assert_that (output, is_equal_to_string (utf8_expected)); g_free (output); assert_that (g_utf8_validate (cp850_input, -1, NULL), is_false); output = strescape_check_utf8 (cp850_input, NULL); - assert_that (output, is_equal_to_string (cp850_expected)); + assert_that (output, is_equal_to_string (cp850_expected)); g_free (output); } -Ensure (utils, strescape_check_utf_8_with_exceptions) +Ensure (utils, strescape_check_utf_8_with_exceptions) { const char *utf8_input = "Äöü\n123\\UTF-8\x04"; const char *utf8_expected = "Äöü\n123\\\\UTF-8\\004"; @@ -136,12 +136,12 @@ Ensure (utils, strescape_check_utf_8_with_exceptions) assert_that (g_utf8_validate (utf8_input, -1, NULL), is_true); gchar *output = strescape_check_utf8 (utf8_input, "\t\n\r"); - assert_that (output, is_equal_to_string (utf8_expected)); + assert_that (output, is_equal_to_string (utf8_expected)); g_free (output); assert_that (g_utf8_validate (cp850_input, -1, NULL), is_false); output = strescape_check_utf8 (cp850_input, "\t\n\r"); - assert_that (output, is_equal_to_string (cp850_expected)); + assert_that (output, is_equal_to_string (cp850_expected)); g_free (output); } @@ -164,7 +164,7 @@ main (int argc, char **argv) add_test_with_context (suite, utils, parse_iso_time_tz_with_z); add_test_with_context (suite, utils, parse_iso_time_tz_with_fallback_tz); add_test_with_context (suite, utils, parse_iso_time_tz_variants); - + add_test_with_context (suite, utils, strescape_check_utf_8_no_exceptions); add_test_with_context (suite, utils, strescape_check_utf_8_with_exceptions); From b3c8abf2c41106ff510878dab0550df360516a94 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 15 Nov 2024 09:52:45 +0100 Subject: [PATCH 36/64] Fix: Remove tail command from gvmd startup script. Remove tail command since messages are now logged to stderr by default --- .docker/start-gvmd.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.docker/start-gvmd.sh b/.docker/start-gvmd.sh index 7083b8f81..61bd5cf21 100644 --- a/.docker/start-gvmd.sh +++ b/.docker/start-gvmd.sh @@ -49,6 +49,4 @@ gvmd --modify-setting 78eceaec-3385-11ea-b237-28d24461215b --value "$uid" echo "starting gvmd" gvmd $GVMD_ARGS || - (cat /var/log/gvm/gvmd.log && exit 1) - -tail -f /var/log/gvm/gvmd.log + (echo "Starting gvmd failed" && exit 1) \ No newline at end of file From 4a50a7f053d84afddd90e709ecb4cda60605b038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 05:03:29 +0000 Subject: [PATCH 37/64] Bump codecov/codecov-action from 4 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 470a23bb2..c74217b0c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -64,7 +64,7 @@ jobs: - name: Configure and run tests run: CTEST_OUTPUT_ON_FAILURE=1 cmake --build build -- tests test - name: Upload test coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: file: build/coverage/coverage.xml token: ${{ secrets.CODECOV_TOKEN }} From 25d41dea4af00e72fd7759c46c76cc1d39ef728d Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Tue, 19 Nov 2024 09:54:49 +0100 Subject: [PATCH 38/64] Change: Run gvmd in foreground in the docker container. To keep the container alive after removing the tail command --- .docker/start-gvmd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.docker/start-gvmd.sh b/.docker/start-gvmd.sh index 61bd5cf21..a05ca0824 100644 --- a/.docker/start-gvmd.sh +++ b/.docker/start-gvmd.sh @@ -18,7 +18,7 @@ [ -z "$USER" ] && USER="admin" [ -z "$PASSWORD" ] && PASSWORD="admin" -[ -z "$GVMD_ARGS" ] && GVMD_ARGS="--listen-mode=666" +[ -z "$GVMD_ARGS" ] && GVMD_ARGS="-f --listen-mode=666" [ -z "$GVMD_USER" ] && GVMD_USER="gvmd" [ -z "$PGRES_DATA" ] && PGRES_DATA="/var/lib/postgresql" From a1e1df0886b6a17d6a1bc3788f6c48f94166c2b8 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 22 Nov 2024 12:25:24 +0100 Subject: [PATCH 39/64] Fix: Rollback on create_credential privkey error If the private key checks in create_credential fail, the SQL transaction is now rolled back. This fixes SQL transaction errors and possible incomplete credentials being created if there are multiple GMP commands per connection and one of them is create_credential failing because of the private key. --- src/manage_sql.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 945ae9aa0..66dafb594 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35916,7 +35916,10 @@ create_credential (const char* name, const char* comment, const char* login, if (key_private) key_private_truncated = truncate_private_key (key_private); else - return 3; + { + sql_rollback (); + return 3; + } generated_key_public = gvm_ssh_public_from_private (key_private_truncated @@ -35926,6 +35929,7 @@ create_credential (const char* name, const char* comment, const char* login, if (generated_key_public == NULL) { g_free (key_private_truncated); + sql_rollback (); return 3; } g_free (generated_key_public); From 705c6c2569b88970bcdc2af08c2f3ca25c87c39b Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Tue, 26 Nov 2024 10:12:32 +0100 Subject: [PATCH 40/64] Fix: Avoid DB check inserts in cleanup-sequences When running gvmd with the --optimize=cleanup-sequences option, the database checks during initialization will avoid most inserts. Setting database_version and max_hosts in the meta table now uses INSERT ... ON CONFLICT instead of deleting the previous entry. Skipping the inserts prevents the cleanup failing if one of the sequence has already run out of ids. The change to the meta table update reduces the risk of the meta table id sequence running out. --- src/manage.c | 9 +- src/manage.h | 2 +- src/manage_sql.c | 142 ++++++++++++++++++++++---------- src/manage_sql.h | 2 +- src/manage_sql_configs.c | 7 +- src/manage_sql_configs.h | 2 +- src/manage_sql_nvts.c | 6 +- src/manage_sql_port_lists.c | 7 +- src/manage_sql_report_formats.c | 11 ++- src/manage_sql_report_formats.h | 2 +- src/manage_sql_secinfo.c | 3 +- 11 files changed, 135 insertions(+), 58 deletions(-) diff --git a/src/manage.c b/src/manage.c index c194bae68..f9e0899c4 100644 --- a/src/manage.c +++ b/src/manage.c @@ -978,7 +978,8 @@ int manage_create_encryption_key (GSList *log_config, const db_conn_info_t *database) { - int ret = manage_option_setup (log_config, database); + int ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) { printf ("Error setting up log config or database connection."); @@ -1042,7 +1043,8 @@ manage_set_encryption_key (GSList *log_config, const db_conn_info_t *database, const char *uid) { - int ret = manage_option_setup (log_config, database); + int ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) { printf ("Error setting up log config or database connection.\n"); @@ -5707,7 +5709,8 @@ manage_rebuild_gvmd_data_from_feed (const char *types, return -1; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) { if (error_msg) diff --git a/src/manage.h b/src/manage.h index 0285d708d..8882d7a52 100644 --- a/src/manage.h +++ b/src/manage.h @@ -127,7 +127,7 @@ init_manage (GSList*, const db_conn_info_t *, int, int, int, int, manage_connection_forker_t, int); int -init_manage_helper (GSList *, const db_conn_info_t *, int); +init_manage_helper (GSList *, const db_conn_info_t *, int, int); void init_manage_process (const db_conn_info_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index 945ae9aa0..6e653b13d 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -930,13 +930,15 @@ cert_check_time () * * @param[in] log_config Log configuration. * @param[in] database Database. + * @param[in] avoid_db_check_inserts Whether to avoid inserts in DB check. * * @return 0 success, -1 error, -2 database is too old, * -3 database needs to be initialised from server, * -5 database is too new. */ int -manage_option_setup (GSList *log_config, const db_conn_info_t *database) +manage_option_setup (GSList *log_config, const db_conn_info_t *database, + int avoid_db_check_inserts) { int ret; @@ -947,7 +949,8 @@ manage_option_setup (GSList *log_config, const db_conn_info_t *database) } ret = init_manage_helper (log_config, database, - MANAGE_ABSOLUTE_MAX_IPS_PER_TARGET); + MANAGE_ABSOLUTE_MAX_IPS_PER_TARGET, + avoid_db_check_inserts); assert (ret != -4); switch (ret) { @@ -6159,10 +6162,9 @@ manage_cert_db_version () void set_db_version (int version) { - sql ("DELETE FROM %s.meta WHERE name = 'database_version';", - sql_schema ()); sql ("INSERT INTO %s.meta (name, value)" - " VALUES ('database_version', '%i');", + " VALUES ('database_version', '%i')" + " ON CONFLICT (name) DO UPDATE SET value = EXCLUDED.value;", sql_schema (), version); } @@ -6408,7 +6410,8 @@ manage_encrypt_all_credentials (GSList *log_config, g_info (" (Re-)encrypting all credentials."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -6449,7 +6452,8 @@ manage_decrypt_all_credentials (GSList *log_config, g_info (" Decrypting all credentials."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -6712,7 +6716,8 @@ manage_check_alerts (GSList *log_config, const db_conn_info_t *database) g_info (" Checking alerts."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -15835,11 +15840,16 @@ manage_update_nvti_cache () /** * @brief Ensure the predefined scanner exists. * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. + * * @return 0 if success, -1 if error. */ static int -check_db_scanners () +check_db_scanners (int avoid_db_check_inserts) { + if (avoid_db_check_inserts) + return 0; + if (sql_int ("SELECT count(*) FROM scanners WHERE uuid = '%s';", SCANNER_UUID_DEFAULT) == 0) { @@ -15868,11 +15878,16 @@ check_db_scanners () /** * @brief Initialize the default settings. * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. + * * Ensure all the default manager settings exist. */ static void -check_db_settings () +check_db_settings (int avoid_db_check_inserts) { + if (avoid_db_check_inserts) + return; + if (sql_int ("SELECT count(*) FROM settings" " WHERE uuid = '6765549a-934e-11e3-b358-406186ea4fc5'" " AND " ACL_IS_GLOBAL () ";") @@ -16219,10 +16234,15 @@ check_db_versions () /** * @brief Ensures the sanity of nvts cache in DB. + * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_nvt_selectors () +check_db_nvt_selectors (int avoid_db_check_inserts) { + if (avoid_db_check_inserts) + return; + /* Ensure every part of the predefined selector exists. * This restores entries lost due to the error solved 2010-08-13 by r8805. */ if (sql_int ("SELECT count(*) FROM nvt_selectors WHERE name =" @@ -16359,10 +16379,15 @@ add_permissions_on_globals (const gchar *role_uuid) /** * @brief Ensure the predefined permissions exists. + * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_permissions () +check_db_permissions (int avoid_db_check_inserts) { + if (avoid_db_check_inserts) + return; + command_t *command; if (sql_int ("SELECT count(*) FROM permissions" @@ -16521,10 +16546,15 @@ check_db_permissions () /** * @brief Ensure the predefined roles exists. + * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_roles () +check_db_roles (int avoid_db_check_inserts) { + if (avoid_db_check_inserts) + return; + if (sql_int ("SELECT count(*) FROM roles WHERE uuid = '" ROLE_UUID_ADMIN "';") == 0) sql ("INSERT INTO roles" @@ -16680,11 +16710,11 @@ manage_migrate_relay_sensors () * Only called by init_manage_internal, and ultimately only by the main process. * * @param[in] check_encryption_key Whether to check encryption key. - * + * @param[in] avoid_db_check_inserts Whether to avoid inserts in DB check. * @return 0 success, -1 error. */ static int -check_db (int check_encryption_key) +check_db (int check_encryption_key, int avoid_db_check_inserts) { /* The file locks managed at startup ensure that this is the only Manager * process accessing the db. Nothing else should be accessing the db, access @@ -16695,19 +16725,19 @@ check_db (int check_encryption_key) create_tables (); check_db_sequences (); set_db_version (GVMD_DATABASE_VERSION); - check_db_roles (); - check_db_nvt_selectors (); + check_db_roles (avoid_db_check_inserts); + check_db_nvt_selectors (avoid_db_check_inserts); check_db_nvts (); - check_db_port_lists (); + check_db_port_lists (avoid_db_check_inserts); clean_auth_cache (); - if (check_db_scanners ()) + if (check_db_scanners (avoid_db_check_inserts)) goto fail; - if (check_db_report_formats ()) + if (check_db_report_formats (avoid_db_check_inserts)) goto fail; if (check_db_report_formats_trash ()) goto fail; - check_db_permissions (); - check_db_settings (); + check_db_permissions (avoid_db_check_inserts); + check_db_settings (avoid_db_check_inserts); cleanup_schedule_times (); if (check_encryption_key && check_db_encryption_key ()) goto fail; @@ -16874,6 +16904,7 @@ cleanup_tables () * with GMP when an alert occurs. * @param[in] skip_db_check Skip DB check. * @param[in] check_encryption_key Check encryption key if doing DB check. + * @param[in] avoid_db_check_inserts Whether to avoid inserts in DB check. * * @return 0 success, -1 error, -2 database is too old, * -4 max_ips_per_target out of range, -5 database is too new. @@ -16888,7 +16919,8 @@ init_manage_internal (GSList *log_config, int stop_tasks, manage_connection_forker_t fork_connection, int skip_db_check, - int check_encryption_key) + int check_encryption_key, + int avoid_db_check_inserts) { int ret; @@ -16974,7 +17006,7 @@ init_manage_internal (GSList *log_config, * 2 a helper processes (--create-user, --get-users, etc) when the * main process is not running. */ - ret = check_db (check_encryption_key); + ret = check_db (check_encryption_key, avoid_db_check_inserts); if (ret) return ret; @@ -16982,8 +17014,10 @@ init_manage_internal (GSList *log_config, /* Set max_hosts in db, so database server side can access it. */ - sql ("DELETE FROM meta WHERE name = 'max_hosts';"); - sql ("INSERT INTO meta (name, value) VALUES ('max_hosts', %i);", max_hosts); + sql ("INSERT INTO meta (name, value)" + " VALUES ('max_hosts', %i)" + " ON CONFLICT (name) DO UPDATE SET value = EXCLUDED.value;", + max_hosts); } if (stop_tasks) @@ -16997,7 +17031,7 @@ init_manage_internal (GSList *log_config, if (skip_db_check == 0) /* Requires NVT cache. */ - check_db_configs (); + check_db_configs (avoid_db_check_inserts); sql_close (); gvmd_db_conn_info.name = database->name ? g_strdup (database->name) : NULL; @@ -17051,7 +17085,8 @@ init_manage (GSList *log_config, const db_conn_info_t *database, 1, /* Stop active tasks. */ fork_connection, skip_db_check, - 1); /* Check encryption key if checking db. */ + 1, /* Check encryption key if checking db. */ + 0 /* Do not avoid inserts if checking db. */); } /** @@ -17063,7 +17098,8 @@ init_manage (GSList *log_config, const db_conn_info_t *database, * * @param[in] log_config Log configuration. * @param[in] database Location of database. - * @param[in] max_ips_per_target Max number of IPs per target. + * @param[in] max_ips_per_target Max number of IPs per target. + * @param[in] avoid_db_check_inserts Whether to avoid inserts in DB check. * * @return 0 success, -1 error, -2 database is too old, -3 database needs * to be initialised from server, -4 max_ips_per_target out of range, @@ -17071,7 +17107,7 @@ init_manage (GSList *log_config, const db_conn_info_t *database, */ int init_manage_helper (GSList *log_config, const db_conn_info_t *database, - int max_ips_per_target) + int max_ips_per_target, int avoid_db_check_inserts) { return init_manage_internal (log_config, database, @@ -17088,7 +17124,8 @@ init_manage_helper (GSList *log_config, const db_conn_info_t *database, lockfile_locked ("gvm-serving") ? 1 /* Skip DB check. */ : 0, /* Do DB check. */ - 0); /* Dummy. */ + 0, /* Dummy. */ + avoid_db_check_inserts); } /** @@ -40245,7 +40282,8 @@ manage_create_scanner (GSList *log_config, const db_conn_info_t *database, g_info (" Creating scanner."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -40434,7 +40472,8 @@ manage_delete_scanner (GSList *log_config, const db_conn_info_t *database, return 3; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -40502,7 +40541,8 @@ manage_modify_scanner (GSList *log_config, const db_conn_info_t *database, g_info (" Modifying scanner."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -40721,7 +40761,8 @@ manage_verify_scanner (GSList *log_config, const db_conn_info_t *database, g_info (" Verifying scanner."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -42206,7 +42247,8 @@ manage_get_scanners (GSList *log_config, const db_conn_info_t *database) g_info (" Getting scanners."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -46145,7 +46187,8 @@ manage_get_roles (GSList *log_config, const db_conn_info_t *database, g_info (" Getting roles."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -52790,7 +52833,8 @@ manage_modify_setting (GSList *log_config, const db_conn_info_t *database, return 3; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -52944,7 +52988,8 @@ manage_create_user (GSList *log_config, const db_conn_info_t *database, g_info (" Creating user."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -53034,7 +53079,8 @@ manage_delete_user (GSList *log_config, const db_conn_info_t *database, g_info (" Deleting user."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -53099,7 +53145,8 @@ manage_get_users (GSList *log_config, const db_conn_info_t *database, g_info (" Getting users."); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -53203,7 +53250,8 @@ manage_set_password (GSList *log_config, const db_conn_info_t *database, return -1; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return ret; @@ -58214,7 +58262,15 @@ manage_optimize (GSList *log_config, const db_conn_info_t *database, return 1; } - ret = manage_option_setup (log_config, database); + int avoid_db_check_inserts = 0; + /* The optimize=cleanup-sequences option may be used if a sequence has + * already reached its maximum value, so avoid any inserts that may cause + * a sequence maximum error. * + */ + if (strcasecmp (name, "cleanup-sequences") == 0) + avoid_db_check_inserts = 1; + + ret = manage_option_setup (log_config, database, avoid_db_check_inserts); if (ret) return ret; diff --git a/src/manage_sql.h b/src/manage_sql.h index c98e15adc..d24868e61 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -448,7 +448,7 @@ void check_alerts (); int -manage_option_setup (GSList *, const db_conn_info_t *); +manage_option_setup (GSList *, const db_conn_info_t *, int); void manage_option_cleanup (); diff --git a/src/manage_sql_configs.c b/src/manage_sql_configs.c index 28e2bb10e..07e25734e 100644 --- a/src/manage_sql_configs.c +++ b/src/manage_sql_configs.c @@ -4532,12 +4532,17 @@ update_config (config_t config, const gchar *name, /** * @brief Check configs, for startup. + * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ void -check_db_configs () +check_db_configs (int avoid_db_check_inserts) { migrate_predefined_configs (); + if (avoid_db_check_inserts) + return; + if (sync_configs_with_feed (FALSE) <= -1) g_warning ("%s: Failed to sync configs with feed", __func__); diff --git a/src/manage_sql_configs.h b/src/manage_sql_configs.h index 888d4e4fb..901878423 100644 --- a/src/manage_sql_configs.h +++ b/src/manage_sql_configs.h @@ -97,7 +97,7 @@ update_config (config_t, const gchar *, const gchar *, const gchar *, int, const array_t*, const array_t*, const gchar *); void -check_db_configs (); +check_db_configs (int); void check_whole_only_in_configs (); diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 04e9cf3c8..73aab286c 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2654,7 +2654,8 @@ manage_rebuild (GSList *log_config, const db_conn_info_t *database) return -1; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) { feed_lockfile_unlock (&lockfile); @@ -2727,7 +2728,8 @@ manage_dump_vt_verification (GSList *log_config, return -1; } - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) { feed_lockfile_unlock (&lockfile); diff --git a/src/manage_sql_port_lists.c b/src/manage_sql_port_lists.c index c24abaea6..b56b9fcc2 100644 --- a/src/manage_sql_port_lists.c +++ b/src/manage_sql_port_lists.c @@ -2652,12 +2652,17 @@ update_port_list (port_list_t port_list, const gchar *name, /** * @brief Check port lists, for startup. + * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ void -check_db_port_lists () +check_db_port_lists (int avoid_db_check_inserts) { migrate_predefined_port_lists (); + if (avoid_db_check_inserts) + return; + if (sync_port_lists_with_feed (FALSE) <= -1) g_warning ("%s: Failed to sync port lists with feed", __func__); diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index becfcb4c5..0a1b49b39 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -4895,16 +4895,21 @@ check_db_trash_report_formats () /** * @brief Ensure the predefined report formats exist. * + * @param[in] avoid_db_check_inserts Whether to avoid inserts. + * * @return 0 success, -1 error. */ int -check_db_report_formats () +check_db_report_formats (int avoid_db_check_inserts) { if (migrate_predefined_report_formats ()) return -1; - if (sync_report_formats_with_feed (FALSE) <= -1) - g_warning ("%s: Failed to sync report formats with feed", __func__); + if (avoid_db_check_inserts == 0) + { + if (sync_report_formats_with_feed (FALSE) <= -1) + g_warning ("%s: Failed to sync report formats with feed", __func__); + } if (check_db_trash_report_formats ()) return -1; diff --git a/src/manage_sql_report_formats.h b/src/manage_sql_report_formats.h index 1ea556752..de7a04be2 100644 --- a/src/manage_sql_report_formats.h +++ b/src/manage_sql_report_formats.h @@ -83,7 +83,7 @@ int migrate_predefined_report_formats (); int -check_db_report_formats (); +check_db_report_formats (int); int check_db_report_formats_trash (); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 48cf21772..c80247780 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -5754,7 +5754,8 @@ manage_rebuild_scap (GSList *log_config, const db_conn_info_t *database) g_info (" Rebuilding SCAP data"); - ret = manage_option_setup (log_config, database); + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); if (ret) return -1; From 16ef4c47e64a39de8cbd7c245d827b68a8fc50f1 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Thu, 28 Nov 2024 10:09:42 +0100 Subject: [PATCH 41/64] Add: New Kerberos credential type The new type "krb5" is added to the create_credential, modify_credential and get_credentials commands. This will later be usable in scan targets for Kerberos 5 authentication. --- src/gmp.c | 67 +++++++++++++++++++++++++++ src/manage.c | 2 + src/manage.h | 10 +++- src/manage_sql.c | 77 +++++++++++++++++++++++++++---- src/schema_formats/XML/GMP.xml.in | 40 ++++++++++++++++ 5 files changed, 185 insertions(+), 11 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 2084b8a6a..231e40eaa 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -449,6 +449,7 @@ typedef struct char *certificate; ///< Certificate for client certificate auth. char *comment; ///< Comment. char *copy; ///< UUID of resource to copy. + char *kdc; ///< Kerberos KDC (key distribution centers). int key; ///< Whether the command included a key element. char *key_phrase; ///< Passphrase for key. char *key_private; ///< Private key from key. @@ -460,6 +461,7 @@ typedef struct char *auth_algorithm; ///< SNMP Authentication algorithm. char *privacy_password; ///< SNMP Privacy password. char *privacy_algorithm; ///< SNMP Privacy algorithm. + char *realm; ///< Kerberos realm. char *type; ///< Type of credential. } create_credential_data_t; @@ -475,6 +477,7 @@ create_credential_data_reset (create_credential_data_t *data) free (data->certificate); free (data->comment); free (data->copy); + free (data->kdc); free (data->key_phrase); free (data->key_private); free (data->key_public); @@ -485,6 +488,7 @@ create_credential_data_reset (create_credential_data_t *data) free (data->auth_algorithm); free (data->privacy_password); free (data->privacy_algorithm); + free (data->realm); free (data->type); memset (data, 0, sizeof (create_credential_data_t)); @@ -2515,6 +2519,7 @@ typedef struct char *comment; ///< Comment. char *community; ///< SNMP Community string. char *credential_id; ///< ID of credential to modify. + char *kdc; ///< Kerberos KDC (key distribution centers). int key; ///< Whether the command included a key element. char *key_phrase; ///< Passphrase for key. char *key_private; ///< Private key from key. @@ -2524,6 +2529,7 @@ typedef struct char *password; ///< Password associated with login name. char *privacy_algorithm; ///< SNMP Privacy algorithm. char *privacy_password; ///< SNMP Privacy password. + char *realm; ///< Kerberos realm. } modify_credential_data_t; /** @@ -2540,6 +2546,7 @@ modify_credential_data_reset (modify_credential_data_t *data) free (data->comment); free (data->community); free (data->credential_id); + free (data->kdc); free (data->key_phrase); free (data->key_private); free (data->key_public); @@ -2548,6 +2555,7 @@ modify_credential_data_reset (modify_credential_data_t *data) free (data->password); free (data->privacy_algorithm); free (data->privacy_password); + free (data->realm); memset (data, 0, sizeof (modify_credential_data_t)); } @@ -4088,6 +4096,7 @@ typedef enum CLIENT_CREATE_CREDENTIAL_COMMENT, CLIENT_CREATE_CREDENTIAL_COMMUNITY, CLIENT_CREATE_CREDENTIAL_COPY, + CLIENT_CREATE_CREDENTIAL_KDC, CLIENT_CREATE_CREDENTIAL_KEY, CLIENT_CREATE_CREDENTIAL_KEY_PHRASE, CLIENT_CREATE_CREDENTIAL_KEY_PRIVATE, @@ -4098,6 +4107,7 @@ typedef enum CLIENT_CREATE_CREDENTIAL_PRIVACY, CLIENT_CREATE_CREDENTIAL_PRIVACY_ALGORITHM, CLIENT_CREATE_CREDENTIAL_PRIVACY_PASSWORD, + CLIENT_CREATE_CREDENTIAL_REALM, CLIENT_CREATE_CREDENTIAL_TYPE, CLIENT_CREATE_FILTER, CLIENT_CREATE_FILTER_COMMENT, @@ -4420,6 +4430,7 @@ typedef enum CLIENT_MODIFY_CREDENTIAL_CERTIFICATE, CLIENT_MODIFY_CREDENTIAL_COMMENT, CLIENT_MODIFY_CREDENTIAL_COMMUNITY, + CLIENT_MODIFY_CREDENTIAL_KDC, CLIENT_MODIFY_CREDENTIAL_KEY, CLIENT_MODIFY_CREDENTIAL_KEY_PHRASE, CLIENT_MODIFY_CREDENTIAL_KEY_PRIVATE, @@ -4430,6 +4441,7 @@ typedef enum CLIENT_MODIFY_CREDENTIAL_PRIVACY, CLIENT_MODIFY_CREDENTIAL_PRIVACY_ALGORITHM, CLIENT_MODIFY_CREDENTIAL_PRIVACY_PASSWORD, + CLIENT_MODIFY_CREDENTIAL_REALM, CLIENT_MODIFY_FILTER, CLIENT_MODIFY_FILTER_COMMENT, CLIENT_MODIFY_FILTER_NAME, @@ -6283,6 +6295,10 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, gvm_append_string (&modify_credential_data->community, ""); set_client_state (CLIENT_MODIFY_CREDENTIAL_COMMUNITY); } + else if (strcasecmp ("KDC", element_name) == 0) + { + set_client_state (CLIENT_MODIFY_CREDENTIAL_KDC); + } else if (strcasecmp ("KEY", element_name) == 0) { modify_credential_data->key = 1; @@ -6302,6 +6318,10 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, gvm_append_string (&modify_credential_data->privacy_algorithm, ""); } + else if (strcasecmp ("REALM", element_name) == 0) + { + set_client_state (CLIENT_MODIFY_CREDENTIAL_REALM); + } ELSE_READ_OVER; case CLIENT_MODIFY_CREDENTIAL_KEY: @@ -6962,6 +6982,8 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_CREATE_CREDENTIAL_COMMENT); else if (strcasecmp ("COMMUNITY", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_COMMUNITY); + else if (strcasecmp ("KDC", element_name) == 0) + set_client_state (CLIENT_CREATE_CREDENTIAL_KDC); else if (strcasecmp ("KEY", element_name) == 0) { create_credential_data->key = 1; @@ -6980,6 +7002,8 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, } else if (strcasecmp ("PRIVACY", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_PRIVACY); + else if (strcasecmp ("REALM", element_name) == 0) + set_client_state (CLIENT_CREATE_CREDENTIAL_REALM); else if (strcasecmp ("TYPE", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_TYPE); ELSE_READ_OVER; @@ -12338,6 +12362,19 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) SEND_TO_CLIENT_OR_FAIL (formats_xml); g_free (formats_xml); + if (type && (strcmp (type, "krb5") == 0)) + { + const char *kdc, *realm; + kdc = credential_iterator_kdc (&credentials); + realm = credential_iterator_realm (&credentials); + + SENDF_TO_CLIENT_OR_FAIL + ("%s" + "%s", + kdc ? kdc : "", + realm ? realm : ""); + } + if (type && (strcmp (type, "snmp") == 0)) { const char *auth_algorithm, *privacy_algorithm; @@ -21333,6 +21370,8 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, create_credential_data->auth_algorithm, create_credential_data->privacy_password, create_credential_data->privacy_algorithm, + create_credential_data->kdc, + create_credential_data->realm, create_credential_data->type, create_credential_data->allow_insecure, &new_credential)) @@ -21440,6 +21479,16 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, (XML_ERROR_SYNTAX ("create_credential", "Cannot determine type for new credential")); break; + case 19: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_credential", + "Selected type requires a kdc")); + break; + case 20: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_credential", + "Selected type requires a realm")); + break; case 99: SEND_TO_CLIENT_OR_FAIL (XML_ERROR_SYNTAX ("create_credential", @@ -21462,6 +21511,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_CREDENTIAL, COMMENT); CLOSE (CLIENT_CREATE_CREDENTIAL, COMMUNITY); CLOSE (CLIENT_CREATE_CREDENTIAL, COPY); + CLOSE (CLIENT_CREATE_CREDENTIAL, KDC); CLOSE (CLIENT_CREATE_CREDENTIAL, KEY); CLOSE (CLIENT_CREATE_CREDENTIAL_KEY, PHRASE); CLOSE (CLIENT_CREATE_CREDENTIAL_KEY, PRIVATE); @@ -21472,6 +21522,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_CREDENTIAL, PRIVACY); CLOSE (CLIENT_CREATE_CREDENTIAL_PRIVACY, ALGORITHM); CLOSE (CLIENT_CREATE_CREDENTIAL_PRIVACY, PASSWORD); + CLOSE (CLIENT_CREATE_CREDENTIAL, REALM); CLOSE (CLIENT_CREATE_CREDENTIAL, TYPE); case CLIENT_CREATE_FILTER: @@ -24527,6 +24578,8 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, modify_credential_data->auth_algorithm, modify_credential_data->privacy_password, modify_credential_data->privacy_algorithm, + modify_credential_data->kdc, + modify_credential_data->realm, modify_credential_data->allow_insecure)) { case 0: @@ -24649,6 +24702,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_CREDENTIAL, CERTIFICATE); CLOSE (CLIENT_MODIFY_CREDENTIAL, COMMENT); CLOSE (CLIENT_MODIFY_CREDENTIAL, COMMUNITY); + CLOSE (CLIENT_MODIFY_CREDENTIAL, KDC); CLOSE (CLIENT_MODIFY_CREDENTIAL, KEY); CLOSE (CLIENT_MODIFY_CREDENTIAL_KEY, PHRASE); CLOSE (CLIENT_MODIFY_CREDENTIAL_KEY, PRIVATE); @@ -24659,6 +24713,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_CREDENTIAL, PRIVACY); CLOSE (CLIENT_MODIFY_CREDENTIAL_PRIVACY, ALGORITHM); CLOSE (CLIENT_MODIFY_CREDENTIAL_PRIVACY, PASSWORD); + CLOSE (CLIENT_MODIFY_CREDENTIAL, REALM); case CLIENT_MODIFY_FILTER: { @@ -27309,6 +27364,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_MODIFY_CREDENTIAL_COMMUNITY, &modify_credential_data->community); + APPEND (CLIENT_MODIFY_CREDENTIAL_KDC, + &modify_credential_data->kdc); + APPEND (CLIENT_MODIFY_CREDENTIAL_KEY_PHRASE, &modify_credential_data->key_phrase); @@ -27333,6 +27391,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_MODIFY_CREDENTIAL_PRIVACY_PASSWORD, &modify_credential_data->privacy_password); + APPEND (CLIENT_MODIFY_CREDENTIAL_REALM, + &modify_credential_data->realm); + case CLIENT_MODIFY_REPORT_CONFIG: modify_report_config_element_text (text, text_len); @@ -27440,6 +27501,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_CREATE_CREDENTIAL_COPY, &create_credential_data->copy); + APPEND (CLIENT_CREATE_CREDENTIAL_KDC, + &create_credential_data->kdc); + APPEND (CLIENT_CREATE_CREDENTIAL_KEY_PHRASE, &create_credential_data->key_phrase); @@ -27464,6 +27528,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_CREATE_CREDENTIAL_PRIVACY_PASSWORD, &create_credential_data->privacy_password); + APPEND (CLIENT_CREATE_CREDENTIAL_REALM, + &create_credential_data->realm); + APPEND (CLIENT_CREATE_CREDENTIAL_TYPE, &create_credential_data->type); diff --git a/src/manage.c b/src/manage.c index c194bae68..682124c79 100644 --- a/src/manage.c +++ b/src/manage.c @@ -4416,6 +4416,8 @@ credential_full_type (const char* abbreviation) return NULL; else if (strcasecmp (abbreviation, "cc") == 0) return "client certificate"; + else if (strcasecmp (abbreviation, "krb5") == 0) + return "Kerberos 5"; else if (strcasecmp (abbreviation, "pw") == 0) return "password only"; else if (strcasecmp (abbreviation, "snmp") == 0) diff --git a/src/manage.h b/src/manage.h index 0285d708d..ea42e6154 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2293,7 +2293,7 @@ int create_credential (const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, - const char*, credential_t*); + const char*, const char*, const char*, credential_t*); int copy_credential (const char*, const char*, const char*, @@ -2303,7 +2303,7 @@ int modify_credential (const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, - const char*); + const char*, const char*, const char*); int delete_credential (const char *, int); @@ -2344,6 +2344,12 @@ credential_iterator_privacy_password (iterator_t*); const char* credential_iterator_public_key (iterator_t*); +const char* +credential_iterator_kdc (iterator_t*); + +const char* +credential_iterator_realm (iterator_t*); + const char* credential_iterator_private_key (iterator_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index 945ae9aa0..af10ceb59 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35670,6 +35670,8 @@ validate_credential_username_for_format (const gchar *username, * @param[in] auth_algorithm SNMP authentication algorithm, or NULL. * @param[in] privacy_password SNMP privacy password. * @param[in] privacy_algorithm SNMP privacy algorithm. + * @param[in] kdc Kerberos KDC (key distribution centers). + * @param[in] realm Kerberos realm. * @param[in] given_type Credential type or NULL. * @param[in] allow_insecure Whether to allow insecure uses. * @param[out] credential Created Credential. @@ -35683,6 +35685,7 @@ validate_credential_username_for_format (const gchar *username, * 14 privacy algorithm missing, * 15 invalid auth algorithm, 16 invalid privacy algorithm, * 17 invalid certificate, 18 cannot determine type, + * 19 key distribution center missing, 20 realm missing, * 99 permission denied, -1 error. */ int @@ -35692,6 +35695,7 @@ create_credential (const char* name, const char* comment, const char* login, const char* certificate, const char* community, const char* auth_algorithm, const char* privacy_password, const char* privacy_algorithm, + const char* kdc, const char *realm, const char* given_type, const char* allow_insecure, credential_t *credential) { @@ -35738,7 +35742,8 @@ create_credential (const char* name, const char* comment, const char* login, && strcmp (given_type, "snmp") && strcmp (given_type, "smime") && strcmp (given_type, "up") - && strcmp (given_type, "usk")) + && strcmp (given_type, "usk") + && strcmp (given_type, "krb5")) { sql_rollback (); return 4; @@ -35753,6 +35758,8 @@ create_credential (const char* name, const char* comment, const char* login, quoted_type = g_strdup ("cc"); else if (login && key_private) quoted_type = g_strdup ("usk"); + else if (login && given_password && (realm || kdc)) + quoted_type = g_strdup ("krb5"); else if (login && given_password) quoted_type = g_strdup ("up"); else if (login && key_private == NULL && given_password == NULL) @@ -35773,7 +35780,8 @@ create_credential (const char* name, const char* comment, const char* login, && (strcmp (quoted_type, "cc") == 0 || strcmp (quoted_type, "pgp") == 0 || strcmp (quoted_type, "smime") == 0 - || strcmp (quoted_type, "snmp") == 0)) + || strcmp (quoted_type, "snmp") == 0 + || strcmp (quoted_type, "krb5") == 0)) ret = 10; // Type does not support autogenerate using_snmp_v3 = 0; @@ -35787,7 +35795,8 @@ create_credential (const char* name, const char* comment, const char* login, ret = 5; else if (given_password == NULL && auto_generate == 0 && (strcmp (quoted_type, "up") == 0 - || strcmp (quoted_type, "pw") == 0)) + || strcmp (quoted_type, "pw") == 0 + || strcmp (quoted_type, "krb5") == 0)) // (username) password requires a password ret = 6; else if (key_private == NULL && auto_generate == 0 @@ -35801,6 +35810,12 @@ create_credential (const char* name, const char* comment, const char* login, else if (key_public == NULL && auto_generate == 0 && strcmp (quoted_type, "pgp") == 0) ret = 9; + else if (kdc == NULL && auto_generate == 0 + && strcmp (quoted_type, "krb5") == 0) + ret = 19; + else if (realm == NULL && auto_generate == 0 + && strcmp (quoted_type, "krb5") == 0) + ret = 20; else if (strcmp (quoted_type, "snmp") == 0) { if (login || given_password || auth_algorithm @@ -35876,9 +35891,10 @@ create_credential (const char* name, const char* comment, const char* login, "username", login); } + if (kdc) + set_credential_data (new_credential, "kdc", kdc); if (key_public) set_credential_data (new_credential, "public_key", key_public); - if (certificate) { gchar *certificate_truncated; @@ -35899,6 +35915,8 @@ create_credential (const char* name, const char* comment, const char* login, if (privacy_algorithm) set_credential_data (new_credential, "privacy_algorithm", privacy_algorithm); + if (realm) + set_credential_data (new_credential, "realm", realm); g_free (quoted_type); @@ -36177,6 +36195,8 @@ copy_credential (const char* name, const char* comment, * @param[in] auth_algorithm Authentication algorithm of Credential. * @param[in] privacy_password Privacy password of Credential. * @param[in] privacy_algorithm Privacy algorithm of Credential. + * @param[in] kdc Kerberos KDC (key distribution centers). + * @param[in] realm Kerberos realm. * @param[in] allow_insecure Whether to allow insecure use. * * @return 0 success, 1 failed to find credential, 2 credential with new name @@ -36196,6 +36216,7 @@ modify_credential (const char *credential_id, const char* certificate, const char* community, const char* auth_algorithm, const char* privacy_password, const char* privacy_algorithm, + const char* kdc, const char* realm, const char* allow_insecure) { credential_t credential; @@ -36471,6 +36492,15 @@ modify_credential (const char *credential_id, { set_credential_data (credential, "secret", ""); } + else if (strcmp (type, "krb5") == 0) + { + if (password) + set_credential_password (credential, password); + if (kdc) + set_credential_data (credential, "kdc", kdc); + if (realm) + set_credential_data (credential, "realm", realm); + } else { g_warning ("%s: Unknown credential type: %s", __func__, type); @@ -36666,6 +36696,14 @@ delete_credential (const char *credential_id, int ultimate) " WHERE credential = credentials.id AND type = 'public_key')", \ NULL, \ KEYWORD_TYPE_STRING }, \ + { "(SELECT value FROM credentials_data" \ + " WHERE credential = credentials.id AND type = 'kdc')" , \ + "kdc", \ + KEYWORD_TYPE_STRING }, \ + { "(SELECT value FROM credentials_data" \ + " WHERE credential = credentials.id AND type = 'realm')", \ + "realm", \ + KEYWORD_TYPE_STRING }, \ /* private data */ \ { "(SELECT value FROM credentials_data" \ " WHERE credential = credentials.id AND type = 'secret')", \ @@ -37248,20 +37286,20 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) if (iterator->done) return NULL; - secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 7); + secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); if (type == NULL) { g_warning ("%s: NULL data type given", __func__); return NULL; } else if (strcmp (type, "password") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 8); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 10); else if (strcmp (type, "private_key") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 11); else if (strcmp (type, "community") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 10); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 12); else if (strcmp (type, "privacy_password") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 11); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 13); else { g_warning ("%s: unknown data type \"%s\"", __func__, type); @@ -37362,6 +37400,27 @@ DEF_ACCESS (credential_iterator_privacy_algorithm, DEF_ACCESS (credential_iterator_public_key, GET_ITERATOR_COLUMN_COUNT + 6); +/** + * @brief Get the key distribution center from an LSC credential iterator. + * + * @param[in] iterator Iterator. + * + * @return Key distribution center, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (credential_iterator_kdc, + GET_ITERATOR_COLUMN_COUNT + 7); + +/** + * @brief Get the realm from an LSC credential iterator. + * + * @param[in] iterator Iterator. + * + * @return Realm, or NULL if iteration is complete. Freed by cleanup_iterator. + */ +DEF_ACCESS (credential_iterator_realm, + GET_ITERATOR_COLUMN_COUNT + 8); + /** * @brief Get the password from a Credential iterator. * diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 986a61a21..5225f9350 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -3987,12 +3987,14 @@ along with this program. If not, see . copy allow_insecure certificate + kdc key login password auth_algorithm community privacy + realm type @@ -4028,6 +4030,11 @@ along with this program. If not, see . text + + kdc + text + The Kerberos KDC (key distribution center(s)) + key @@ -4114,11 +4121,17 @@ along with this program. If not, see . + + realm + text + The Kerberos realm + type The type of credential to create

cc: Client certificate

+

krb5: Kerberos 5

pgp: PGP encryption key

pw: Password only

smime: S/MIME certificate

@@ -4129,6 +4142,7 @@ along with this program. If not, see . cc + krb5 pgp pw smime @@ -10911,6 +10925,8 @@ END:VCALENDAR certificate + kdc + realm owner @@ -11037,6 +11053,7 @@ END:VCALENDAR The type of the credential

cc: Client certificate

+

krb5: Kerberos 5

pgp: PGP encryption key

pw: Password only

smime: S/MIME certificate

@@ -11047,6 +11064,7 @@ END:VCALENDAR cc + krb5 pgp pw smime @@ -11199,6 +11217,16 @@ END:VCALENDAR certificate text
+ + kdc + text + The Kerberos KDC (key distribution center(s)) + + + realm + text + The Kerberos realm +
filters @@ -26744,12 +26772,14 @@ END:VCALENDAR name allow_insecure certificate + kdc key login password community auth_algorithm privacy + realm name @@ -26777,6 +26807,11 @@ END:VCALENDAR text + + kdc + text + The Kerberos KDC (key distribution center(s)) + key @@ -26863,6 +26898,11 @@ END:VCALENDAR + + realm + text + The Kerberos realm + From 5bcc39e0b4f73a85665553a3301d0aeeea2a9cb6 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Thu, 28 Nov 2024 10:09:42 +0100 Subject: [PATCH 42/64] Add: New Kerberos credential type The new type "krb5" is added to the create_credential, modify_credential and get_credentials commands. This will later be usable in scan targets for Kerberos 5 authentication. --- src/gmp.c | 67 +++++++++++++++++++++++++++ src/manage.c | 2 + src/manage.h | 10 +++- src/manage_sql.c | 77 +++++++++++++++++++++++++++---- src/schema_formats/XML/GMP.xml.in | 40 ++++++++++++++++ 5 files changed, 185 insertions(+), 11 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 2084b8a6a..231e40eaa 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -449,6 +449,7 @@ typedef struct char *certificate; ///< Certificate for client certificate auth. char *comment; ///< Comment. char *copy; ///< UUID of resource to copy. + char *kdc; ///< Kerberos KDC (key distribution centers). int key; ///< Whether the command included a key element. char *key_phrase; ///< Passphrase for key. char *key_private; ///< Private key from key. @@ -460,6 +461,7 @@ typedef struct char *auth_algorithm; ///< SNMP Authentication algorithm. char *privacy_password; ///< SNMP Privacy password. char *privacy_algorithm; ///< SNMP Privacy algorithm. + char *realm; ///< Kerberos realm. char *type; ///< Type of credential. } create_credential_data_t; @@ -475,6 +477,7 @@ create_credential_data_reset (create_credential_data_t *data) free (data->certificate); free (data->comment); free (data->copy); + free (data->kdc); free (data->key_phrase); free (data->key_private); free (data->key_public); @@ -485,6 +488,7 @@ create_credential_data_reset (create_credential_data_t *data) free (data->auth_algorithm); free (data->privacy_password); free (data->privacy_algorithm); + free (data->realm); free (data->type); memset (data, 0, sizeof (create_credential_data_t)); @@ -2515,6 +2519,7 @@ typedef struct char *comment; ///< Comment. char *community; ///< SNMP Community string. char *credential_id; ///< ID of credential to modify. + char *kdc; ///< Kerberos KDC (key distribution centers). int key; ///< Whether the command included a key element. char *key_phrase; ///< Passphrase for key. char *key_private; ///< Private key from key. @@ -2524,6 +2529,7 @@ typedef struct char *password; ///< Password associated with login name. char *privacy_algorithm; ///< SNMP Privacy algorithm. char *privacy_password; ///< SNMP Privacy password. + char *realm; ///< Kerberos realm. } modify_credential_data_t; /** @@ -2540,6 +2546,7 @@ modify_credential_data_reset (modify_credential_data_t *data) free (data->comment); free (data->community); free (data->credential_id); + free (data->kdc); free (data->key_phrase); free (data->key_private); free (data->key_public); @@ -2548,6 +2555,7 @@ modify_credential_data_reset (modify_credential_data_t *data) free (data->password); free (data->privacy_algorithm); free (data->privacy_password); + free (data->realm); memset (data, 0, sizeof (modify_credential_data_t)); } @@ -4088,6 +4096,7 @@ typedef enum CLIENT_CREATE_CREDENTIAL_COMMENT, CLIENT_CREATE_CREDENTIAL_COMMUNITY, CLIENT_CREATE_CREDENTIAL_COPY, + CLIENT_CREATE_CREDENTIAL_KDC, CLIENT_CREATE_CREDENTIAL_KEY, CLIENT_CREATE_CREDENTIAL_KEY_PHRASE, CLIENT_CREATE_CREDENTIAL_KEY_PRIVATE, @@ -4098,6 +4107,7 @@ typedef enum CLIENT_CREATE_CREDENTIAL_PRIVACY, CLIENT_CREATE_CREDENTIAL_PRIVACY_ALGORITHM, CLIENT_CREATE_CREDENTIAL_PRIVACY_PASSWORD, + CLIENT_CREATE_CREDENTIAL_REALM, CLIENT_CREATE_CREDENTIAL_TYPE, CLIENT_CREATE_FILTER, CLIENT_CREATE_FILTER_COMMENT, @@ -4420,6 +4430,7 @@ typedef enum CLIENT_MODIFY_CREDENTIAL_CERTIFICATE, CLIENT_MODIFY_CREDENTIAL_COMMENT, CLIENT_MODIFY_CREDENTIAL_COMMUNITY, + CLIENT_MODIFY_CREDENTIAL_KDC, CLIENT_MODIFY_CREDENTIAL_KEY, CLIENT_MODIFY_CREDENTIAL_KEY_PHRASE, CLIENT_MODIFY_CREDENTIAL_KEY_PRIVATE, @@ -4430,6 +4441,7 @@ typedef enum CLIENT_MODIFY_CREDENTIAL_PRIVACY, CLIENT_MODIFY_CREDENTIAL_PRIVACY_ALGORITHM, CLIENT_MODIFY_CREDENTIAL_PRIVACY_PASSWORD, + CLIENT_MODIFY_CREDENTIAL_REALM, CLIENT_MODIFY_FILTER, CLIENT_MODIFY_FILTER_COMMENT, CLIENT_MODIFY_FILTER_NAME, @@ -6283,6 +6295,10 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, gvm_append_string (&modify_credential_data->community, ""); set_client_state (CLIENT_MODIFY_CREDENTIAL_COMMUNITY); } + else if (strcasecmp ("KDC", element_name) == 0) + { + set_client_state (CLIENT_MODIFY_CREDENTIAL_KDC); + } else if (strcasecmp ("KEY", element_name) == 0) { modify_credential_data->key = 1; @@ -6302,6 +6318,10 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, gvm_append_string (&modify_credential_data->privacy_algorithm, ""); } + else if (strcasecmp ("REALM", element_name) == 0) + { + set_client_state (CLIENT_MODIFY_CREDENTIAL_REALM); + } ELSE_READ_OVER; case CLIENT_MODIFY_CREDENTIAL_KEY: @@ -6962,6 +6982,8 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_CREATE_CREDENTIAL_COMMENT); else if (strcasecmp ("COMMUNITY", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_COMMUNITY); + else if (strcasecmp ("KDC", element_name) == 0) + set_client_state (CLIENT_CREATE_CREDENTIAL_KDC); else if (strcasecmp ("KEY", element_name) == 0) { create_credential_data->key = 1; @@ -6980,6 +7002,8 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, } else if (strcasecmp ("PRIVACY", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_PRIVACY); + else if (strcasecmp ("REALM", element_name) == 0) + set_client_state (CLIENT_CREATE_CREDENTIAL_REALM); else if (strcasecmp ("TYPE", element_name) == 0) set_client_state (CLIENT_CREATE_CREDENTIAL_TYPE); ELSE_READ_OVER; @@ -12338,6 +12362,19 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) SEND_TO_CLIENT_OR_FAIL (formats_xml); g_free (formats_xml); + if (type && (strcmp (type, "krb5") == 0)) + { + const char *kdc, *realm; + kdc = credential_iterator_kdc (&credentials); + realm = credential_iterator_realm (&credentials); + + SENDF_TO_CLIENT_OR_FAIL + ("%s" + "%s", + kdc ? kdc : "", + realm ? realm : ""); + } + if (type && (strcmp (type, "snmp") == 0)) { const char *auth_algorithm, *privacy_algorithm; @@ -21333,6 +21370,8 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, create_credential_data->auth_algorithm, create_credential_data->privacy_password, create_credential_data->privacy_algorithm, + create_credential_data->kdc, + create_credential_data->realm, create_credential_data->type, create_credential_data->allow_insecure, &new_credential)) @@ -21440,6 +21479,16 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, (XML_ERROR_SYNTAX ("create_credential", "Cannot determine type for new credential")); break; + case 19: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_credential", + "Selected type requires a kdc")); + break; + case 20: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_credential", + "Selected type requires a realm")); + break; case 99: SEND_TO_CLIENT_OR_FAIL (XML_ERROR_SYNTAX ("create_credential", @@ -21462,6 +21511,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_CREDENTIAL, COMMENT); CLOSE (CLIENT_CREATE_CREDENTIAL, COMMUNITY); CLOSE (CLIENT_CREATE_CREDENTIAL, COPY); + CLOSE (CLIENT_CREATE_CREDENTIAL, KDC); CLOSE (CLIENT_CREATE_CREDENTIAL, KEY); CLOSE (CLIENT_CREATE_CREDENTIAL_KEY, PHRASE); CLOSE (CLIENT_CREATE_CREDENTIAL_KEY, PRIVATE); @@ -21472,6 +21522,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_CREDENTIAL, PRIVACY); CLOSE (CLIENT_CREATE_CREDENTIAL_PRIVACY, ALGORITHM); CLOSE (CLIENT_CREATE_CREDENTIAL_PRIVACY, PASSWORD); + CLOSE (CLIENT_CREATE_CREDENTIAL, REALM); CLOSE (CLIENT_CREATE_CREDENTIAL, TYPE); case CLIENT_CREATE_FILTER: @@ -24527,6 +24578,8 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, modify_credential_data->auth_algorithm, modify_credential_data->privacy_password, modify_credential_data->privacy_algorithm, + modify_credential_data->kdc, + modify_credential_data->realm, modify_credential_data->allow_insecure)) { case 0: @@ -24649,6 +24702,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_CREDENTIAL, CERTIFICATE); CLOSE (CLIENT_MODIFY_CREDENTIAL, COMMENT); CLOSE (CLIENT_MODIFY_CREDENTIAL, COMMUNITY); + CLOSE (CLIENT_MODIFY_CREDENTIAL, KDC); CLOSE (CLIENT_MODIFY_CREDENTIAL, KEY); CLOSE (CLIENT_MODIFY_CREDENTIAL_KEY, PHRASE); CLOSE (CLIENT_MODIFY_CREDENTIAL_KEY, PRIVATE); @@ -24659,6 +24713,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_CREDENTIAL, PRIVACY); CLOSE (CLIENT_MODIFY_CREDENTIAL_PRIVACY, ALGORITHM); CLOSE (CLIENT_MODIFY_CREDENTIAL_PRIVACY, PASSWORD); + CLOSE (CLIENT_MODIFY_CREDENTIAL, REALM); case CLIENT_MODIFY_FILTER: { @@ -27309,6 +27364,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_MODIFY_CREDENTIAL_COMMUNITY, &modify_credential_data->community); + APPEND (CLIENT_MODIFY_CREDENTIAL_KDC, + &modify_credential_data->kdc); + APPEND (CLIENT_MODIFY_CREDENTIAL_KEY_PHRASE, &modify_credential_data->key_phrase); @@ -27333,6 +27391,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_MODIFY_CREDENTIAL_PRIVACY_PASSWORD, &modify_credential_data->privacy_password); + APPEND (CLIENT_MODIFY_CREDENTIAL_REALM, + &modify_credential_data->realm); + case CLIENT_MODIFY_REPORT_CONFIG: modify_report_config_element_text (text, text_len); @@ -27440,6 +27501,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_CREATE_CREDENTIAL_COPY, &create_credential_data->copy); + APPEND (CLIENT_CREATE_CREDENTIAL_KDC, + &create_credential_data->kdc); + APPEND (CLIENT_CREATE_CREDENTIAL_KEY_PHRASE, &create_credential_data->key_phrase); @@ -27464,6 +27528,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, APPEND (CLIENT_CREATE_CREDENTIAL_PRIVACY_PASSWORD, &create_credential_data->privacy_password); + APPEND (CLIENT_CREATE_CREDENTIAL_REALM, + &create_credential_data->realm); + APPEND (CLIENT_CREATE_CREDENTIAL_TYPE, &create_credential_data->type); diff --git a/src/manage.c b/src/manage.c index f9e0899c4..1878928ba 100644 --- a/src/manage.c +++ b/src/manage.c @@ -4418,6 +4418,8 @@ credential_full_type (const char* abbreviation) return NULL; else if (strcasecmp (abbreviation, "cc") == 0) return "client certificate"; + else if (strcasecmp (abbreviation, "krb5") == 0) + return "Kerberos 5"; else if (strcasecmp (abbreviation, "pw") == 0) return "password only"; else if (strcasecmp (abbreviation, "snmp") == 0) diff --git a/src/manage.h b/src/manage.h index 8882d7a52..b5e1711cc 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2293,7 +2293,7 @@ int create_credential (const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, - const char*, credential_t*); + const char*, const char*, const char*, credential_t*); int copy_credential (const char*, const char*, const char*, @@ -2303,7 +2303,7 @@ int modify_credential (const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, - const char*); + const char*, const char*, const char*); int delete_credential (const char *, int); @@ -2344,6 +2344,12 @@ credential_iterator_privacy_password (iterator_t*); const char* credential_iterator_public_key (iterator_t*); +const char* +credential_iterator_kdc (iterator_t*); + +const char* +credential_iterator_realm (iterator_t*); + const char* credential_iterator_private_key (iterator_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index 6e653b13d..6f2daa2b1 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35707,6 +35707,8 @@ validate_credential_username_for_format (const gchar *username, * @param[in] auth_algorithm SNMP authentication algorithm, or NULL. * @param[in] privacy_password SNMP privacy password. * @param[in] privacy_algorithm SNMP privacy algorithm. + * @param[in] kdc Kerberos KDC (key distribution centers). + * @param[in] realm Kerberos realm. * @param[in] given_type Credential type or NULL. * @param[in] allow_insecure Whether to allow insecure uses. * @param[out] credential Created Credential. @@ -35720,6 +35722,7 @@ validate_credential_username_for_format (const gchar *username, * 14 privacy algorithm missing, * 15 invalid auth algorithm, 16 invalid privacy algorithm, * 17 invalid certificate, 18 cannot determine type, + * 19 key distribution center missing, 20 realm missing, * 99 permission denied, -1 error. */ int @@ -35729,6 +35732,7 @@ create_credential (const char* name, const char* comment, const char* login, const char* certificate, const char* community, const char* auth_algorithm, const char* privacy_password, const char* privacy_algorithm, + const char* kdc, const char *realm, const char* given_type, const char* allow_insecure, credential_t *credential) { @@ -35775,7 +35779,8 @@ create_credential (const char* name, const char* comment, const char* login, && strcmp (given_type, "snmp") && strcmp (given_type, "smime") && strcmp (given_type, "up") - && strcmp (given_type, "usk")) + && strcmp (given_type, "usk") + && strcmp (given_type, "krb5")) { sql_rollback (); return 4; @@ -35790,6 +35795,8 @@ create_credential (const char* name, const char* comment, const char* login, quoted_type = g_strdup ("cc"); else if (login && key_private) quoted_type = g_strdup ("usk"); + else if (login && given_password && (realm || kdc)) + quoted_type = g_strdup ("krb5"); else if (login && given_password) quoted_type = g_strdup ("up"); else if (login && key_private == NULL && given_password == NULL) @@ -35810,7 +35817,8 @@ create_credential (const char* name, const char* comment, const char* login, && (strcmp (quoted_type, "cc") == 0 || strcmp (quoted_type, "pgp") == 0 || strcmp (quoted_type, "smime") == 0 - || strcmp (quoted_type, "snmp") == 0)) + || strcmp (quoted_type, "snmp") == 0 + || strcmp (quoted_type, "krb5") == 0)) ret = 10; // Type does not support autogenerate using_snmp_v3 = 0; @@ -35824,7 +35832,8 @@ create_credential (const char* name, const char* comment, const char* login, ret = 5; else if (given_password == NULL && auto_generate == 0 && (strcmp (quoted_type, "up") == 0 - || strcmp (quoted_type, "pw") == 0)) + || strcmp (quoted_type, "pw") == 0 + || strcmp (quoted_type, "krb5") == 0)) // (username) password requires a password ret = 6; else if (key_private == NULL && auto_generate == 0 @@ -35838,6 +35847,12 @@ create_credential (const char* name, const char* comment, const char* login, else if (key_public == NULL && auto_generate == 0 && strcmp (quoted_type, "pgp") == 0) ret = 9; + else if (kdc == NULL && auto_generate == 0 + && strcmp (quoted_type, "krb5") == 0) + ret = 19; + else if (realm == NULL && auto_generate == 0 + && strcmp (quoted_type, "krb5") == 0) + ret = 20; else if (strcmp (quoted_type, "snmp") == 0) { if (login || given_password || auth_algorithm @@ -35913,9 +35928,10 @@ create_credential (const char* name, const char* comment, const char* login, "username", login); } + if (kdc) + set_credential_data (new_credential, "kdc", kdc); if (key_public) set_credential_data (new_credential, "public_key", key_public); - if (certificate) { gchar *certificate_truncated; @@ -35936,6 +35952,8 @@ create_credential (const char* name, const char* comment, const char* login, if (privacy_algorithm) set_credential_data (new_credential, "privacy_algorithm", privacy_algorithm); + if (realm) + set_credential_data (new_credential, "realm", realm); g_free (quoted_type); @@ -36214,6 +36232,8 @@ copy_credential (const char* name, const char* comment, * @param[in] auth_algorithm Authentication algorithm of Credential. * @param[in] privacy_password Privacy password of Credential. * @param[in] privacy_algorithm Privacy algorithm of Credential. + * @param[in] kdc Kerberos KDC (key distribution centers). + * @param[in] realm Kerberos realm. * @param[in] allow_insecure Whether to allow insecure use. * * @return 0 success, 1 failed to find credential, 2 credential with new name @@ -36233,6 +36253,7 @@ modify_credential (const char *credential_id, const char* certificate, const char* community, const char* auth_algorithm, const char* privacy_password, const char* privacy_algorithm, + const char* kdc, const char* realm, const char* allow_insecure) { credential_t credential; @@ -36508,6 +36529,15 @@ modify_credential (const char *credential_id, { set_credential_data (credential, "secret", ""); } + else if (strcmp (type, "krb5") == 0) + { + if (password) + set_credential_password (credential, password); + if (kdc) + set_credential_data (credential, "kdc", kdc); + if (realm) + set_credential_data (credential, "realm", realm); + } else { g_warning ("%s: Unknown credential type: %s", __func__, type); @@ -36703,6 +36733,14 @@ delete_credential (const char *credential_id, int ultimate) " WHERE credential = credentials.id AND type = 'public_key')", \ NULL, \ KEYWORD_TYPE_STRING }, \ + { "(SELECT value FROM credentials_data" \ + " WHERE credential = credentials.id AND type = 'kdc')" , \ + "kdc", \ + KEYWORD_TYPE_STRING }, \ + { "(SELECT value FROM credentials_data" \ + " WHERE credential = credentials.id AND type = 'realm')", \ + "realm", \ + KEYWORD_TYPE_STRING }, \ /* private data */ \ { "(SELECT value FROM credentials_data" \ " WHERE credential = credentials.id AND type = 'secret')", \ @@ -37285,20 +37323,20 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) if (iterator->done) return NULL; - secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 7); + secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); if (type == NULL) { g_warning ("%s: NULL data type given", __func__); return NULL; } else if (strcmp (type, "password") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 8); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 10); else if (strcmp (type, "private_key") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 11); else if (strcmp (type, "community") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 10); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 12); else if (strcmp (type, "privacy_password") == 0) - unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 11); + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 13); else { g_warning ("%s: unknown data type \"%s\"", __func__, type); @@ -37399,6 +37437,27 @@ DEF_ACCESS (credential_iterator_privacy_algorithm, DEF_ACCESS (credential_iterator_public_key, GET_ITERATOR_COLUMN_COUNT + 6); +/** + * @brief Get the key distribution center from an LSC credential iterator. + * + * @param[in] iterator Iterator. + * + * @return Key distribution center, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (credential_iterator_kdc, + GET_ITERATOR_COLUMN_COUNT + 7); + +/** + * @brief Get the realm from an LSC credential iterator. + * + * @param[in] iterator Iterator. + * + * @return Realm, or NULL if iteration is complete. Freed by cleanup_iterator. + */ +DEF_ACCESS (credential_iterator_realm, + GET_ITERATOR_COLUMN_COUNT + 8); + /** * @brief Get the password from a Credential iterator. * diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 986a61a21..5225f9350 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -3987,12 +3987,14 @@ along with this program. If not, see . copy allow_insecure certificate + kdc key login password auth_algorithm community privacy + realm type @@ -4028,6 +4030,11 @@ along with this program. If not, see . text + + kdc + text + The Kerberos KDC (key distribution center(s)) + key @@ -4114,11 +4121,17 @@ along with this program. If not, see . + + realm + text + The Kerberos realm + type The type of credential to create

cc: Client certificate

+

krb5: Kerberos 5

pgp: PGP encryption key

pw: Password only

smime: S/MIME certificate

@@ -4129,6 +4142,7 @@ along with this program. If not, see . cc + krb5 pgp pw smime @@ -10911,6 +10925,8 @@ END:VCALENDAR certificate + kdc + realm owner @@ -11037,6 +11053,7 @@ END:VCALENDAR The type of the credential

cc: Client certificate

+

krb5: Kerberos 5

pgp: PGP encryption key

pw: Password only

smime: S/MIME certificate

@@ -11047,6 +11064,7 @@ END:VCALENDAR cc + krb5 pgp pw smime @@ -11199,6 +11217,16 @@ END:VCALENDAR certificate text
+ + kdc + text + The Kerberos KDC (key distribution center(s)) + + + realm + text + The Kerberos realm +
filters @@ -26744,12 +26772,14 @@ END:VCALENDAR name allow_insecure certificate + kdc key login password community auth_algorithm privacy + realm name @@ -26777,6 +26807,11 @@ END:VCALENDAR text + + kdc + text + The Kerberos KDC (key distribution center(s)) + key @@ -26863,6 +26898,11 @@ END:VCALENDAR + + realm + text + The Kerberos realm + From 5c0d5fa8887acea08473cb623de322991ad12b1e Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 29 Nov 2024 09:38:41 +0100 Subject: [PATCH 43/64] Fix prototype and simplify check_db_... functions The new parameter has been added to the check_db_port_lists prototype and various check_db_... functions that would only return if the avoid_db_check_inserts parameter is true have the parameter removed and are instead wrapped in if conditions. --- src/manage_sql.c | 57 +++++++++++++------------------------ src/manage_sql_port_lists.h | 2 +- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 6f2daa2b1..d79371261 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -15840,16 +15840,11 @@ manage_update_nvti_cache () /** * @brief Ensure the predefined scanner exists. * - * @param[in] avoid_db_check_inserts Whether to avoid inserts. - * * @return 0 if success, -1 if error. */ static int -check_db_scanners (int avoid_db_check_inserts) +check_db_scanners () { - if (avoid_db_check_inserts) - return 0; - if (sql_int ("SELECT count(*) FROM scanners WHERE uuid = '%s';", SCANNER_UUID_DEFAULT) == 0) { @@ -15878,16 +15873,11 @@ check_db_scanners (int avoid_db_check_inserts) /** * @brief Initialize the default settings. * - * @param[in] avoid_db_check_inserts Whether to avoid inserts. - * * Ensure all the default manager settings exist. */ static void -check_db_settings (int avoid_db_check_inserts) +check_db_settings () { - if (avoid_db_check_inserts) - return; - if (sql_int ("SELECT count(*) FROM settings" " WHERE uuid = '6765549a-934e-11e3-b358-406186ea4fc5'" " AND " ACL_IS_GLOBAL () ";") @@ -16234,15 +16224,10 @@ check_db_versions () /** * @brief Ensures the sanity of nvts cache in DB. - * - * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_nvt_selectors (int avoid_db_check_inserts) +check_db_nvt_selectors () { - if (avoid_db_check_inserts) - return; - /* Ensure every part of the predefined selector exists. * This restores entries lost due to the error solved 2010-08-13 by r8805. */ if (sql_int ("SELECT count(*) FROM nvt_selectors WHERE name =" @@ -16379,15 +16364,10 @@ add_permissions_on_globals (const gchar *role_uuid) /** * @brief Ensure the predefined permissions exists. - * - * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_permissions (int avoid_db_check_inserts) +check_db_permissions () { - if (avoid_db_check_inserts) - return; - command_t *command; if (sql_int ("SELECT count(*) FROM permissions" @@ -16546,15 +16526,10 @@ check_db_permissions (int avoid_db_check_inserts) /** * @brief Ensure the predefined roles exists. - * - * @param[in] avoid_db_check_inserts Whether to avoid inserts. */ static void -check_db_roles (int avoid_db_check_inserts) +check_db_roles () { - if (avoid_db_check_inserts) - return; - if (sql_int ("SELECT count(*) FROM roles WHERE uuid = '" ROLE_UUID_ADMIN "';") == 0) sql ("INSERT INTO roles" @@ -16725,19 +16700,25 @@ check_db (int check_encryption_key, int avoid_db_check_inserts) create_tables (); check_db_sequences (); set_db_version (GVMD_DATABASE_VERSION); - check_db_roles (avoid_db_check_inserts); - check_db_nvt_selectors (avoid_db_check_inserts); + if (avoid_db_check_inserts == 0) + { + check_db_roles (); + check_db_nvt_selectors (); + } check_db_nvts (); check_db_port_lists (avoid_db_check_inserts); clean_auth_cache (); - if (check_db_scanners (avoid_db_check_inserts)) + if (avoid_db_check_inserts == 0 && check_db_scanners ()) goto fail; if (check_db_report_formats (avoid_db_check_inserts)) goto fail; if (check_db_report_formats_trash ()) goto fail; - check_db_permissions (avoid_db_check_inserts); - check_db_settings (avoid_db_check_inserts); + if (avoid_db_check_inserts == 0) + { + check_db_permissions (); + check_db_settings (); + } cleanup_schedule_times (); if (check_encryption_key && check_db_encryption_key ()) goto fail; @@ -17086,7 +17067,7 @@ init_manage (GSList *log_config, const db_conn_info_t *database, fork_connection, skip_db_check, 1, /* Check encryption key if checking db. */ - 0 /* Do not avoid inserts if checking db. */); + 0 /* Do not avoid inserts if checking db. */); } /** @@ -17125,7 +17106,7 @@ init_manage_helper (GSList *log_config, const db_conn_info_t *database, ? 1 /* Skip DB check. */ : 0, /* Do DB check. */ 0, /* Dummy. */ - avoid_db_check_inserts); + avoid_db_check_inserts); } /** @@ -58328,7 +58309,7 @@ manage_optimize (GSList *log_config, const db_conn_info_t *database, */ if (strcasecmp (name, "cleanup-sequences") == 0) avoid_db_check_inserts = 1; - + ret = manage_option_setup (log_config, database, avoid_db_check_inserts); if (ret) return ret; diff --git a/src/manage_sql_port_lists.h b/src/manage_sql_port_lists.h index 9d20c199c..0539cf253 100644 --- a/src/manage_sql_port_lists.h +++ b/src/manage_sql_port_lists.h @@ -74,6 +74,6 @@ update_port_list (port_list_t, const gchar *, const gchar *, array_t *, const gchar *); void -check_db_port_lists (); +check_db_port_lists (int); #endif /* not _GVMD_MANAGE_SQL_PORT_LISTS_H */ From b34dbadd8825a9c1a5a5b94688253df1c8805fb3 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 2 Dec 2024 11:58:03 +0100 Subject: [PATCH 44/64] Add: Kerberos credential for targets Targets now have the krb5_credential element that can be used to pass Kerberos 5 credentials to the scanner for authenticated scans. This allows scans of Windows systems that no longer allow the old SMB authentication method. --- src/gmp.c | 135 ++++++++++++++++++++++++++- src/manage.c | 61 ++++++++++++- src/manage.h | 11 ++- src/manage_sql.c | 146 +++++++++++++++++++++++++++++- src/manage_sql.h | 1 + src/schema_formats/XML/GMP.xml.in | 68 +++++++++++++- 6 files changed, 413 insertions(+), 9 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 231e40eaa..696d84510 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -950,6 +950,7 @@ typedef struct char *esxi_credential_id; ///< ESXi credential for new target. char *esxi_lsc_credential_id; ///< ESXi credential (deprecated). char *snmp_credential_id; ///< SNMP credential for new target. + char *krb5_credential_id; ///< Kerberos 5 credential for new target. char *name; ///< Name of new target. } create_target_data_t; @@ -982,6 +983,7 @@ create_target_data_reset (create_target_data_t *data) free (data->esxi_credential_id); free (data->esxi_lsc_credential_id); free (data->snmp_credential_id); + free (data->krb5_credential_id); free (data->name); memset (data, 0, sizeof (create_target_data_t)); @@ -2883,6 +2885,7 @@ typedef struct char *esxi_credential_id; ///< ESXi credential for target. char *esxi_lsc_credential_id; ///< ESXi credential for target (deprecated). char *snmp_credential_id; ///< SNMP credential for target. + char *krb5_credential_id; ///< Kerberos 5 credential for target. char *target_id; ///< Target UUID. } modify_target_data_t; @@ -2913,6 +2916,7 @@ modify_target_data_reset (modify_target_data_t *data) free (data->esxi_credential_id); free (data->esxi_lsc_credential_id); free (data->snmp_credential_id); + free (data->krb5_credential_id); free (data->target_id); memset (data, 0, sizeof (modify_target_data_t)); @@ -4295,6 +4299,7 @@ typedef enum CLIENT_CREATE_TARGET_NAME, CLIENT_CREATE_TARGET_PORT_LIST, CLIENT_CREATE_TARGET_PORT_RANGE, + CLIENT_CREATE_TARGET_KRB5_CREDENTIAL, CLIENT_CREATE_TARGET_SMB_CREDENTIAL, CLIENT_CREATE_TARGET_SNMP_CREDENTIAL, CLIENT_CREATE_TARGET_SSH_CREDENTIAL, @@ -4532,6 +4537,7 @@ typedef enum CLIENT_MODIFY_TARGET_REVERSE_LOOKUP_UNIFY, CLIENT_MODIFY_TARGET_NAME, CLIENT_MODIFY_TARGET_PORT_LIST, + CLIENT_MODIFY_TARGET_KRB5_CREDENTIAL, CLIENT_MODIFY_TARGET_SMB_CREDENTIAL, CLIENT_MODIFY_TARGET_SNMP_CREDENTIAL, CLIENT_MODIFY_TARGET_SSH_CREDENTIAL, @@ -6636,6 +6642,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, &modify_target_data->port_list_id); set_client_state (CLIENT_MODIFY_TARGET_PORT_LIST); } + else if (strcasecmp ("KRB5_CREDENTIAL", element_name) == 0) + { + append_attribute (attribute_names, attribute_values, "id", + &modify_target_data->krb5_credential_id); + set_client_state (CLIENT_MODIFY_TARGET_KRB5_CREDENTIAL); + } else if (strcasecmp ("SSH_CREDENTIAL", element_name) == 0) { append_attribute (attribute_names, attribute_values, "id", @@ -7647,6 +7659,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, gvm_append_string (&create_target_data->port_range, ""); set_client_state (CLIENT_CREATE_TARGET_PORT_RANGE); } + else if (strcasecmp ("KRB5_CREDENTIAL", element_name) == 0) + { + append_attribute (attribute_names, attribute_values, "id", + &create_target_data->krb5_credential_id); + set_client_state (CLIENT_CREATE_TARGET_KRB5_CREDENTIAL); + } else if (strcasecmp ("SSH_CREDENTIAL", element_name) == 0) { append_attribute (attribute_names, attribute_values, "id", @@ -17862,18 +17880,20 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error) char *ssh_name, *ssh_uuid, *smb_name, *smb_uuid; char *esxi_name, *esxi_uuid, *snmp_name, *snmp_uuid; char *ssh_elevate_name, *ssh_elevate_uuid; + char *krb5_name, *krb5_uuid; const char *port_list_uuid, *port_list_name, *ssh_port; const char *hosts, *exclude_hosts, *reverse_lookup_only; const char *reverse_lookup_unify, *allow_simultaneous_ips; credential_t ssh_credential, smb_credential; credential_t esxi_credential, snmp_credential; - credential_t ssh_elevate_credential; + credential_t ssh_elevate_credential, krb5_credential; int port_list_trash, max_hosts, port_list_available; int ssh_credential_available; int smb_credential_available; int esxi_credential_available; int snmp_credential_available; int ssh_elevate_credential_available; + int krb5_credential_available; ret = get_next (&targets, &get_targets_data->get, &first, &count, init_target_iterator); @@ -17891,6 +17911,7 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error) snmp_credential = target_iterator_snmp_credential (&targets); ssh_elevate_credential = target_iterator_ssh_elevate_credential (&targets); + krb5_credential = target_iterator_krb5_credential (&targets); ssh_credential_available = 1; if (ssh_credential) @@ -18048,6 +18069,38 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error) ssh_elevate_uuid = NULL; } + krb5_credential_available = 1; + if (krb5_credential) + { + if (get_targets_data->get.trash + && target_iterator_krb5_trash (&targets)) + { + krb5_name + = trash_credential_name (krb5_credential); + krb5_uuid + = trash_credential_uuid (krb5_credential); + krb5_credential_available + = trash_credential_readable (krb5_credential); + } + else + { + credential_t found; + + krb5_name = credential_name (krb5_credential); + krb5_uuid = credential_uuid (krb5_credential); + if (find_credential_with_permission (krb5_uuid, + &found, + "get_credentials")) + abort (); + krb5_credential_available = (found > 0); + } + } + else + { + krb5_name = NULL; + krb5_uuid = NULL; + } + port_list_uuid = target_iterator_port_list_uuid (&targets); port_list_name = target_iterator_port_list_name (&targets); port_list_trash = target_iterator_port_list_trash (&targets); @@ -18158,6 +18211,18 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error) SEND_TO_CLIENT_OR_FAIL (""); SENDF_TO_CLIENT_OR_FAIL ("" + "" + "%s" + "%i", + krb5_uuid ? krb5_uuid : "", + krb5_name ? krb5_name : "", + (get_targets_data->get.trash + && target_iterator_krb5_trash (&targets))); + + if (krb5_credential_available == 0) + SEND_TO_CLIENT_OR_FAIL (""); + + SENDF_TO_CLIENT_OR_FAIL ("" "" "%s" "" @@ -18215,6 +18280,8 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error) free (esxi_uuid); free (ssh_elevate_name); free (ssh_elevate_uuid); + free (krb5_name); + free (krb5_uuid); } cleanup_iterator (&targets); filtered = get_targets_data->get.id @@ -22963,6 +23030,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, credential_t ssh_credential = 0, ssh_elevate_credential = 0; credential_t smb_credential = 0; credential_t esxi_credential = 0, snmp_credential = 0; + credential_t krb5_credential = 0; target_t new_target; if (create_target_data->copy) @@ -23139,6 +23207,31 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, return; } } + else if (create_target_data->krb5_credential_id + && find_credential_with_permission + (create_target_data->krb5_credential_id, + &krb5_credential, + "get_credentials")) + SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("create_target")); + else if (create_target_data->krb5_credential_id + && krb5_credential == 0) + { + if (send_find_error_to_client + ("create_target", "Credential", + create_target_data->snmp_credential_id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + } + else if (create_target_data->smb_credential_id + && create_target_data->krb5_credential_id) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_target", + "Targets cannot have both an SMB and" + " Kerberos 5 credential")); + /* Create target from host string. */ else switch (create_target (create_target_data->name, @@ -23156,6 +23249,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, smb_credential, esxi_credential, snmp_credential, + krb5_credential, create_target_data->reverse_lookup_only, create_target_data->reverse_lookup_unify, create_target_data->alive_tests, @@ -23265,6 +23359,13 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, " different from the SSH credential")); log_event_fail ("target", "Target", NULL, "created"); break; + case 16: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_target", + "Kerberos 5 credential must be of type" + " 'krb5'")); + log_event_fail ("target", "Target", NULL, "created"); + break; case 99: SEND_TO_CLIENT_OR_FAIL (XML_ERROR_SYNTAX ("create_target", @@ -23304,6 +23405,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_TARGET, NAME); CLOSE (CLIENT_CREATE_TARGET, PORT_LIST); CLOSE (CLIENT_CREATE_TARGET, PORT_RANGE); + CLOSE (CLIENT_CREATE_TARGET, KRB5_CREDENTIAL); CLOSE (CLIENT_CREATE_TARGET, SSH_CREDENTIAL); CLOSE (CLIENT_CREATE_TARGET, SSH_LSC_CREDENTIAL); CLOSE (CLIENT_CREATE_TARGET, SSH_ELEVATE_CREDENTIAL); @@ -25763,6 +25865,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, ? modify_target_data->esxi_credential_id : modify_target_data->esxi_lsc_credential_id, modify_target_data->snmp_credential_id, + modify_target_data->krb5_credential_id, modify_target_data->reverse_lookup_only, modify_target_data->reverse_lookup_unify, modify_target_data->alive_tests, @@ -26012,6 +26115,35 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, log_event_fail ("target", "Target", modify_target_data->target_id, "modified"); break; + case 26: + log_event_fail ("target", "Target", + modify_target_data->target_id, + "modified"); + if (send_find_error_to_client + ("modify_target", "Credential", + modify_target_data->krb5_credential_id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + break; + case 27: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_target", + "Kerberos 5 credential must be of type" + " 'krb5'")); + log_event_fail ("target", "Target", + modify_target_data->target_id, "modified"); + break; + case 28: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_target", + "Targets cannot have both an SMB and" + " Kerberos 5 credential")); + log_event_fail ("target", "Target", + modify_target_data->target_id, "modified"); + break; case 99: SEND_TO_CLIENT_OR_FAIL (XML_ERROR_SYNTAX ("modify_target", @@ -26051,6 +26183,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_TARGET, HOSTS); CLOSE (CLIENT_MODIFY_TARGET, NAME); CLOSE (CLIENT_MODIFY_TARGET, PORT_LIST); + CLOSE (CLIENT_MODIFY_TARGET, KRB5_CREDENTIAL); CLOSE (CLIENT_MODIFY_TARGET, SSH_CREDENTIAL); CLOSE (CLIENT_MODIFY_TARGET, SSH_LSC_CREDENTIAL); CLOSE (CLIENT_MODIFY_TARGET, SSH_ELEVATE_CREDENTIAL); diff --git a/src/manage.c b/src/manage.c index 1878928ba..72458dbb1 100644 --- a/src/manage.c +++ b/src/manage.c @@ -2396,6 +2396,61 @@ target_osp_snmp_credential (target_t target) return NULL; } +/** + * @brief Get the Kerberos 5 credential of a target as an osp_credential_t + * + * @param[in] target The target to get the credential from. + * + * @return Pointer to a newly allocated osp_credential_t + */ +static osp_credential_t * +target_osp_krb5_credential (target_t target) +{ + credential_t credential; + credential = target_credential (target, "krb5"); + if (credential) + { + iterator_t iter; + osp_credential_t *osp_credential; + + init_credential_iterator_one (&iter, credential); + if (!next (&iter)) + { + g_warning ("%s: Kerberos 5 Credential not found.", __func__); + cleanup_iterator (&iter); + return NULL; + } + if (strcmp (credential_iterator_type (&iter), "krb5")) + { + g_warning ("%s: Kerberos 5 Credential not of type 'krb5'.", + __func__); + cleanup_iterator (&iter); + return NULL; + } + + osp_credential = osp_credential_new ("up", "krb5", NULL); + osp_credential_set_auth_data (osp_credential, + "username", + credential_iterator_login (&iter) + ?: ""); + osp_credential_set_auth_data (osp_credential, + "password", + credential_iterator_password (&iter) + ?: ""); + osp_credential_set_auth_data (osp_credential, + "kdc", + credential_iterator_kdc (&iter) + ?: ""); + osp_credential_set_auth_data (osp_credential, + "realm", + credential_iterator_realm (&iter) + ?: ""); + cleanup_iterator (&iter); + return osp_credential; + } + return NULL; +} + /** * @brief Prepare a report for resuming an OSP scan * @@ -2571,7 +2626,7 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id, GSList *osp_targets, *vts; GHashTable *vts_hash_table; osp_credential_t *ssh_credential, *smb_credential, *esxi_credential; - osp_credential_t *snmp_credential; + osp_credential_t *snmp_credential, *krb5_credential; gchar *max_checks, *max_hosts, *hosts_ordering; GHashTable *scanner_options; int ret, empty; @@ -2663,6 +2718,10 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id, if (snmp_credential) osp_target_add_credential (osp_target, snmp_credential); + krb5_credential = target_osp_krb5_credential (target); + if (krb5_credential) + osp_target_add_credential (osp_target, krb5_credential); + /* Initialize vts table for vulnerability tests and their preferences */ vts = NULL; vts_hash_table diff --git a/src/manage.h b/src/manage.h index b5e1711cc..b7d7a3cee 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1826,7 +1826,8 @@ find_target_with_permission (const char *, target_t *, const char *); int create_target (const char*, const char*, const char*, const char*, const char*, const char *, const char*, credential_t, credential_t, - const char *, credential_t, credential_t, credential_t, + const char *, + credential_t, credential_t, credential_t, credential_t, const char *, const char *, const char *, const char *, target_t*); @@ -1837,7 +1838,7 @@ int modify_target (const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, - const char*); + const char*, const char*); int delete_target (const char*, int); @@ -1887,6 +1888,9 @@ target_iterator_snmp_credential (iterator_t*); int target_iterator_ssh_elevate_credential (iterator_t*); +int +target_iterator_krb5_credential (iterator_t*); + int target_iterator_ssh_trash (iterator_t*); @@ -1902,6 +1906,9 @@ target_iterator_snmp_trash (iterator_t*); int target_iterator_ssh_elevate_trash (iterator_t*); +int +target_iterator_krb5_trash (iterator_t*); + const char* target_iterator_allow_simultaneous_ips (iterator_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index d79371261..bf6c98f07 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -32663,6 +32663,8 @@ target_login_port (target_t target, const char* type) * 10 invalid SMB credential type, 11 invalid ESXi credential type, * 12 invalid SNMP credential type, 13 port range or port list required, * 14 SSH elevate credential without an SSH credential, + * 15 elevate credential must be different from the SSH credential, + * 16 invalid Kerberos 5 credential type, * 99 permission denied, -1 error. */ int @@ -32673,6 +32675,7 @@ create_target (const char* name, const char* asset_hosts_filter, credential_t ssh_elevate_credential, const char* ssh_port, credential_t smb_credential, credential_t esxi_credential, credential_t snmp_credential, + credential_t krb5_credential, const char *reverse_lookup_only, const char *reverse_lookup_unify, const char *alive_tests, const char *allow_simultaneous_ips, @@ -32937,6 +32940,22 @@ create_target (const char* name, const char* asset_hosts_filter, new_target, snmp_credential, "0"); } + if (krb5_credential) + { + gchar *type = credential_type (krb5_credential); + if (strcmp (type, "krb5")) + { + sql_rollback (); + return 16; + } + g_free (type); + + sql ("INSERT INTO targets_login_data" + " (target, type, credential, port)" + " VALUES (%llu, 'krb5', %llu, %s);", + new_target, krb5_credential, "0"); + } + sql_commit (); return 0; @@ -33134,6 +33153,7 @@ delete_target (const char *target_id, int ultimate) * @param[in] smb_credential_id SMB credential. * @param[in] esxi_credential_id ESXi credential. * @param[in] snmp_credential_id SNMP credential. + * @param[in] krb5_credential_id Kerberos 5 credential. * @param[in] reverse_lookup_only Scanner preference reverse_lookup_only. * @param[in] reverse_lookup_unify Scanner preference reverse_lookup_unify. * @param[in] alive_tests Alive tests. @@ -33152,6 +33172,9 @@ delete_target (const char *target_id, int ultimate) * 22 failed to find SSH elevate cred, 23 invalid SSH elevate * credential type, 24 SSH elevate credential without SSH credential, * 25 SSH elevate credential equals SSH credential, + * 26 failed to find Kerberos 5 credential, + * 27 invalid Kerberos 5 credential type, + * 28 cannot use both SMB and Kerberos 5 credential, * 99 permission denied, -1 error. */ int @@ -33161,6 +33184,7 @@ modify_target (const char *target_id, const char *name, const char *hosts, const char *ssh_elevate_credential_id, const char *ssh_port, const char *smb_credential_id, const char *esxi_credential_id, const char* snmp_credential_id, + const char *krb5_credential_id, const char *reverse_lookup_only, const char *reverse_lookup_unify, const char *alive_tests, const char *allow_simultaneous_ips) @@ -33168,6 +33192,8 @@ modify_target (const char *target_id, const char *name, const char *hosts, target_t target; credential_t ssh_credential = 0; credential_t ssh_elevate_credential = 0; + credential_t smb_credential; + credential_t krb5_credential; assert (target_id); @@ -33401,8 +33427,6 @@ modify_target (const char *target_id, const char *name, const char *hosts, if (smb_credential_id) { - credential_t smb_credential; - if (target_in_use (target)) { sql_rollback (); @@ -33440,6 +33464,8 @@ modify_target (const char *target_id, const char *name, const char *hosts, else set_target_login_data (target, "smb", 0, 0); } + else + smb_credential = target_smb_credential (target); if (esxi_credential_id) { @@ -33544,6 +33570,54 @@ modify_target (const char *target_id, const char *name, const char *hosts, } } + if (krb5_credential_id) + { + if (target_in_use (target)) + { + sql_rollback (); + return 15; + } + + krb5_credential = 0; + if (strcmp (krb5_credential_id, "0")) + { + gchar *type; + if (find_credential_with_permission (krb5_credential_id, + &krb5_credential, + "get_credentials")) + { + sql_rollback (); + return -1; + } + + if (krb5_credential == 0) + { + sql_rollback (); + return 26; + } + + type = credential_type (krb5_credential); + if (strcmp (type, "krb5")) + { + sql_rollback (); + return 27; + } + g_free (type); + + set_target_login_data (target, "krb5", krb5_credential, 0); + } + else + set_target_login_data (target, "krb5", 0, 0); + } + else + krb5_credential = target_krb5_credential (target); + + if (smb_credential && krb5_credential) + { + sql_rollback (); + return 28; + } + if (exclude_hosts) { gchar *quoted_exclude_hosts, *quoted_hosts, *clean, *clean_exclude; @@ -33707,6 +33781,12 @@ modify_target (const char *target_id, const char *name, const char *hosts, NULL, \ KEYWORD_TYPE_INTEGER }, \ { "0", NULL, KEYWORD_TYPE_INTEGER }, \ + { "(SELECT credential FROM targets_login_data" \ + " WHERE target = targets.id" \ + " AND type = CAST ('krb5' AS text))", \ + NULL, \ + KEYWORD_TYPE_INTEGER }, \ + { "0", NULL, KEYWORD_TYPE_INTEGER }, \ { "allow_simultaneous_ips", \ NULL, \ KEYWORD_TYPE_INTEGER }, \ @@ -33755,6 +33835,15 @@ modify_target (const char *target_id, const char *name, const char *hosts, "ssh_elevate_credential", \ KEYWORD_TYPE_STRING \ }, \ + { \ + "(SELECT name FROM credentials" \ + " WHERE credentials.id" \ + " = (SELECT credential FROM targets_login_data" \ + " WHERE target = targets.id" \ + " AND type = CAST ('krb5' AS text)))", \ + "krb5_credential", \ + KEYWORD_TYPE_STRING \ + }, \ { "hosts", NULL, KEYWORD_TYPE_STRING }, \ { "max_hosts (hosts, exclude_hosts)", \ "ips", \ @@ -33832,6 +33921,12 @@ modify_target (const char *target_id, const char *name, const char *hosts, { "trash_target_credential_location (id, CAST ('elevate' AS text))", \ NULL, \ KEYWORD_TYPE_INTEGER }, \ + { "target_credential (id, 1, CAST ('krb5' AS text))", \ + NULL, \ + KEYWORD_TYPE_INTEGER }, \ + { "trash_target_credential_location (id, CAST ('krb5' AS text))", \ + NULL, \ + KEYWORD_TYPE_INTEGER }, \ { "allow_simultaneous_ips", \ NULL, \ KEYWORD_TYPE_INTEGER }, \ @@ -34186,6 +34281,38 @@ target_iterator_ssh_elevate_trash (iterator_t* iterator) return ret; } +/** + * @brief Get the Kerberos 5 LSC credential from a target iterator. + * + * @param[in] iterator Iterator. + * + * @return Kerberos 5 LSC credential. + */ +int +target_iterator_krb5_credential (iterator_t* iterator) +{ + int ret; + if (iterator->done) return -1; + ret = iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 20); + return ret; +} + +/** + * @brief Get the Kerberos 5 LSC credential location from a target iterator. + * + * @param[in] iterator Iterator. + * + * @return Kerberos 5 LSC credential. + */ +int +target_iterator_krb5_trash (iterator_t* iterator) +{ + int ret; + if (iterator->done) return -1; + ret = iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 21); + return ret; +} + /** * @brief Get the allow_simultaneous_ips value from a target iterator. * @@ -34194,7 +34321,7 @@ target_iterator_ssh_elevate_trash (iterator_t* iterator) * @return allow_simult_ips_same_host or NULL if iteration is complete. */ DEF_ACCESS (target_iterator_allow_simultaneous_ips, - GET_ITERATOR_COLUMN_COUNT + 20); + GET_ITERATOR_COLUMN_COUNT + 22); /** * @brief Return the UUID of a tag. @@ -34457,6 +34584,19 @@ target_ssh_elevate_credential (target_t target) return target_credential (target, "elevate"); } +/** + * @brief Return the Kerberos 5 credential associated with a target, if any. + * + * @param[in] target Target. + * + * @return Kerberos 5 credential if any, else 0. + */ +credential_t +target_krb5_credential (target_t target) +{ + return target_credential (target, "krb5"); +} + /** * @brief Return the port list associated with a target, if any. * diff --git a/src/manage_sql.h b/src/manage_sql.h index d24868e61..c7181ac4a 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -353,6 +353,7 @@ credential_t target_ssh_credential (target_t); credential_t target_smb_credential (target_t); credential_t target_esxi_credential (target_t); credential_t target_ssh_elevate_credential (target_t); +credential_t target_krb5_credential (target_t); int create_current_report (task_t, char **, task_status_t); diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 5225f9350..ef0368341 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -5698,7 +5698,12 @@ END:VCALENDAR exclude_hosts ssh_credential ssh_elevate_credential - smb_credential + + + krb5_credential + smb_credential + + esxi_credential snmp_credential ssh_lsc_credential @@ -5788,6 +5793,17 @@ END:VCALENDAR + + krb5_credential + Kerberos 5 login credentials for target + + + id + uuid + 1 + + + smb_credential SMB login credentials for target @@ -21833,6 +21849,7 @@ END:VCALENDAR ssh_credential smb_credential esxi_credential + krb5_credential snmp_credential ssh_elevate_credential permissions @@ -22072,6 +22089,37 @@ END:VCALENDAR boolean + + krb5_credential + + + id + + A UUID if there is a credential, otherwise the empty string + + uuid_or_empty + 1 + + name + permissions + trash + + + name + The name of the Kerberos 5 LSC credential + name + + + permissions + Permissions the user has on the task + + + + trash + Whether the LSC credential is in the trashcan + boolean + + snmp_credential @@ -28146,7 +28194,12 @@ END:VCALENDAR exclude_hosts ssh_credential ssh_elevate_credential - smb_credential + + + krb5_credential + smb_credential + + esxi_credential snmp_credential ssh_lsc_credential @@ -28218,6 +28271,17 @@ END:VCALENDAR + + krb5_credential + Kerberos 5 login credentials for target + + + id + uuid + 1 + + + esxi_credential ESXi credential to use on target From 9613a4858c67332689e56a532e7c46bd33edd24e Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 2 Dec 2024 12:02:46 +0100 Subject: [PATCH 45/64] Add another sql_rollback in create_credential --- src/manage_sql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manage_sql.c b/src/manage_sql.c index 66dafb594..133e9f05a 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35760,6 +35760,7 @@ create_credential (const char* name, const char* comment, const char* login, else { g_warning ("%s: Cannot determine type of new credential", __func__); + sql_rollback (); return 18; } From 3a252c6415a6dd2b7bc26270bda8cced52e8ce52 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 20 Aug 2024 19:55:19 +0200 Subject: [PATCH 46/64] Remove resource_id field from get_permissions_data_t --- src/gmp.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 231e40eaa..03219f1d5 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -1905,7 +1905,6 @@ get_overrides_data_reset (get_overrides_data_t *data) typedef struct { get_data_t get; ///< Get args. - char *resource_id; ///< Resource whose permissions to get. } get_permissions_data_t; /** @@ -1916,8 +1915,6 @@ typedef struct static void get_permissions_data_reset (get_permissions_data_t *data) { - free (data->resource_id); - get_data_reset (&data->get); memset (data, 0, sizeof (get_permissions_data_t)); } @@ -5475,8 +5472,6 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, get_data_parse_attributes (&get_permissions_data->get, "permission", attribute_names, attribute_values); - append_attribute (attribute_names, attribute_values, "resource_id", - &get_permissions_data->resource_id); set_client_state (CLIENT_GET_PERMISSIONS); } else if (strcasecmp ("GET_PREFERENCES", element_name) == 0) From 21dec6c2c754bcb1e9c1be8ce2debf3b8cbb994b Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 8 Oct 2024 11:15:04 +0200 Subject: [PATCH 47/64] Fix: add LIBDIR to SYSTEMD_SERVICE_DIR config --- config/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index a9c1ce686..5756751d5 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -15,9 +15,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - if (NOT SYSTEMD_SERVICE_DIR) - set (SYSTEMD_SERVICE_DIR "/lib/systemd/system") + set (SYSTEMD_SERVICE_DIR "${LIBDIR}/systemd/system") endif (NOT SYSTEMD_SERVICE_DIR) if (NOT LOGROTATE_DIR) From 993a755c6b17e6c006c2f6e7139a9bfce3fcad7e Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 16 Jul 2024 18:37:38 +0200 Subject: [PATCH 48/64] GMP doc: GET_FILTERS: fix duplicate FILTERS in HTML Currently E in PATTERN refers to an ELE by NAME. Extend E to refer to the ELE by ID. ID takes preference over NAME. Also select only one ELE for E. This allows adding an ID to the second FILTERS ELE in GET_FILTERS, preventing the two FILTERS from being merged and duplicated by the HTML XSL. --- src/schema_formats/HTML/HTML.xsl | 9 ++++++--- src/schema_formats/XML/GMP.xml.in | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/schema_formats/HTML/HTML.xsl b/src/schema_formats/HTML/HTML.xsl index d27a54606..8a349f4a2 100644 --- a/src/schema_formats/HTML/HTML.xsl +++ b/src/schema_formats/HTML/HTML.xsl @@ -579,12 +579,14 @@ along with this program. If not, see .
  • - + + + select="($line-element/ele[id=$element-name-or-id]|$line-element/ele[name=$element-name-or-id])[1]"/> - <> + <>
    ()
    @@ -611,6 +613,7 @@ along with this program. If not, see .
    + <> diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 5225f9350..29254734a 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -11773,7 +11773,7 @@ END:VCALENDAR filter filters sort - filters + filters2 filter_count @@ -12030,6 +12030,7 @@ END:VCALENDAR + filters2 filters From 6a179f7df4bb0f53371c1ec8fe278914d1c48386 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 16 Jul 2024 19:02:14 +0200 Subject: [PATCH 49/64] Also check ID for E in RNC --- src/schema_formats/rnc.xsl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/schema_formats/rnc.xsl b/src/schema_formats/rnc.xsl index 02c50816f..90ab354b2 100644 --- a/src/schema_formats/rnc.xsl +++ b/src/schema_formats/rnc.xsl @@ -182,6 +182,10 @@ response + + + + From be90c66eb02121dc9ae1fe4023d765f619df511d Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Thu, 5 Dec 2024 13:23:25 +0000 Subject: [PATCH 50/64] Automatic release to 24.1.0 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a279ac168..908fb0965 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 24.0.1 + VERSION 24.1.0 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 1) +set (PROJECT_DEV_VERSION 0) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From c81ffd4d1dba616e9d68f2ad32df0c0580ce2c43 Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Thu, 5 Dec 2024 13:23:26 +0000 Subject: [PATCH 51/64] Automatic adjustments after release [skip ci] * Update to version 24.1.1-dev1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 908fb0965..766c9808a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 24.1.0 + VERSION 24.1.1 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 0) +set (PROJECT_DEV_VERSION 1) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From 0e49e1ec1be168cb7aa179f28150dc0a93541d52 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Thu, 5 Dec 2024 16:03:17 +0100 Subject: [PATCH 52/64] Small fixes in adding Kerberos to targets The not found error for the Kerberos credential in create_target now uses the correct id. For create_target the mutual exclusion of SMB and Kerberos is checked earlier. If the type check for the Kerberos credential in create_target or modify_target fails, the type string is now freed. --- src/gmp.c | 14 +++++++------- src/manage_sql.c | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 08ea2b9ef..6648af6c8 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -23094,6 +23094,12 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, (XML_ERROR_SYNTAX ("create_target", "Hosts must be at least one" " character long")); + else if (create_target_data->smb_credential_id + && create_target_data->krb5_credential_id) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_target", + "Targets cannot have both an SMB and" + " Kerberos 5 credential")); else if (create_target_data->ssh_credential_id && find_credential_with_permission (create_target_data->ssh_credential_id, @@ -23213,19 +23219,13 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, { if (send_find_error_to_client ("create_target", "Credential", - create_target_data->snmp_credential_id, + create_target_data->krb5_credential_id, gmp_parser)) { error_send_to_client (error); return; } } - else if (create_target_data->smb_credential_id - && create_target_data->krb5_credential_id) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_target", - "Targets cannot have both an SMB and" - " Kerberos 5 credential")); /* Create target from host string. */ else switch (create_target diff --git a/src/manage_sql.c b/src/manage_sql.c index 53a08370f..320a427ae 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -32946,6 +32946,7 @@ create_target (const char* name, const char* asset_hosts_filter, if (strcmp (type, "krb5")) { sql_rollback (); + g_free (type); return 16; } g_free (type); @@ -33600,6 +33601,7 @@ modify_target (const char *target_id, const char *name, const char *hosts, if (strcmp (type, "krb5")) { sql_rollback (); + g_free (type); return 27; } g_free (type); From 0f82c2e93b6495ee404acd0ac65ca85e8b9371e8 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Thu, 5 Dec 2024 16:10:21 +0100 Subject: [PATCH 53/64] Fix: Correct resource types in GMP element doc Several summaries for the "permissions" element now refer to the correct resource types instead of "task". --- src/schema_formats/XML/GMP.xml.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 247a20c50..7b2bfc493 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -22015,7 +22015,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the credential @@ -22051,7 +22051,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the credential @@ -22082,7 +22082,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the credential @@ -22113,7 +22113,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the credential @@ -22178,7 +22178,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the credential @@ -22211,7 +22211,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the port_list @@ -23053,7 +23053,7 @@ END:VCALENDAR permissions - Permissions the user has on the task + Permissions the user has on the scanner From 0def545e85cf17ed7b47d454b30b7c0ef63b126a Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Tue, 10 Dec 2024 09:44:12 +0100 Subject: [PATCH 54/64] Fix: Handle schemas in SCAP rebuild correctly The SCAP rebuild will now use the "scap2" schema for the "cpe_matches" table and create_view_vulns explicitly uses the "scap.cves". This fixes the SCAP rebuild either not working at all for old, missing or empty "scap" schemas or using using outdated CPE match data. --- src/gmp.c | 4 +++- src/manage.h | 2 +- src/manage_pg.c | 2 +- src/manage_sql.c | 7 +++++-- src/manage_sql_secinfo.c | 6 +++++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 6648af6c8..b26378a66 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -13367,7 +13367,9 @@ print_cpe_match_nodes_xml (resource_t node, GString *buffer) vee ?: ""); iterator_t cpe_matches; - init_cpe_match_string_matches_iterator (&cpe_matches, match_criteria_id); + init_cpe_match_string_matches_iterator ( + &cpe_matches, match_criteria_id, NULL + ); xml_string_append (buffer, ""); while (next (&cpe_matches)) diff --git a/src/manage.h b/src/manage.h index b7d7a3cee..680400a76 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1751,7 +1751,7 @@ int cpe_match_string_iterator_vulnerable (iterator_t*); void -init_cpe_match_string_matches_iterator (iterator_t*, const char *); +init_cpe_match_string_matches_iterator (iterator_t*, const char *, const char*); const char* cpe_matches_cpe_name_id (iterator_t*); diff --git a/src/manage_pg.c b/src/manage_pg.c index 56ea9f7e0..dfd272043 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -1834,7 +1834,7 @@ create_view_vulns () " severity, " G_STRINGIFY (QOD_DEFAULT) " AS qod," " 'cve' AS type" - " FROM cves" + " FROM scap.cves" " WHERE uuid in (SELECT * FROM used_nvts)"); else sql ("CREATE OR REPLACE VIEW vulns AS" diff --git a/src/manage_sql.c b/src/manage_sql.c index 320a427ae..d24ac857b 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -20661,15 +20661,18 @@ DEF_ACCESS (cpe_match_string_iterator_version_end_excl, 7); * * @param[in] iterator Iterator. * @param[in] match_criteria_id The match criteria id to get the matches for. + * @param[in] schema Schema name, NULL for the default "scap". */ void init_cpe_match_string_matches_iterator (iterator_t* iterator, - const char *match_criteria_id) + const char *match_criteria_id, + const char *schema) { init_iterator (iterator, "SELECT cpe_name_id, cpe_name" - " FROM scap.cpe_matches" + " FROM %s.cpe_matches" " WHERE match_criteria_id = '%s'", + schema ? schema : "scap", match_criteria_id); } diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index c80247780..37be2185f 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3500,7 +3500,11 @@ handle_cve_configurations (resource_t cve_db_id, char * cve_id, if (vulnerable) { iterator_t cpe_matches; - init_cpe_match_string_matches_iterator (&cpe_matches, quoted_match_criteria_id); + init_cpe_match_string_matches_iterator ( + &cpe_matches, + quoted_match_criteria_id, + "scap2" + ); while (next (&cpe_matches)) g_string_append_printf (software, "%s ", cpe_matches_cpe_name (&cpe_matches)); cleanup_iterator (&cpe_matches); From 89d09886842029fae573fea129e6620fedca0dd5 Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Tue, 10 Dec 2024 09:08:44 +0000 Subject: [PATCH 55/64] Automatic release to 24.1.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 766c9808a..88ca84bfd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 1) +set (PROJECT_DEV_VERSION 0) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From 61e9921aa1a16669e095240b5f59f5cb573d1632 Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Tue, 10 Dec 2024 09:08:46 +0000 Subject: [PATCH 56/64] Automatic adjustments after release [skip ci] * Update to version 24.1.2-dev1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88ca84bfd..34d3cd40b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 24.1.1 + VERSION 24.1.2 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 0) +set (PROJECT_DEV_VERSION 1) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From cd3e76b43b4af1ae31f64cb8b546fbc0d1a2ebad Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Wed, 11 Dec 2024 10:13:39 +0100 Subject: [PATCH 57/64] Fix: Handle missing primary CVSS metrics in CVEs Updating CVEs from JSON now handles the case where there are no primary metrics for the newest CVSS version by also checking metrics of other CVSS version or falling back to the secondary metrics of the newest CVSS version. This fixes a crash when loading a JSON feed containing CVEs with no primary metrics for the newest CVSS version. --- src/manage_sql_secinfo.c | 99 +++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 37be2185f..165a47125 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -3577,7 +3577,8 @@ handle_json_cve_item (cJSON *item) modified_time = parse_iso_time (modified); cJSON *metrics_json; - cJSON *cvss_metric_array; + cJSON *best_cvss_metric_item = NULL; + gboolean cvss_metric_is_primary = FALSE; metrics_json = cJSON_GetObjectItemCaseSensitive (cve_json, "metrics"); if (!cJSON_IsObject (metrics_json)) @@ -3587,73 +3588,77 @@ handle_json_cve_item (cJSON *item) return -1; } - gboolean cvss_metric_found = FALSE; - const char *cvss_metric_keys[] = { "cvssMetricV40", "cvssMetricV31", "cvssMetricV30", "cvssMetricV2"}; + score_dbl = SEVERITY_MISSING; + vector = NULL; + for (int i = 0; i < 4; i++) { - cvss_metric_array + cJSON *cvss_metric_array = cJSON_GetObjectItemCaseSensitive (metrics_json, cvss_metric_keys[i]); if (cJSON_IsArray (cvss_metric_array) && cJSON_GetArraySize (cvss_metric_array) > 0) { - cvss_metric_found = TRUE; - break; + cJSON *cvss_metric_item; + cJSON_ArrayForEach (cvss_metric_item, cvss_metric_array) + { + char *source_type + = json_object_item_string (cvss_metric_item, "type"); + if (source_type == NULL) + { + g_warning ("%s: type missing in CVSS metric for %s.", + __func__, cve_id); + return -1; + } + if (strcmp (source_type, "Primary") == 0) + cvss_metric_is_primary = TRUE; + + if (cvss_metric_is_primary) + { + best_cvss_metric_item = cvss_metric_item; + break; + } + else if (best_cvss_metric_item == NULL) + best_cvss_metric_item = cvss_metric_item; + } + + if (cvss_metric_is_primary) + break; } } - if (cvss_metric_found) + if (best_cvss_metric_item) { - cJSON *cvss_json; - cJSON *cvss_metric_item; - char *source_type; + cJSON *cvss_json + = cJSON_GetObjectItemCaseSensitive (best_cvss_metric_item, "cvssData"); + if (!cJSON_IsObject (cvss_json)) + { + g_warning ("%s: cvssData missing or not an object for %s.", + __func__, cve_id); + return -1; + } - cJSON_ArrayForEach (cvss_metric_item, cvss_metric_array) + score_dbl = json_object_item_double (cvss_json, + "baseScore", + SEVERITY_MISSING); + if (score_dbl == SEVERITY_MISSING) { - source_type = json_object_item_string (cvss_metric_item, "type"); - if (source_type == NULL) - { - g_warning ("%s: type missing in CVSS metric for %s.", - __func__, cve_id); - return -1; - } - else if (strcmp (source_type, "Primary")) - continue; + g_warning ("%s: baseScore missing for %s.", __func__, cve_id); + return -1; + } - cvss_json = cJSON_GetObjectItemCaseSensitive (cvss_metric_item, - "cvssData"); - if (!cJSON_IsObject (cvss_json)) - { - g_warning ("%s: cvssData missing or not an object for %s.", - __func__, cve_id); - return -1; - } - score_dbl = json_object_item_double (cvss_json, - "baseScore", - SEVERITY_MISSING); - if (score_dbl == SEVERITY_MISSING) - { - g_warning ("%s: baseScore missing for %s.", __func__, cve_id); - return -1; - } - vector = json_object_item_string (cvss_json, "vectorString"); - if (vector == NULL) - { - g_warning ("%s: vectorString missing for %s.", __func__, cve_id); - return -1; - } + vector = json_object_item_string (cvss_json, "vectorString"); + if (vector == NULL) + { + g_warning ("%s: vectorString missing for %s.", __func__, cve_id); + return -1; } } - else - { - score_dbl = SEVERITY_MISSING; - vector = NULL; - } cJSON *descriptions_json; cJSON *description_item_json; From dc7b4a9aa3a1e0a5ca509076599123e80c0c3ac1 Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Wed, 11 Dec 2024 10:15:49 +0000 Subject: [PATCH 58/64] Automatic release to 24.1.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34d3cd40b..b8b1cf413 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 1) +set (PROJECT_DEV_VERSION 0) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From 483d65831c80ca16a3d2549aceca5fdc6a807415 Mon Sep 17 00:00:00 2001 From: Greenbone Bot Date: Wed, 11 Dec 2024 10:15:50 +0000 Subject: [PATCH 59/64] Automatic adjustments after release [skip ci] * Update to version 24.1.3-dev1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8b1cf413..0f91fd6af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required (VERSION 3.0) message ("-- Configuring Greenbone Vulnerability Manager...") project (gvm - VERSION 24.1.2 + VERSION 24.1.3 LANGUAGES C) if (POLICY CMP0005) @@ -58,7 +58,7 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES "Release") # Set dev version if this is a development version and not a full release, # unset (put value 0 or delete line) before a full release and reset after. -set (PROJECT_DEV_VERSION 0) +set (PROJECT_DEV_VERSION 1) # If PROJECT_DEV_VERSION is set, the version string will be set to: # "major.minor.patch~dev${PROJECT_DEV_VERSION}${GIT_REVISION}" From e1138b554e010bd916fe636d6441cd9b3c457b7b Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Fri, 6 Dec 2024 17:30:54 +0100 Subject: [PATCH 60/64] Change: Adjust all severity ratings to match CVSS 3.1. Mark holes, warnings and infos as deprecated to be removed in the future. Add high, medium and low instead. --- src/gmp.c | 40 +++-- src/manage.c | 19 ++- src/manage.h | 8 +- src/manage_pg.c | 54 +++++-- src/manage_sql.c | 368 +++++++++++++++++++++++++++++++-------------- src/manage_utils.c | 8 +- 6 files changed, 349 insertions(+), 148 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index b26378a66..87ce78b1c 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -8506,7 +8506,8 @@ buffer_override_xml (GString *buffer, iterator_t *overrides, override_iterator_active (overrides), strlen (excerpt) < strlen (text), excerpt, - override_iterator_threat (overrides) + override_iterator_severity (overrides) + && override_iterator_threat (overrides) ? override_iterator_threat (overrides) : "", override_iterator_severity (overrides) @@ -15194,7 +15195,7 @@ handle_get_reports (gmp_parser_t *gmp_parser, GError **error) ("apply_overrides=%i min_qod=%i levels=%s compliance_levels=%s", overrides, min_qod, - levels ? levels : "hmlgdf", + levels ? levels : "chmlgdf", compliance_levels ? compliance_levels : "yniu"); g_free (compliance_levels); @@ -18490,8 +18491,8 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) report_t running_report; char *owner, *observers; int target_in_trash, scanner_in_trash; - int holes = 0, infos = 0, logs = 0, warnings = 0; - int holes_2 = 0, infos_2 = 0, warnings_2 = 0; + int criticals = 0, holes = 0, infos = 0, logs = 0, warnings = 0; + int criticals_2 = 0, holes_2 = 0, infos_2 = 0, warnings_2 = 0; int false_positives = 0, task_scanner_type; int target_available, config_available; int scanner_available; @@ -18598,7 +18599,7 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) { // TODO Could skip this count for tasks page. if (report_counts (first_report_id, - &holes_2, &infos_2, &logs, + &criticals_2, &holes_2, &infos_2, &logs, &warnings_2, &false_positives, &severity_2, apply_overrides, min_qod)) g_error ("%s: GET_TASKS: error getting counts for" @@ -18614,7 +18615,7 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) if (((first_report_id == NULL) || (strcmp (second_last_report_id, first_report_id))) && report_counts (second_last_report_id, - &holes_2, &infos_2, + &criticals_2, &holes_2, &infos_2, &logs, &warnings_2, &false_positives, &severity_2, apply_overrides, min_qod)) @@ -18668,7 +18669,7 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) { if (report_counts (last_report_id, - &holes, &infos, &logs, + &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, apply_overrides, min_qod)) g_error ("%s: GET_TASKS: error getting counts for" @@ -18677,6 +18678,7 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) } else { + criticals = criticals_2; holes = holes_2; infos = infos_2; warnings = warnings_2; @@ -18730,10 +18732,14 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) "%s" "%s" "" - "%i" - "%i" + "%i" + "%i" + "%i" + "%i" + "%i" "%i" - "%i" + "%i" + "%i" "" "%i" "" @@ -18747,10 +18753,14 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) timestamp, scan_start, scan_end, + criticals, + holes, holes, infos, + infos, logs, warnings, + warnings, false_positives, severity); free (scan_start); @@ -18905,8 +18915,8 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) get_tasks_data->get.trash ? "" : task_iterator_trend_counts - (&tasks, holes, warnings, infos, severity, - holes_2, warnings_2, infos_2, severity_2), + (&tasks, criticals, holes, warnings, infos, severity, + criticals_2, holes_2, warnings_2, infos_2, severity_2), task_schedule_xml, current_report, last_report); @@ -19700,10 +19710,14 @@ gmp_xml_handle_result () { create_report_data->result_severity = strdup (""); } - else if (strcasecmp (create_report_data->result_threat, "High") == 0) + else if (strcasecmp (create_report_data->result_threat, "Critical") == 0) { create_report_data->result_severity = strdup ("10.0"); } + else if (strcasecmp (create_report_data->result_threat, "High") == 0) + { + create_report_data->result_severity = strdup ("8.9"); + } else if (strcasecmp (create_report_data->result_threat, "Medium") == 0) { create_report_data->result_severity = strdup ("5.0"); diff --git a/src/manage.c b/src/manage.c index 72458dbb1..9b7d0cd71 100644 --- a/src/manage.c +++ b/src/manage.c @@ -860,6 +860,8 @@ scanner_type_valid (scanner_type_t scanner_type) const char * threat_message_type (const char *threat) { + if (strcasecmp (threat, "Critical") == 0) + return "Alarm"; if (strcasecmp (threat, "High") == 0) return "Alarm"; if (strcasecmp (threat, "Medium") == 0) @@ -886,8 +888,10 @@ threat_message_type (const char *threat) int severity_in_level (double severity, const char *level) { - if (strcmp (level, "high") == 0) - return severity >= 7 && severity <= 10; + if (strcmp (level, "critical") == 0) + return severity >= 9 && severity <= 10; + else if (strcmp (level, "high") == 0) + return severity >= 7 && severity < 9; else if (strcmp (level, "medium") == 0) return severity >= 4 && severity < 7; else if (strcmp (level, "low") == 0) @@ -919,6 +923,8 @@ severity_to_level (double severity, int mode) { if (mode == 1) return "Alarm"; + else if (severity_in_level (severity, "critical")) + return "Critical"; else if (severity_in_level (severity, "high")) return "High"; else if (severity_in_level (severity, "medium")) @@ -1300,11 +1306,12 @@ severity_data_range_count (const severity_data_t* severity_data, * @param[out] lows The number of Low severity results. * @param[out] mediums The number of Medium severity results. * @param[out] highs The number of High severity results. + * @param[out] criticals The number of Critical severity results. */ void severity_data_level_counts (const severity_data_t *severity_data, int *errors, int *false_positives, - int *logs, int *lows, int *mediums, int *highs) + int *logs, int *lows, int *mediums, int *highs, int* criticals) { if (errors) *errors @@ -1341,6 +1348,12 @@ severity_data_level_counts (const severity_data_t *severity_data, = severity_data_range_count (severity_data, level_min_severity ("high"), level_max_severity ("high")); + + if (criticals) + *criticals + = severity_data_range_count (severity_data, + level_min_severity ("critical"), + level_max_severity ("critical")); } diff --git a/src/manage.h b/src/manage.h index 680400a76..a2667abaf 100644 --- a/src/manage.h +++ b/src/manage.h @@ -902,7 +902,7 @@ int task_last_report (task_t, report_t*); const char * -task_iterator_trend_counts (iterator_t *, int, int, int, double, int, int, int, +task_iterator_trend_counts (iterator_t *, int, int, int, int, double, int, int, int, int, double); int @@ -1067,7 +1067,7 @@ severity_data_add_count (severity_data_t*, double, int); void severity_data_level_counts (const severity_data_t*, - int*, int*, int*, int*, int*, int*); + int*, int*, int*, int*, int*, int*, int*); /* General task facilities. */ @@ -1338,11 +1338,11 @@ report_scan_result_count (report_t, const char*, const char*, int, const char*, const char*, int, int, int*); int -report_counts (const char*, int*, int*, int*, int*, int*, double*, +report_counts (const char*, int*, int*, int*, int*, int*, int*, double*, int, int); int -report_counts_id (report_t, int*, int*, int*, int*, int*, double*, +report_counts_id (report_t, int*, int*, int*, int*, int*, int*, double*, const get_data_t*, const char*); int diff --git a/src/manage_pg.c b/src/manage_pg.c index dfd272043..704615c5c 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -230,8 +230,10 @@ manage_create_sql_functions () " v := " G_STRINGIFY (SEVERITY_ERROR) ";" " ELSE" " CASE" - " WHEN lower (lvl) = 'high' THEN" + " WHEN lower (lvl) = 'critical' THEN" " v := 10.0;" + " WHEN lower (lvl) = 'high' THEN" + " v := 8.9;" " WHEN lower (lvl) = 'medium' THEN" " v := 6.9;" " WHEN lower (lvl) = 'low' THEN" @@ -262,6 +264,8 @@ manage_create_sql_functions () " v := " G_STRINGIFY (SEVERITY_ERROR) ";" " ELSE" " CASE" + " WHEN lower (lvl) = 'critical' THEN" + " v := 9.0;" " WHEN lower (lvl) = 'high' THEN" " v := 7.0;" " WHEN lower (lvl) = 'medium' THEN" @@ -497,20 +501,22 @@ manage_create_sql_functions () sql ("CREATE OR REPLACE FUNCTION order_threat (text)" " RETURNS integer AS $$" " BEGIN" - " IF $1 = 'High' THEN" + " IF $1 = 'Critical' THEN" " RETURN 1;" - " ELSIF $1 = 'Medium' THEN" + " ELSIF $1 = 'High' THEN" " RETURN 2;" - " ELSIF $1 = 'Low' THEN" + " ELSIF $1 = 'Medium' THEN" " RETURN 3;" - " ELSIF $1 = 'Log' THEN" + " ELSIF $1 = 'Low' THEN" " RETURN 4;" - " ELSIF $1 = 'False Positive' THEN" + " ELSIF $1 = 'Log' THEN" " RETURN 5;" - " ELSIF $1 = 'None' THEN" + " ELSIF $1 = 'False Positive' THEN" " RETURN 6;" - " ELSE" + " ELSIF $1 = 'None' THEN" " RETURN 7;" + " ELSE" + " RETURN 8;" " END IF;" " END;" "$$ LANGUAGE plpgsql" @@ -1364,6 +1370,8 @@ manage_create_sql_functions () " second_last_report integer;" " severity_a double precision;" " severity_b double precision;" + " critical_a bigint;" + " critical_b bigint;" " high_a bigint;" " high_b bigint;" " medium_a bigint;" @@ -1399,6 +1407,10 @@ manage_create_sql_functions () " RETURN 'down'::text;" " END IF;" /* Calculate trend. */ + " critical_a := report_severity_count (last_report, $2, $3," + " 'critical');" + " critical_b := report_severity_count (second_last_report, $2, $3," + " 'critical');" " high_a := report_severity_count (last_report, $2, $3," " 'high');" " high_b := report_severity_count (second_last_report, $2, $3," @@ -1411,7 +1423,9 @@ manage_create_sql_functions () " 'low');" " low_b := report_severity_count (second_last_report, $2, $3," " 'low');" - " IF high_a > 0 THEN" + " IF critical_a > 0 THEN" + " threat_a := 5;" + " ELSEIF high_a > 0 THEN" " threat_a := 4;" " ELSIF medium_a > 0 THEN" " threat_a := 3;" @@ -1420,7 +1434,9 @@ manage_create_sql_functions () " ELSE" " threat_a := 1;" " END IF;" - " IF high_b > 0 THEN" + " IF critical_b > 0 THEN" + " threat_b := 5;" + " ELSEIF high_b > 0 THEN" " threat_b := 4;" " ELSIF medium_b > 0 THEN" " threat_b := 3;" @@ -1436,6 +1452,14 @@ manage_create_sql_functions () " RETURN 'down'::text;" " END IF;" /* Check if the threat count changed. */ + " IF critical_a > 0 THEN" + " IF critical_a > critical_b THEN" + " RETURN 'more'::text;" + " ELSIF critical_a < critical_b THEN" + " RETURN 'less'::text;" + " END IF;" + " RETURN 'same'::text;" + " END IF;" " IF high_a > 0 THEN" " IF high_a > high_b THEN" " RETURN 'more'::text;" @@ -1574,9 +1598,12 @@ manage_create_sql_functions () " text)" " RETURNS boolean AS $$" " (SELECT CASE lower ($2)" + " WHEN 'critical'" + " THEN $1 >= 9" + " AND $1 <= 10" " WHEN 'high'" " THEN $1 >= 7" - " AND $1 <= 10" + " AND $1 < 9" " WHEN 'medium'" " THEN $1 >= 4" " AND $1 < 7" @@ -1619,6 +1646,9 @@ manage_create_sql_functions () " WHEN $2 = 1" " THEN 'Alarm'" " WHEN severity_in_level ($1::double precision," + " 'critical')" + " THEN 'Critical'" + " WHEN severity_in_level ($1::double precision," " 'high')" " THEN 'High'" " WHEN severity_in_level ($1::double precision," @@ -1648,6 +1678,8 @@ manage_create_sql_functions () " THEN (SELECT CASE" " WHEN $2 = 1" " THEN 'Alarm'" + " WHEN severity_in_level ($1, 'critical')" + " THEN 'Critical'" " WHEN severity_in_level ($1, 'high')" " THEN 'High'" " WHEN severity_in_level ($1, 'medium')" diff --git a/src/manage_sql.c b/src/manage_sql.c index d24ac857b..134aa8842 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -251,9 +251,9 @@ static void check_for_updated_cert (); static int -report_counts_id_full (report_t, int *, int *, int *, int *, int *, +report_counts_id_full (report_t, int *, int *, int *, int *, int *, int *, double *, const get_data_t*, const char* , - int *, int *, int *, int *, int *, double *); + int *, int *, int *, int *, int *, int *, double *); static gboolean find_group_with_permission (const char *, group_t *, const char *); @@ -2604,6 +2604,7 @@ keyword_applies_to_column (keyword_t *keyword, const char* column) && (strstr ("False Positive", keyword->string) == NULL) && (strstr ("Error", keyword->string) == NULL) && (strstr ("Alarm", keyword->string) == NULL) + && (strstr ("Critical", keyword->string) == NULL) && (strstr ("High", keyword->string) == NULL) && (strstr ("Medium", keyword->string) == NULL) && (strstr ("Low", keyword->string) == NULL) @@ -3045,7 +3046,8 @@ filter_clause (const char* type, const char* filter, || strcmp (keyword->string, "log_per_host") == 0 || strcmp (keyword->string, "low_per_host") == 0 || strcmp (keyword->string, "medium_per_host") == 0 - || strcmp (keyword->string, "high_per_host") == 0) + || strcmp (keyword->string, "high_per_host") == 0 + || strcmp (keyword->string, "critical_per_host") == 0) { gchar *column; column = columns_select_column (select_columns, @@ -3082,6 +3084,7 @@ filter_clause (const char* type, const char* filter, || (strcmp (keyword->string, "published") == 0) || (strcmp (keyword->string, "qod") == 0) || (strcmp (keyword->string, "cves") == 0) + || (strcmp (keyword->string, "critical") == 0) || (strcmp (keyword->string, "high") == 0) || (strcmp (keyword->string, "medium") == 0) || (strcmp (keyword->string, "low") == 0) @@ -3238,7 +3241,8 @@ filter_clause (const char* type, const char* filter, || strcmp (keyword->string, "log_per_host") == 0 || strcmp (keyword->string, "low_per_host") == 0 || strcmp (keyword->string, "medium_per_host") == 0 - || strcmp (keyword->string, "high_per_host") == 0) + || strcmp (keyword->string, "high_per_host") == 0 + || strcmp (keyword->string, "critical_per_host") == 0) { gchar *column; column = columns_select_column (select_columns, @@ -3275,6 +3279,7 @@ filter_clause (const char* type, const char* filter, || (strcmp (keyword->string, "published") == 0) || (strcmp (keyword->string, "qod") == 0) || (strcmp (keyword->string, "cves") == 0) + || (strcmp (keyword->string, "critical") == 0) || (strcmp (keyword->string, "high") == 0) || (strcmp (keyword->string, "medium") == 0) || (strcmp (keyword->string, "low") == 0) @@ -14535,7 +14540,7 @@ condition_met (task_t task, report_t report, alert_t alert, { char *filter_id, *count_string; report_t last_report; - int holes, infos, logs, warnings, false_positives; + int criticals, holes, infos, logs, warnings, false_positives; int count; double severity; @@ -14582,11 +14587,11 @@ condition_met (task_t task, report_t report, alert_t alert, memset (&get, 0, sizeof (get_data_t)); get.type = "result"; get.filt_id = filter_id; - report_counts_id (last_report, &holes, &infos, &logs, + report_counts_id (last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); - db_count = holes + infos + logs + warnings + db_count = criticals + holes + infos + logs + warnings + false_positives; g_debug ("%s: count: %i vs %i", __func__, db_count, count); @@ -14603,7 +14608,7 @@ condition_met (task_t task, report_t report, alert_t alert, { char *direction, *filter_id, *count_string; report_t last_report; - int holes, infos, logs, warnings, false_positives; + int criticals, holes, infos, logs, warnings, false_positives; int count; double severity; @@ -14639,10 +14644,10 @@ condition_met (task_t task, report_t report, alert_t alert, get.type = "result"; get.filt_id = filter_id; - report_counts_id (last_report, &holes, &infos, &logs, + report_counts_id (last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); - last_count = holes + infos + logs + warnings + last_count = criticals + holes + infos + logs + warnings + false_positives; second_last_report = 0; @@ -14653,10 +14658,10 @@ condition_met (task_t task, report_t report, alert_t alert, { int cmp, second_last_count; - report_counts_id (second_last_report, &holes, &infos, + report_counts_id (second_last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); - second_last_count = holes + infos + logs + warnings + second_last_count = criticals + holes + infos + logs + warnings + false_positives; cmp = last_count - second_last_count; @@ -15032,9 +15037,9 @@ append_to_task_string (task_t task, const char* field, const char* value) { GET_ITERATOR_FILTER_COLUMNS, "status", "total", "first_report", \ "last_report", "threat", "trend", "severity", "schedule", "next_due", \ "first", "last", "false_positive", "log", "low", "medium", "high", \ - "hosts", "result_hosts", "fp_per_host", "log_per_host", "low_per_host", \ - "medium_per_host", "high_per_host", "target", "usage_type", \ - "first_report_created", "last_report_created", NULL } + "critical", "hosts", "result_hosts", "fp_per_host", "log_per_host", \ + "low_per_host", "medium_per_host", "high_per_host", "critical_per_host", \ + "target", "usage_type", "first_report_created", "last_report_created", NULL } /** * @brief Task iterator columns. @@ -15169,6 +15174,14 @@ append_to_task_string (task_t task, const char* field, const char* value) "high", \ KEYWORD_TYPE_INTEGER \ }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod, 'Critical')" \ + " END", \ + "critical", \ + KEYWORD_TYPE_INTEGER \ + }, \ { \ "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ " report_host_count (task_last_report (id))" \ @@ -15243,6 +15256,18 @@ append_to_task_string (task_t task, const char* field, const char* value) "high_per_host", \ KEYWORD_TYPE_INTEGER \ }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'Critical') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "critical_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ { \ "(SELECT name FROM targets WHERE id = target)", \ "target", \ @@ -21119,7 +21144,7 @@ report_cache_counts (report_t report, int clear_original, int clear_overridden, const char* users_where) { iterator_t cache_iterator; - int holes, infos, logs, warnings, false_positives; + int criticals, holes, infos, logs, warnings, false_positives; double severity; get_data_t *get = NULL; gchar *old_user_id; @@ -21151,7 +21176,7 @@ report_cache_counts (report_t report, int clear_original, int clear_overridden, report, user, override, min_qod); } - report_counts_id (report, &holes, &infos, &logs, &warnings, + report_counts_id (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, get, NULL); get_data_reset (get); @@ -22110,12 +22135,11 @@ report_add_results_array (report_t report, GArray *results) #define REPORT_ITERATOR_FILTER_COLUMNS \ { ANON_GET_ITERATOR_FILTER_COLUMNS, "task_id", "name", "creation_time", \ "date", "status", "task", "severity", "false_positive", "log", "low", \ - "medium", "high", "hosts", "result_hosts", "fp_per_host", "log_per_host", \ - "low_per_host", "medium_per_host", "high_per_host", "duration", \ - "duration_per_host", "start_time", "end_time", "scan_start", "scan_end", \ - "compliance_yes", "compliance_no", "compliance_incomplete", \ - "compliant", NULL } - + "medium", "high", "critical", "hosts", "result_hosts", "fp_per_host", \ + "log_per_host", "low_per_host", "medium_per_host", "high_per_host", \ + "critical_per_host", "duration", "duration_per_host", "start_time", \ + "end_time", "scan_start", "scan_end", "compliance_yes", "compliance_no", \ + "compliance_incomplete", "compliant", NULL } /** * @brief Report iterator columns. */ @@ -22182,6 +22206,11 @@ report_add_results_array (report_t report, GArray *results) "high", \ KEYWORD_TYPE_INTEGER \ }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod, 'Critical')", \ + "critical", \ + KEYWORD_TYPE_INTEGER \ + }, \ { \ "(SELECT name FROM users WHERE users.id = reports.owner)", \ "_owner", \ @@ -22237,6 +22266,14 @@ report_add_results_array (report_t report, GArray *results) "high_per_host", \ KEYWORD_TYPE_INTEGER \ }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'Critical') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "critical_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ { \ "(CASE WHEN (start_time IS NULL or end_time IS NULL)" \ " THEN NULL ELSE end_time - start_time END)", \ @@ -22584,6 +22621,11 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append_printf (levels_sql, " AND severity_in_levels (%s", new_severity_sql); + if (strchr (levels, 'c')) + { + g_string_append (levels_sql, ", 'critical'"); + count++; + } if (strchr (levels, 'h')) { g_string_append (levels_sql, ", 'high'"); @@ -22618,7 +22660,7 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append (levels_sql, ")"); - if (count == 5) + if (count == 6) { /* All levels. */ g_string_free (levels_sql, TRUE); @@ -23312,7 +23354,7 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod = filter_term_min_qod (filter); levels = filter_term_value (filter, "levels"); if (levels == NULL) - levels = g_strdup ("hmlgdf"); + levels = g_strdup ("chmlgdf"); compliance_levels = filter_term_value (filter, "compliance_levels"); // Build clause fragments @@ -23338,7 +23380,7 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod_clause = where_qod (min_qod); - levels_clause = where_levels_auto (levels ? levels : "hmlgdf", + levels_clause = where_levels_auto (levels ? levels : "chmlgdf", given_new_severity_sql ? given_new_severity_sql : new_severity_sql); @@ -25840,6 +25882,7 @@ report_severity_data (report_t report, const char *host, * use report_counts_id instead. * * @param[in] report_id ID of report. + * @param[out] criticals Number of critical messages. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -25852,7 +25895,7 @@ report_severity_data (report_t report, const char *host, * @return 0 on success, -1 on error. */ int -report_counts (const char* report_id, int* holes, int* infos, +report_counts (const char* report_id, int* criticals, int* holes, int* infos, int* logs, int* warnings, int* false_positives, double* severity, int override, int min_qod) { @@ -25865,7 +25908,7 @@ report_counts (const char* report_id, int* holes, int* infos, // TODO Check if report was found. get = report_results_get_data (1, -1, override, min_qod); - ret = report_counts_id (report, holes, infos, logs, warnings, + ret = report_counts_id (report, criticals, holes, infos, logs, warnings, false_positives, severity, get, NULL); get_data_reset (get); free (get); @@ -26036,6 +26079,7 @@ cache_report_counts (report_t report, int override, int min_qod, * @brief Get the message counts for a report. * * @param[in] report Report. + * @param[out] criticals Number of critical messages. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -26044,6 +26088,7 @@ cache_report_counts (report_t report, int override, int min_qod, * @param[out] severity Maximum severity of the report. * @param[in] get Get data. * @param[in] host Host to which to limit the count. + * @param[out] filtered_criticals Number of critical messages after filtering. * @param[out] filtered_holes Number of hole messages after filtering. * @param[out] filtered_infos Number of info messages after filtering. * @param[out] filtered_logs Number of log messages after filtering. @@ -26055,11 +26100,11 @@ cache_report_counts (report_t report, int override, int min_qod, * @return 0 on success, -1 on error. */ static int -report_counts_id_full (report_t report, int* holes, int* infos, +report_counts_id_full (report_t report, int* criticals, int* holes, int* infos, int* logs, int* warnings, int* false_positives, double* severity, const get_data_t* get, const char* host, - int* filtered_holes, + int* filtered_criticals, int* filtered_holes, int* filtered_infos, int* filtered_logs, int* filtered_warnings, int* filtered_false_positives, double* filtered_severity) @@ -26071,11 +26116,11 @@ report_counts_id_full (report_t report, int* holes, int* infos, int override, min_qod_int; severity_data_t severity_data, filtered_severity_data; - unfiltered_requested = (holes || warnings || infos || logs || false_positives + unfiltered_requested = (criticals || holes || warnings || infos || logs || false_positives || severity); - filtered_requested = (filtered_holes || filtered_warnings || filtered_infos - || filtered_logs || filtered_false_positives - || filtered_severity); + filtered_requested = (filtered_criticals || filtered_holes || filtered_warnings + || filtered_infos || filtered_logs + || filtered_false_positives || filtered_severity); if (current_credentials.uuid == NULL || strcmp (current_credentials.uuid, "") == 0) @@ -26170,11 +26215,11 @@ report_counts_id_full (report_t report, int* holes, int* infos, severity_data_level_counts (&severity_data, NULL, false_positives, - logs, infos, warnings, holes); + logs, infos, warnings, holes, criticals); severity_data_level_counts (&filtered_severity_data, NULL, filtered_false_positives, filtered_logs, filtered_infos, - filtered_warnings, filtered_holes); + filtered_warnings, filtered_holes, filtered_criticals); if (severity) *severity = severity_data.max; @@ -26345,6 +26390,7 @@ report_compliance_counts (report_t report, * @brief Get only the filtered message counts for a report. * * @param[in] report Report. + * @param[out] criticals Number of critical messages. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -26357,14 +26403,14 @@ report_compliance_counts (report_t report, * @return 0 on success, -1 on error. */ int -report_counts_id (report_t report, int* holes, int* infos, +report_counts_id (report_t report, int* criticals, int* holes, int* infos, int* logs, int* warnings, int* false_positives, double* severity, const get_data_t *get, const char *host) { int ret; - ret = report_counts_id_full (report, NULL, NULL, NULL, NULL, NULL, NULL, - get, host, holes, infos, logs, warnings, - false_positives, severity); + ret = report_counts_id_full (report, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + get, host, criticals, holes, infos, logs, + warnings, false_positives, severity); return ret; } @@ -26407,7 +26453,7 @@ report_severity (report_t report, int overrides, int min_qod) g_debug ("%s: could not get max from cache", __func__); get_data_t *get = report_results_get_data (1, -1, overrides, min_qod); report_counts_id (report, NULL, NULL, NULL, NULL, - NULL, &severity, get, NULL); + NULL, NULL, &severity, get, NULL); get_data_reset (get); free (get); } @@ -28121,6 +28167,7 @@ host_summary_append (GString *host_summary_buffer, const char *host, * @param[in] lean Whether to return lean report. * @param[in] host_summary_buffer Host sumary buffer. * @param[in] f_host_ports Hashtable for host ports. + * @param[in] f_host_criticals Hashtable for host criticals. * @param[in] f_host_holes Hashtable for host holes. * @param[in] f_host_warnings Hashtable for host host warnings. * @param[in] f_host_infos Hashtable for host infos. @@ -28141,6 +28188,7 @@ print_report_host_xml (FILE *stream, int lean, GString *host_summary_buffer, GHashTable *f_host_ports, + GHashTable *f_host_criticals, GHashTable *f_host_holes, GHashTable *f_host_warnings, GHashTable *f_host_infos, @@ -28224,9 +28272,12 @@ print_report_host_xml (FILE *stream, } else { - int holes_count, warnings_count, infos_count; + int criticals_count, holes_count, warnings_count, infos_count; int logs_count, false_positives_count; + criticals_count + = GPOINTER_TO_INT + (g_hash_table_lookup ( f_host_criticals, current_host)); holes_count = GPOINTER_TO_INT (g_hash_table_lookup ( f_host_holes, current_host)); @@ -28250,9 +28301,13 @@ print_report_host_xml (FILE *stream, "%d" "" "%d" - "%d" - "%d" - "%d" + "%d" + "%d" + "%d" + "%d" + "%d" + "%d" + "%d" "%d" "%d" "", @@ -28261,10 +28316,14 @@ print_report_host_xml (FILE *stream, ? host_iterator_end_time (hosts) : "", ports_count, - (holes_count + warnings_count + infos_count + (criticals_count + holes_count + warnings_count + infos_count + logs_count + false_positives_count), + criticals_count, + holes_count, holes_count, warnings_count, + warnings_count, + infos_count, infos_count, logs_count, false_positives_count); @@ -28505,14 +28564,16 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, * @param[in] result_hosts_only Whether to only include hosts with results. * @param[in] orig_filtered_result_count Result count. * @param[in] filtered_result_count Result count. - * @param[in] orig_f_holes Result count. - * @param[in] f_holes Result count. - * @param[in] orig_f_infos Result count. - * @param[in] f_infos Result count. - * @param[in] orig_f_logs Result count. - * @param[in] f_logs Result count. - * @param[in] orig_f_warnings Result count. - * @param[in] f_warnings Result count. + * @param[in] orig_f_criticals Result count. + * @param[in] f_criticals Result count. + * @param[in] orig_f_infos Result count. + * @param[in] f_holes Result count. + * @param[in] orig_f_infos Result count. + * @param[in] f_infos Result count. + * @param[in] orig_f_logs Result count. + * @param[in] f_logs Result count. + * @param[in] orig_f_warnings Result count. + * @param[in] f_warnings Result count. * @param[in] orig_f_false_positives Result count. * @param[in] f_false_positives Result count. * @param[in] f_compliance_yes filtered compliant count. @@ -28533,6 +28594,7 @@ print_report_delta_xml (FILE *out, iterator_t *results, const char *sort_field, int result_hosts_only, int *orig_filtered_result_count, int *filtered_result_count, + int *orig_f_criticals, int *f_criticals, int *orig_f_holes, int *f_holes, int *orig_f_infos, int *f_infos, int *orig_f_logs, int *f_logs, @@ -28547,6 +28609,7 @@ print_report_delta_xml (FILE *out, iterator_t *results, GTree *ports; *orig_f_holes = *f_holes; + *orig_f_criticals = *f_criticals; *orig_f_infos = *f_infos; *orig_f_logs = *f_logs; *orig_f_warnings = *f_warnings; @@ -28595,6 +28658,11 @@ print_report_delta_xml (FILE *out, iterator_t *results, level = result_iterator_level (results); (*orig_filtered_result_count)++; (*filtered_result_count)++; + if (strcmp (level, "Critical") == 0) + { + (*orig_f_criticals)++; + (*f_criticals)++; + } if (strcmp (level, "High") == 0) { (*orig_f_holes)++; @@ -28736,9 +28804,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, array_t *result_hosts; int reuse_result_iterator; iterator_t results, delta_results; - int holes, infos, logs, warnings, false_positives; - int f_holes, f_infos, f_logs, f_warnings, f_false_positives; - int orig_f_holes, orig_f_infos, orig_f_logs; + int criticals, holes, infos, logs, warnings, false_positives; + int f_criticals, f_holes, f_infos, f_logs, f_warnings, f_false_positives; + int orig_f_criticals, orig_f_holes, orig_f_infos, orig_f_logs; int orig_f_warnings, orig_f_false_positives, orig_filtered_result_count; int search_phrase_exact, apply_overrides, count_filtered; double severity, f_severity; @@ -28747,7 +28815,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, GString *filters_buffer, *filters_extra_buffer, *host_summary_buffer; gchar *term_value; GHashTable *f_host_ports; - GHashTable *f_host_holes, *f_host_warnings, *f_host_infos; + GHashTable *f_host_criticals, *f_host_holes, *f_host_warnings, *f_host_infos; GHashTable *f_host_logs, *f_host_false_positives; GHashTable *f_host_compliant, *f_host_notcompliant; GHashTable *f_host_incomplete, *f_host_undefined; @@ -28769,8 +28837,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, f_compliance_count = 0; orig_filtered_result_count = 0; orig_f_false_positives = orig_f_warnings = orig_f_logs = orig_f_infos = 0; - orig_f_holes = 0; + orig_f_holes = orig_f_criticals = 0; f_host_ports = NULL; + f_host_criticals = NULL; f_host_holes = NULL; f_host_warnings = NULL; f_host_infos = NULL; @@ -28850,7 +28919,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, max_results = manage_max_rows (max_results); - levels = levels ? levels : g_strdup ("hmlgdf"); + levels = levels ? levels : g_strdup ("chmlgdf"); if (task && (task_uuid (task, &tsk_uuid) || task_usage_type(task, &tsk_usage_type))) { @@ -28966,16 +29035,16 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { if (delta == 0) { - int total_holes, total_infos, total_logs; + int total_criticals, total_holes, total_infos, total_logs; int total_warnings, total_false_positives; get_data_t *all_results_get; all_results_get = report_results_get_data (1, -1, 0, 0); - report_counts_id (report, &total_holes, &total_infos, - &total_logs, &total_warnings, + report_counts_id (report, &total_criticals, &total_holes, + &total_infos, &total_logs, &total_warnings, &total_false_positives, NULL, all_results_get, NULL); - total_result_count = total_holes + total_infos + total_result_count = total_criticals + total_holes + total_infos + total_logs + total_warnings + total_false_positives; get_data_reset (all_results_get); @@ -28995,10 +29064,10 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { /* Beware, we're using the full variables temporarily here, but * report_counts_id counts the filtered results. */ - report_counts_id (report, &holes, &infos, &logs, &warnings, + report_counts_id (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, NULL, get, NULL); - filtered_result_count = holes + infos + logs + warnings + filtered_result_count = criticals + holes + infos + logs + warnings + false_positives; } @@ -29065,6 +29134,8 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { + if (strchr (levels, 'c')) + g_string_append (filters_extra_buffer, "Critical"); if (strchr (levels, 'h')) g_string_append (filters_extra_buffer, "High"); if (strchr (levels, 'm')) @@ -29379,19 +29450,19 @@ print_report_xml_start (report_t report, report_t delta, task_t task, /* We're getting all the filtered results, so we can count them as we * print them, to save time. */ - report_counts_id_full (report, &holes, &infos, &logs, + report_counts_id_full (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, - get, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + get, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - f_holes = f_infos = f_logs = f_warnings = 0; + f_criticals = f_holes = f_infos = f_logs = f_warnings = 0; f_false_positives = f_severity = 0; } else - report_counts_id_full (report, &holes, &infos, &logs, + report_counts_id_full (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, get, NULL, - &f_holes, &f_infos, &f_logs, &f_warnings, - &f_false_positives, &f_severity); + &f_criticals, &f_holes, &f_infos, &f_logs, + &f_warnings, &f_false_positives, &f_severity); } /* Results. */ @@ -29455,6 +29526,8 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { + f_host_criticals = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); f_host_holes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); f_host_warnings = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -29478,6 +29551,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, sort_field, result_hosts_only, &orig_filtered_result_count, &filtered_result_count, + &orig_f_criticals, &f_criticals, &orig_f_holes, &f_holes, &orig_f_infos, &f_infos, &orig_f_logs, &f_logs, @@ -29587,6 +29661,12 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (count_filtered) f_logs++; } + else if (strcasecmp (level, "critical") == 0) + { + f_host_result_counts = f_host_criticals; + if (count_filtered) + f_criticals++; + } else if (strcasecmp (level, "high") == 0) { f_host_result_counts = f_host_holes; @@ -29701,24 +29781,32 @@ print_report_xml_start (report_t report, report_t delta, task_t task, PRINT (out, "" "%i" - "%i" - "%i" + "%i" + "%i" + "%i" + "%i" + "%i" "%i" - "%i" + "%i" + "%i" "" "%i" "" "", orig_filtered_result_count, + (strchr (levels, 'c') ? orig_f_criticals : 0), (strchr (levels, 'h') ? orig_f_holes : 0), + (strchr (levels, 'h') ? orig_f_holes : 0), + (strchr (levels, 'l') ? orig_f_infos : 0), (strchr (levels, 'l') ? orig_f_infos : 0), (strchr (levels, 'g') ? orig_f_logs : 0), (strchr (levels, 'm') ? orig_f_warnings : 0), + (strchr (levels, 'm') ? orig_f_warnings : 0), (strchr (levels, 'f') ? orig_f_false_positives : 0)); else { if (count_filtered) - filtered_result_count = f_holes + f_infos + f_logs + filtered_result_count = f_criticals + f_holes + f_infos + f_logs + f_warnings + false_positives; PRINT (out, @@ -29726,10 +29814,17 @@ print_report_xml_start (report_t report, report_t delta, task_t task, "%i" "%i" "%i" - "%i%i" - "%i%i" + "" + "%i" + "%i" + "" + "%i%i" + "%i%i" + "%i%i" + "%i%i" "%i%i" - "%i%i" + "%i%i" + "%i%i" "" "%i" "%i" @@ -29738,14 +29833,22 @@ print_report_xml_start (report_t report, report_t delta, task_t task, total_result_count, total_result_count, filtered_result_count, + criticals, + (strchr (levels, 'c') ? f_criticals : 0), + holes, + (strchr (levels, 'h') ? f_holes : 0), holes, (strchr (levels, 'h') ? f_holes : 0), infos, (strchr (levels, 'l') ? f_infos : 0), + infos, + (strchr (levels, 'l') ? f_infos : 0), logs, (strchr (levels, 'g') ? f_logs : 0), warnings, (strchr (levels, 'm') ? f_warnings : 0), + warnings, + (strchr (levels, 'm') ? f_warnings : 0), false_positives, (strchr (levels, 'f') ? f_false_positives : 0)); @@ -29789,6 +29892,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, lean, host_summary_buffer, f_host_ports, + f_host_criticals, f_host_holes, f_host_warnings, f_host_infos, @@ -29819,6 +29923,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, lean, host_summary_buffer, f_host_ports, + f_host_criticals, f_host_holes, f_host_warnings, f_host_infos, @@ -29841,6 +29946,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { + g_hash_table_destroy (f_host_criticals); g_hash_table_destroy (f_host_holes); g_hash_table_destroy (f_host_warnings); g_hash_table_destroy (f_host_infos); @@ -29968,6 +30074,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { + g_hash_table_destroy (f_host_criticals); g_hash_table_destroy (f_host_holes); g_hash_table_destroy (f_host_warnings); g_hash_table_destroy (f_host_infos); @@ -30917,20 +31024,22 @@ parse_osp_report (task_t task, report_t report, const char *report_xml) /** * @brief Return the trend of a task, given counts. * - * @param[in] holes_a Number of holes on earlier report. - * @param[in] warns_a Number of warnings on earlier report. - * @param[in] infos_a Number of infos on earlier report. - * @param[in] severity_a Severity of earlier report. - * @param[in] holes_b Number of holes on later report. - * @param[in] warns_b Number of warnings on later report. - * @param[in] infos_b Number of infos on later report. - * @param[in] severity_b Severity of later report. + * @param[in] criticals_a Number of criticals on earlier report. + * @param[in] holes_a Number of holes on earlier report. + * @param[in] warns_a Number of warnings on earlier report. + * @param[in] infos_a Number of infos on earlier report. + * @param[in] severity_a Severity of earlier report. + * @param[in] criticals_b Number of criticals on later report. + * @param[in] holes_b Number of holes on later report. + * @param[in] warns_b Number of warnings on later report. + * @param[in] infos_b Number of infos on later report. + * @param[in] severity_b Severity of later report. * * @return "up", "down", "more", "less", "same" or if too few reports "". */ static const char * -task_trend_calc (int holes_a, int warns_a, int infos_a, double severity_a, - int holes_b, int warns_b, int infos_b, double severity_b) +task_trend_calc (int criticals_a, int holes_a, int warns_a, int infos_a, double severity_a, + int criticals_b, int holes_b, int warns_b, int infos_b, double severity_b) { int threat_a, threat_b; @@ -30944,7 +31053,9 @@ task_trend_calc (int holes_a, int warns_a, int infos_a, double severity_a, /* Calculate trend. */ - if (holes_a > 0) + if (criticals_a > 0) + threat_a = 5; + else if (holes_a > 0) threat_a = 4; else if (warns_a > 0) threat_a = 3; @@ -30953,7 +31064,9 @@ task_trend_calc (int holes_a, int warns_a, int infos_a, double severity_a, else threat_a = 1; - if (holes_b > 0) + if (criticals_b > 0) + threat_b = 5; + else if (holes_b > 0) threat_b = 4; else if (warns_b > 0) threat_b = 3; @@ -30972,6 +31085,15 @@ task_trend_calc (int holes_a, int warns_a, int infos_a, double severity_a, /* Check if the threat count changed in the highest level. */ + if (criticals_a) + { + if (criticals_a > criticals_b) + return "more"; + if (criticals_a < criticals_b) + return "less"; + return "same"; + } + if (holes_a) { if (holes_a > holes_b) @@ -31005,21 +31127,23 @@ task_trend_calc (int holes_a, int warns_a, int infos_a, double severity_a, /** * @brief Return the trend of a task, given counts. * - * @param[in] iterator Task iterator. - * @param[in] holes_a Number of holes on earlier report. - * @param[in] warns_a Number of warnings on earlier report. - * @param[in] infos_a Number of infos on earlier report. - * @param[in] severity_a Severity score of earlier report. - * @param[in] holes_b Number of holes on later report. - * @param[in] warns_b Number of warnings on later report. - * @param[in] infos_b Number of infos on later report. + * @param[in] iterator Task iterator. + * @param[in] criticals_a Number of criticals on earlier report. + * @param[in] holes_a Number of holes on earlier report. + * @param[in] warns_a Number of warnings on earlier report. + * @param[in] infos_a Number of infos on earlier report. + * @param[in] severity_a Severity score of earlier report. + * @param[in] criticals_b Number of criticals on later report. + * @param[in] holes_b Number of holes on later report. + * @param[in] warns_b Number of warnings on later report. + * @param[in] infos_b Number of infos on later report. * @param[in] severity_b Severity score of later report. * * @return "up", "down", "more", "less", "same" or if too few reports "". */ const char * -task_iterator_trend_counts (iterator_t *iterator, int holes_a, int warns_a, - int infos_a, double severity_a, int holes_b, +task_iterator_trend_counts (iterator_t *iterator, int criticals_a, int holes_a, int warns_a, + int infos_a, double severity_a, int criticals_b, int holes_b, int warns_b, int infos_b, double severity_b) { /* Ensure there are enough reports. */ @@ -31031,8 +31155,8 @@ task_iterator_trend_counts (iterator_t *iterator, int holes_a, int warns_a, if (task_iterator_run_status (iterator) == TASK_STATUS_RUNNING) return ""; - return task_trend_calc (holes_a, warns_a, infos_a, severity_a, - holes_b, warns_b, infos_b, severity_b); + return task_trend_calc (criticals_a, holes_a, warns_a, infos_a, severity_a, + criticals_b, holes_b, warns_b, infos_b, severity_b); } /** @@ -38205,9 +38329,9 @@ create_note (const char* active, const char* nvt, const char* text, if (text == NULL) return -1; - if (threat && strcmp (threat, "High") && strcmp (threat, "Medium") - && strcmp (threat, "Low") && strcmp (threat, "Log") - && strcmp (threat, "")) + if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") + && strcmp (threat, "Medium") && strcmp (threat, "Low") + && strcmp (threat, "Log") && strcmp (threat, "")) return -1; quoted_text = sql_insert (text); @@ -38227,6 +38351,8 @@ create_note (const char* active, const char* nvt, const char* text, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; + else if (strcmp (threat, "Critical") == 0) + severity_dbl = 0.1; else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -38461,9 +38587,10 @@ modify_note (const gchar *note_id, const char *active, const char *nvt, if (nvt && !nvt_exists (nvt)) return 4; - if (threat && strcmp (threat, "High") && strcmp (threat, "Medium") - && strcmp (threat, "Low") && strcmp (threat, "Log") - && strcmp (threat, "Alarm") && strcmp (threat, "")) + if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") + && strcmp (threat, "Medium") && strcmp (threat, "Low") + && strcmp (threat, "Log") && strcmp (threat, "Alarm") + && strcmp (threat, "")) return -1; if (port && validate_results_port (port)) @@ -38487,6 +38614,8 @@ modify_note (const gchar *note_id, const char *active, const char *nvt, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; + else if (strcmp (threat, "Critical") == 0) + severity_dbl = 0.1; else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39193,14 +39322,15 @@ create_override (const char* active, const char* nvt, const char* text, if (port && validate_results_port (port)) return 2; - if (threat && strcmp (threat, "High") && strcmp (threat, "Medium") - && strcmp (threat, "Low") && strcmp (threat, "Log") - && strcmp (threat, "Alarm") && strcmp (threat, "")) + if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") + && strcmp (threat, "Medium") && strcmp (threat, "Low") + && strcmp (threat, "Log") && strcmp (threat, "Alarm") + && strcmp (threat, "")) return -1; - if (new_threat && strcmp (new_threat, "High") && strcmp (new_threat, "Medium") - && strcmp (new_threat, "Low") && strcmp (new_threat, "Log") - && strcmp (new_threat, "False Positive") + if (new_threat && strcmp (threat, "Critical") && strcmp (new_threat, "High") + && strcmp (new_threat, "Medium") && strcmp (new_threat, "Low") + && strcmp (new_threat, "Log") && strcmp (new_threat, "False Positive") && strcmp (new_threat, "Alarm") && strcmp (new_threat, "")) return -1; @@ -39217,6 +39347,8 @@ create_override (const char* active, const char* nvt, const char* text, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; + else if (strcmp (threat, "Critical") == 0) + severity_dbl = 0.1; else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39249,6 +39381,8 @@ create_override (const char* active, const char* nvt, const char* text, { if (strcmp (new_threat, "Alarm") == 0) new_severity_dbl = 10.0; + else if (strcmp (new_threat, "Critical") == 0) + new_severity_dbl = 10.0; else if (strcmp (new_threat, "High") == 0) new_severity_dbl = 10.0; else if (strcmp (new_threat, "Medium") == 0) @@ -39567,6 +39701,8 @@ modify_override (const gchar *override_id, const char *active, const char *nvt, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; + else if (strcmp (threat, "Critical") == 0) + severity_dbl = 0.1; else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39599,6 +39735,8 @@ modify_override (const gchar *override_id, const char *active, const char *nvt, { if (strcmp (new_threat, "Alarm") == 0) new_severity_dbl = 10.0; + else if (strcmp (new_threat, "Critical") == 0) + new_severity_dbl = 10.0; else if (strcmp (new_threat, "High") == 0) new_severity_dbl = 10.0; else if (strcmp (new_threat, "Medium") == 0) diff --git a/src/manage_utils.c b/src/manage_utils.c index 674eb0008..5bb51df2b 100644 --- a/src/manage_utils.c +++ b/src/manage_utils.c @@ -211,7 +211,9 @@ level_min_severity (const char *level) else if (strcasecmp (level, "Error") == 0) return SEVERITY_ERROR; - if (strcasecmp (level, "high") == 0) + if (strcasecmp (level, "critical") == 0) + return 9.0; + else if (strcasecmp (level, "high") == 0) return 7.0; else if (strcasecmp (level, "medium") == 0) return 4.0; @@ -241,8 +243,10 @@ level_max_severity (const char *level) else if (strcasecmp (level, "Error") == 0) return SEVERITY_ERROR; - if (strcasecmp (level, "high") == 0) + if (strcasecmp (level, "critical") == 0) return 10.0; + else if (strcasecmp (level, "high") == 0) + return 8.9; else if (strcasecmp (level, "medium") == 0) return 6.9; else if (strcasecmp (level, "low") == 0) From a0affb39ca134e3ff8dfe290c705590fb3655664 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Tue, 10 Dec 2024 19:40:14 +0100 Subject: [PATCH 61/64] Use CVSS3_RATINGS toggle to apply 3.x rating scale. --- src/gmp.c | 74 +++- src/manage.c | 24 +- src/manage.h | 21 +- src/manage_pg.c | 56 ++- src/manage_sql.c | 860 +++++++++++++++++++++++++++++++++++++++------ src/manage_utils.c | 13 +- 6 files changed, 915 insertions(+), 133 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 87ce78b1c..533026a4f 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -8506,8 +8506,8 @@ buffer_override_xml (GString *buffer, iterator_t *overrides, override_iterator_active (overrides), strlen (excerpt) < strlen (text), excerpt, - override_iterator_severity (overrides) - && override_iterator_threat (overrides) + (override_iterator_severity (overrides) + && override_iterator_threat (overrides)) ? override_iterator_threat (overrides) : "", override_iterator_severity (overrides) @@ -8601,7 +8601,8 @@ buffer_override_xml (GString *buffer, iterator_t *overrides, ? override_iterator_hosts (overrides) : "", override_iterator_port (overrides) ? override_iterator_port (overrides) : "", - override_iterator_threat (overrides) + (override_iterator_severity (overrides) + && override_iterator_threat (overrides)) ? override_iterator_threat (overrides) : "", override_iterator_severity (overrides) ? override_iterator_severity (overrides) : "", @@ -15195,7 +15196,11 @@ handle_get_reports (gmp_parser_t *gmp_parser, GError **error) ("apply_overrides=%i min_qod=%i levels=%s compliance_levels=%s", overrides, min_qod, +#if CVSS3_RATINGS == 1 levels ? levels : "chmlgdf", +#else + levels ? levels : "hmlgdf", +#endif compliance_levels ? compliance_levels : "yniu"); g_free (compliance_levels); @@ -18491,8 +18496,11 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) report_t running_report; char *owner, *observers; int target_in_trash, scanner_in_trash; - int criticals = 0, holes = 0, infos = 0, logs = 0, warnings = 0; - int criticals_2 = 0, holes_2 = 0, infos_2 = 0, warnings_2 = 0; + int holes = 0, infos = 0, logs = 0, warnings = 0; + int holes_2 = 0, infos_2 = 0, warnings_2 = 0; +#if CVSS3_RATINGS == 1 + int criticals = 0, criticals_2 = 0; +#endif int false_positives = 0, task_scanner_type; int target_available, config_available; int scanner_available; @@ -18598,13 +18606,20 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) if (first_report_id && (get_tasks_data->get.trash == 0)) { // TODO Could skip this count for tasks page. +#if CVSS3_RATINGS == 1 if (report_counts (first_report_id, &criticals_2, &holes_2, &infos_2, &logs, &warnings_2, &false_positives, &severity_2, apply_overrides, min_qod)) - g_error ("%s: GET_TASKS: error getting counts for" - " first report, aborting", - __func__); +#else + if (report_counts (first_report_id, + &holes_2, &infos_2, &logs, + &warnings_2, &false_positives, + &severity_2, apply_overrides, min_qod)) +#endif + g_error ("%s: GET_TASKS: error getting counts for" + " first report, aborting", + __func__); } second_last_report_id = task_second_last_report_id (index); @@ -18614,11 +18629,20 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) * doing the count again. */ if (((first_report_id == NULL) || (strcmp (second_last_report_id, first_report_id))) +#if CVSS3_RATINGS == 1 && report_counts (second_last_report_id, &criticals_2, &holes_2, &infos_2, &logs, &warnings_2, &false_positives, &severity_2, - apply_overrides, min_qod)) + apply_overrides, min_qod) +#else + && report_counts (second_last_report_id, + &holes_2, &infos_2, + &logs, &warnings_2, + &false_positives, &severity_2, + apply_overrides, min_qod) +#endif + ) g_error ("%s: GET_TASKS: error getting counts for" " second report, aborting", __func__); @@ -18667,6 +18691,7 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) && strcmp (last_report_id, second_last_report_id))) { +#if CVSS3_RATINGS == 1 if (report_counts (last_report_id, &criticals, &holes, &infos, &logs, @@ -18675,10 +18700,22 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) g_error ("%s: GET_TASKS: error getting counts for" " last report, aborting", __func__); +#else + if (report_counts + (last_report_id, + &holes, &infos, &logs, + &warnings, &false_positives, &severity, + apply_overrides, min_qod)) + g_error ("%s: GET_TASKS: error getting counts for" + " last report, aborting", + __func__); +#endif } else { +#if CVSS3_RATINGS == 1 criticals = criticals_2; +#endif holes = holes_2; infos = infos_2; warnings = warnings_2; @@ -18732,7 +18769,9 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) "%s" "%s" "" +#if CVSS3_RATINGS == 1 "%i" +#endif "%i" "%i" "%i" @@ -18753,7 +18792,9 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) timestamp, scan_start, scan_end, +#if CVSS3_RATINGS == 1 criticals, +#endif holes, holes, infos, @@ -18912,11 +18953,19 @@ handle_get_tasks (gmp_parser_t *gmp_parser, GError **error) progress_xml, task_iterator_total_reports (&tasks), task_iterator_finished_reports (&tasks), +#if CVSS3_RATINGS == 1 get_tasks_data->get.trash ? "" : task_iterator_trend_counts (&tasks, criticals, holes, warnings, infos, severity, criticals_2, holes_2, warnings_2, infos_2, severity_2), +#else + get_tasks_data->get.trash + ? "" + : task_iterator_trend_counts + (&tasks, 0, holes, warnings, infos, severity, + 0, holes_2, warnings_2, infos_2, severity_2), +#endif task_schedule_xml, current_report, last_report); @@ -19710,6 +19759,7 @@ gmp_xml_handle_result () { create_report_data->result_severity = strdup (""); } +#if CVSS3_RATINGS == 1 else if (strcasecmp (create_report_data->result_threat, "Critical") == 0) { create_report_data->result_severity = strdup ("10.0"); @@ -19718,6 +19768,12 @@ gmp_xml_handle_result () { create_report_data->result_severity = strdup ("8.9"); } +#else + else if (strcasecmp (create_report_data->result_threat, "High") == 0) + { + create_report_data->result_severity = strdup ("10.0"); + } +#endif else if (strcasecmp (create_report_data->result_threat, "Medium") == 0) { create_report_data->result_severity = strdup ("5.0"); diff --git a/src/manage.c b/src/manage.c index 9b7d0cd71..a9a402045 100644 --- a/src/manage.c +++ b/src/manage.c @@ -860,8 +860,10 @@ scanner_type_valid (scanner_type_t scanner_type) const char * threat_message_type (const char *threat) { +#if CVSS3_RATINGS == 1 if (strcasecmp (threat, "Critical") == 0) return "Alarm"; +#endif if (strcasecmp (threat, "High") == 0) return "Alarm"; if (strcasecmp (threat, "Medium") == 0) @@ -888,10 +890,15 @@ threat_message_type (const char *threat) int severity_in_level (double severity, const char *level) { +#if CVSS3_RATINGS == 1 if (strcmp (level, "critical") == 0) return severity >= 9 && severity <= 10; else if (strcmp (level, "high") == 0) return severity >= 7 && severity < 9; +#else + if (strcmp (level, "high") == 0) + return severity >= 7 && severity <= 10; +#endif else if (strcmp (level, "medium") == 0) return severity >= 4 && severity < 7; else if (strcmp (level, "low") == 0) @@ -923,8 +930,10 @@ severity_to_level (double severity, int mode) { if (mode == 1) return "Alarm"; +#if CVSS3_RATINGS == 1 else if (severity_in_level (severity, "critical")) return "Critical"; +#endif else if (severity_in_level (severity, "high")) return "High"; else if (severity_in_level (severity, "medium")) @@ -1307,11 +1316,20 @@ severity_data_range_count (const severity_data_t* severity_data, * @param[out] mediums The number of Medium severity results. * @param[out] highs The number of High severity results. * @param[out] criticals The number of Critical severity results. + * Only if CVSS3_RATINGS is enabled. */ void severity_data_level_counts (const severity_data_t *severity_data, - int *errors, int *false_positives, - int *logs, int *lows, int *mediums, int *highs, int* criticals) + int *errors, + int *false_positives, + int *logs, + int *lows, + int *mediums, + int *highs +#if CVSS3_RATINGS == 1 + ,int* criticals +#endif + ) { if (errors) *errors @@ -1349,11 +1367,13 @@ severity_data_level_counts (const severity_data_t *severity_data, level_min_severity ("high"), level_max_severity ("high")); +#if CVSS3_RATINGS == 1 if (criticals) *criticals = severity_data_range_count (severity_data, level_min_severity ("critical"), level_max_severity ("critical")); +#endif } diff --git a/src/manage.h b/src/manage.h index a2667abaf..ce073b277 100644 --- a/src/manage.h +++ b/src/manage.h @@ -902,9 +902,8 @@ int task_last_report (task_t, report_t*); const char * -task_iterator_trend_counts (iterator_t *, int, int, int, int, double, int, int, int, int, - double); - +task_iterator_trend_counts (iterator_t *, int, int, int, int, double, int, int, + int, int, double); int task_schedule_periods (task_t); @@ -1065,9 +1064,15 @@ severity_data_add (severity_data_t*, double); void severity_data_add_count (severity_data_t*, double, int); +#if CVSS3_RATINGS == 1 void severity_data_level_counts (const severity_data_t*, int*, int*, int*, int*, int*, int*, int*); +#else +void +severity_data_level_counts (const severity_data_t*, + int*, int*, int*, int*, int*, int*); +#endif /* General task facilities. */ @@ -1337,6 +1342,7 @@ int report_scan_result_count (report_t, const char*, const char*, int, const char*, const char*, int, int, int*); +#if CVSS3_RATINGS == 1 int report_counts (const char*, int*, int*, int*, int*, int*, int*, double*, int, int); @@ -1344,6 +1350,15 @@ report_counts (const char*, int*, int*, int*, int*, int*, int*, double*, int report_counts_id (report_t, int*, int*, int*, int*, int*, int*, double*, const get_data_t*, const char*); +#else +int +report_counts (const char*, int*, int*, int*, int*, int*, double*, + int, int); + +int +report_counts_id (report_t, int*, int*, int*, int*, int*, double*, + const get_data_t*, const char*); +#endif int report_counts_id_no_filt (report_t, int*, int*, int*, int*, int*, int*, diff --git a/src/manage_pg.c b/src/manage_pg.c index 704615c5c..ada46ee6c 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -230,10 +230,15 @@ manage_create_sql_functions () " v := " G_STRINGIFY (SEVERITY_ERROR) ";" " ELSE" " CASE" +#if CVSS3_RATINGS == 1 " WHEN lower (lvl) = 'critical' THEN" " v := 10.0;" " WHEN lower (lvl) = 'high' THEN" " v := 8.9;" +#else + " WHEN lower (lvl) = 'high' THEN" + " v := 10.0;" +#endif " WHEN lower (lvl) = 'medium' THEN" " v := 6.9;" " WHEN lower (lvl) = 'low' THEN" @@ -264,8 +269,10 @@ manage_create_sql_functions () " v := " G_STRINGIFY (SEVERITY_ERROR) ";" " ELSE" " CASE" +#if CVSS3_RATINGS == 1 " WHEN lower (lvl) = 'critical' THEN" " v := 9.0;" +#endif " WHEN lower (lvl) = 'high' THEN" " v := 7.0;" " WHEN lower (lvl) = 'medium' THEN" @@ -498,6 +505,7 @@ manage_create_sql_functions () "$$ LANGUAGE plpgsql" " IMMUTABLE;"); +#if CVSS3_RATINGS == 1 sql ("CREATE OR REPLACE FUNCTION order_threat (text)" " RETURNS integer AS $$" " BEGIN" @@ -521,7 +529,29 @@ manage_create_sql_functions () " END;" "$$ LANGUAGE plpgsql" " IMMUTABLE;"); - +#else + sql ("CREATE OR REPLACE FUNCTION order_threat (text)" + " RETURNS integer AS $$" + " BEGIN" + " IF $1 = 'High' THEN" + " RETURN 1;" + " ELSIF $1 = 'Medium' THEN" + " RETURN 2;" + " ELSIF $1 = 'Low' THEN" + " RETURN 3;" + " ELSIF $1 = 'Log' THEN" + " RETURN 4;" + " ELSIF $1 = 'False Positive' THEN" + " RETURN 5;" + " ELSIF $1 = 'None' THEN" + " RETURN 6;" + " ELSE" + " RETURN 7;" + " END IF;" + " END;" + "$$ LANGUAGE plpgsql" + " IMMUTABLE;"); +#endif sql ("CREATE OR REPLACE FUNCTION severity_to_type (double precision)" " RETURNS text AS $$" " BEGIN" @@ -1370,8 +1400,10 @@ manage_create_sql_functions () " second_last_report integer;" " severity_a double precision;" " severity_b double precision;" +#if CVSS3_RATINGS == 1 " critical_a bigint;" " critical_b bigint;" +#endif " high_a bigint;" " high_b bigint;" " medium_a bigint;" @@ -1407,10 +1439,12 @@ manage_create_sql_functions () " RETURN 'down'::text;" " END IF;" /* Calculate trend. */ +#if CVSS3_RATINGS == 1 " critical_a := report_severity_count (last_report, $2, $3," " 'critical');" " critical_b := report_severity_count (second_last_report, $2, $3," " 'critical');" +#endif " high_a := report_severity_count (last_report, $2, $3," " 'high');" " high_b := report_severity_count (second_last_report, $2, $3," @@ -1423,9 +1457,13 @@ manage_create_sql_functions () " 'low');" " low_b := report_severity_count (second_last_report, $2, $3," " 'low');" +#if CVSS3_RATINGS == 1 " IF critical_a > 0 THEN" " threat_a := 5;" " ELSEIF high_a > 0 THEN" +#else + " IF high_a > 0 THEN" +#endif " threat_a := 4;" " ELSIF medium_a > 0 THEN" " threat_a := 3;" @@ -1434,9 +1472,13 @@ manage_create_sql_functions () " ELSE" " threat_a := 1;" " END IF;" +#if CVSS3_RATINGS == 1 " IF critical_b > 0 THEN" " threat_b := 5;" " ELSEIF high_b > 0 THEN" +#else + " IF high_b > 0 THEN" +#endif " threat_b := 4;" " ELSIF medium_b > 0 THEN" " threat_b := 3;" @@ -1452,6 +1494,7 @@ manage_create_sql_functions () " RETURN 'down'::text;" " END IF;" /* Check if the threat count changed. */ +#if CVSS3_RATINGS == 1 " IF critical_a > 0 THEN" " IF critical_a > critical_b THEN" " RETURN 'more'::text;" @@ -1460,6 +1503,7 @@ manage_create_sql_functions () " END IF;" " RETURN 'same'::text;" " END IF;" +#endif " IF high_a > 0 THEN" " IF high_a > high_b THEN" " RETURN 'more'::text;" @@ -1598,12 +1642,18 @@ manage_create_sql_functions () " text)" " RETURNS boolean AS $$" " (SELECT CASE lower ($2)" +#if CVSS3_RATINGS == 1 " WHEN 'critical'" " THEN $1 >= 9" " AND $1 <= 10" " WHEN 'high'" " THEN $1 >= 7" " AND $1 < 9" +#else + " WHEN 'high'" + " THEN $1 >= 7" + " AND $1 <= 10" +#endif " WHEN 'medium'" " THEN $1 >= 4" " AND $1 < 7" @@ -1645,9 +1695,11 @@ manage_create_sql_functions () " THEN (SELECT CASE" " WHEN $2 = 1" " THEN 'Alarm'" +#if CVSS3_RATINGS == 1 " WHEN severity_in_level ($1::double precision," " 'critical')" " THEN 'Critical'" +#endif " WHEN severity_in_level ($1::double precision," " 'high')" " THEN 'High'" @@ -1678,8 +1730,10 @@ manage_create_sql_functions () " THEN (SELECT CASE" " WHEN $2 = 1" " THEN 'Alarm'" +#if CVSS3_RATINGS == 1 " WHEN severity_in_level ($1, 'critical')" " THEN 'Critical'" +#endif " WHEN severity_in_level ($1, 'high')" " THEN 'High'" " WHEN severity_in_level ($1, 'medium')" diff --git a/src/manage_sql.c b/src/manage_sql.c index 134aa8842..4578ce058 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -250,10 +250,17 @@ check_for_updated_scap (); static void check_for_updated_cert (); +#if CVSS3_RATINGS == 1 static int report_counts_id_full (report_t, int *, int *, int *, int *, int *, int *, double *, const get_data_t*, const char* , int *, int *, int *, int *, int *, int *, double *); +#else +static int +report_counts_id_full (report_t, int *, int *, int *, int *, int *, + double *, const get_data_t*, const char* , + int *, int *, int *, int *, int *, double *); +#endif static gboolean find_group_with_permission (const char *, group_t *, const char *); @@ -2604,7 +2611,9 @@ keyword_applies_to_column (keyword_t *keyword, const char* column) && (strstr ("False Positive", keyword->string) == NULL) && (strstr ("Error", keyword->string) == NULL) && (strstr ("Alarm", keyword->string) == NULL) +#if CVSS3_RATINGS == 1 && (strstr ("Critical", keyword->string) == NULL) +#endif && (strstr ("High", keyword->string) == NULL) && (strstr ("Medium", keyword->string) == NULL) && (strstr ("Low", keyword->string) == NULL) @@ -3047,7 +3056,10 @@ filter_clause (const char* type, const char* filter, || strcmp (keyword->string, "low_per_host") == 0 || strcmp (keyword->string, "medium_per_host") == 0 || strcmp (keyword->string, "high_per_host") == 0 - || strcmp (keyword->string, "critical_per_host") == 0) +#if CVSS3_RATINGS == 1 + || strcmp (keyword->string, "critical_per_host") == 0 +#endif + ) { gchar *column; column = columns_select_column (select_columns, @@ -3084,7 +3096,9 @@ filter_clause (const char* type, const char* filter, || (strcmp (keyword->string, "published") == 0) || (strcmp (keyword->string, "qod") == 0) || (strcmp (keyword->string, "cves") == 0) +#if CVSS3_RATINGS == 1 || (strcmp (keyword->string, "critical") == 0) +#endif || (strcmp (keyword->string, "high") == 0) || (strcmp (keyword->string, "medium") == 0) || (strcmp (keyword->string, "low") == 0) @@ -3242,7 +3256,10 @@ filter_clause (const char* type, const char* filter, || strcmp (keyword->string, "low_per_host") == 0 || strcmp (keyword->string, "medium_per_host") == 0 || strcmp (keyword->string, "high_per_host") == 0 - || strcmp (keyword->string, "critical_per_host") == 0) +#if CVSS3_RATINGS == 1 + || strcmp (keyword->string, "critical_per_host") == 0 +#endif + ) { gchar *column; column = columns_select_column (select_columns, @@ -3279,7 +3296,9 @@ filter_clause (const char* type, const char* filter, || (strcmp (keyword->string, "published") == 0) || (strcmp (keyword->string, "qod") == 0) || (strcmp (keyword->string, "cves") == 0) +#if CVSS3_RATINGS == 1 || (strcmp (keyword->string, "critical") == 0) +#endif || (strcmp (keyword->string, "high") == 0) || (strcmp (keyword->string, "medium") == 0) || (strcmp (keyword->string, "low") == 0) @@ -14540,7 +14559,7 @@ condition_met (task_t task, report_t report, alert_t alert, { char *filter_id, *count_string; report_t last_report; - int criticals, holes, infos, logs, warnings, false_positives; + int criticals = 0, holes, infos, logs, warnings, false_positives; int count; double severity; @@ -14587,10 +14606,15 @@ condition_met (task_t task, report_t report, alert_t alert, memset (&get, 0, sizeof (get_data_t)); get.type = "result"; get.filt_id = filter_id; +#if CVSS3_RATINGS == 1 report_counts_id (last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); - +#else + report_counts_id (last_report, &holes, &infos, &logs, + &warnings, &false_positives, &severity, + &get, NULL); +#endif db_count = criticals + holes + infos + logs + warnings + false_positives; @@ -14608,7 +14632,7 @@ condition_met (task_t task, report_t report, alert_t alert, { char *direction, *filter_id, *count_string; report_t last_report; - int criticals, holes, infos, logs, warnings, false_positives; + int criticals = 0, holes, infos, logs, warnings, false_positives; int count; double severity; @@ -14643,10 +14667,15 @@ condition_met (task_t task, report_t report, alert_t alert, get_data_t get; get.type = "result"; get.filt_id = filter_id; - +#if CVSS3_RATINGS == 1 report_counts_id (last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); +#else + report_counts_id (last_report, &holes, &infos, &logs, + &warnings, &false_positives, &severity, + &get, NULL); +#endif last_count = criticals + holes + infos + logs + warnings + false_positives; @@ -14657,10 +14686,15 @@ condition_met (task_t task, report_t report, alert_t alert, if (second_last_report) { int cmp, second_last_count; - +#if CVSS3_RATINGS == 1 report_counts_id (second_last_report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, &get, NULL); +#else + report_counts_id (second_last_report, &holes, &infos, + &logs, &warnings, &false_positives, + &severity, &get, NULL); +#endif second_last_count = criticals + holes + infos + logs + warnings + false_positives; @@ -15033,13 +15067,23 @@ append_to_task_string (task_t task, const char* field, const char* value) /** * @brief Filter columns for task iterator. */ +#if CVSS3_RATINGS == 1 + #define TASK_ITERATOR_FILTER_COLUMNS \ + { GET_ITERATOR_FILTER_COLUMNS, "status", "total", "first_report", \ + "last_report", "threat", "trend", "severity", "schedule", "next_due", \ + "first", "last", "false_positive", "log", "low", "medium", "high", \ + "critical", "hosts", "result_hosts", "fp_per_host", "log_per_host", \ + "low_per_host", "medium_per_host", "high_per_host", "critical_per_host", \ + "target", "usage_type", "first_report_created", "last_report_created", NULL } +#else #define TASK_ITERATOR_FILTER_COLUMNS \ { GET_ITERATOR_FILTER_COLUMNS, "status", "total", "first_report", \ "last_report", "threat", "trend", "severity", "schedule", "next_due", \ "first", "last", "false_positive", "log", "low", "medium", "high", \ - "critical", "hosts", "result_hosts", "fp_per_host", "log_per_host", \ - "low_per_host", "medium_per_host", "high_per_host", "critical_per_host", \ - "target", "usage_type", "first_report_created", "last_report_created", NULL } + "hosts", "result_hosts", "fp_per_host", "log_per_host", "low_per_host", \ + "medium_per_host", "high_per_host", "target", "usage_type", \ + "first_report_created", "last_report_created", NULL } +#endif /** * @brief Task iterator columns. @@ -15083,6 +15127,7 @@ append_to_task_string (task_t task, const char* field, const char* value) /** * @brief Task iterator WHERE columns. */ +#if CVSS3_RATINGS == 1 #define TASK_ITERATOR_WHERE_COLUMNS_INNER \ { \ "task_threat_level (id, opts.override, opts.min_qod)", \ @@ -15288,8 +15333,195 @@ append_to_task_string (task_t task, const char* field, const char* value) " ORDER BY creation_time DESC LIMIT 1)", \ "last_report_created", \ KEYWORD_TYPE_INTEGER \ - } \ - + } +#else +#define TASK_ITERATOR_WHERE_COLUMNS_INNER \ + { \ + "task_threat_level (id, opts.override, opts.min_qod)", \ + "threat", \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "task_trend (id, opts.override, opts.min_qod)", \ + "trend", \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "task_severity (id, opts.override, opts.min_qod)", \ + "severity", \ + KEYWORD_TYPE_DOUBLE \ + }, \ + { \ + "(SELECT schedules.name FROM schedules" \ + " WHERE schedules.id = tasks.schedule)", \ + "schedule", \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "(CASE WHEN schedule_next_time IS NULL" \ + " THEN -1" \ + " WHEN schedule_next_time = 0 AND tasks.schedule > 0" \ + " THEN (SELECT first_time" \ + " FROM schedules" \ + " WHERE schedules.id = tasks.schedule)" \ + " ELSE schedule_next_time" \ + " END)", \ + "next_due", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(SELECT creation_time FROM reports WHERE task = tasks.id" \ + /* TODO 1 == TASK_STATUS_DONE */ \ + " AND scan_run_status = 1" \ + " ORDER BY creation_time ASC LIMIT 1)", \ + "first", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(SELECT creation_time FROM reports WHERE task = tasks.id" \ + /* TODO 1 == TASK_STATUS_DONE */ \ + " AND scan_run_status = 1" \ + " ORDER BY creation_time DESC LIMIT 1)", \ + "last", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'False Positive')" \ + " END", \ + "false_positive", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod, 'Log')" \ + " END", \ + "log", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod, 'Low')" \ + " END", \ + "low", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod, 'Medium')" \ + " END", \ + "medium", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod, 'High')" \ + " END", \ + "high", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_host_count (task_last_report (id))" \ + " END", \ + "hosts", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " report_result_host_count (task_last_report (id), opts.min_qod)" \ + " END", \ + "result_hosts", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'False Positive') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "fp_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'Log') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "log_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'Low') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "low_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'Medium') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "medium_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "CASE WHEN target IS null OR opts.ignore_severity != 0 THEN 0 ELSE" \ + " coalesce (report_severity_count (task_last_report (id)," \ + " opts.override, opts.min_qod," \ + " 'High') * 1.0" \ + " / nullif (report_result_host_count (task_last_report (id),"\ + " opts.min_qod), 0)," \ + " 0)" \ + " END", \ + "high_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(SELECT name FROM targets WHERE id = target)", \ + "target", \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "(SELECT creation_time FROM reports WHERE task = tasks.id" \ + /* TODO 1 == TASK_STATUS_DONE */ \ + " AND scan_run_status = 1" \ + " ORDER BY creation_time ASC LIMIT 1)", \ + "first_report_created", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(SELECT creation_time FROM reports WHERE task = tasks.id" \ + /* TODO 1 == TASK_STATUS_DONE */ \ + " AND scan_run_status = 1" \ + " ORDER BY creation_time DESC LIMIT 1)", \ + "last_report_created", \ + KEYWORD_TYPE_INTEGER \ + } +#endif /** * @brief Task iterator WHERE columns. */ @@ -21144,7 +21376,7 @@ report_cache_counts (report_t report, int clear_original, int clear_overridden, const char* users_where) { iterator_t cache_iterator; - int criticals, holes, infos, logs, warnings, false_positives; + int holes, infos, logs, warnings, false_positives; double severity; get_data_t *get = NULL; gchar *old_user_id; @@ -21175,9 +21407,14 @@ report_cache_counts (report_t report, int clear_original, int clear_overridden, " AND min_qod = %d", report, user, override, min_qod); } - +#if CVSS3_RATINGS == 1 + int criticals; report_counts_id (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, &severity, get, NULL); +#else + report_counts_id (report, &holes, &infos, &logs, &warnings, + &false_positives, &severity, get, NULL); +#endif get_data_reset (get); g_free (get); @@ -22132,6 +22369,7 @@ report_add_results_array (report_t report, GArray *results) /** * @brief Filter columns for report iterator. */ +#if CVSS3_RATINGS == 1 #define REPORT_ITERATOR_FILTER_COLUMNS \ { ANON_GET_ITERATOR_FILTER_COLUMNS, "task_id", "name", "creation_time", \ "date", "status", "task", "severity", "false_positive", "log", "low", \ @@ -22140,6 +22378,16 @@ report_add_results_array (report_t report, GArray *results) "critical_per_host", "duration", "duration_per_host", "start_time", \ "end_time", "scan_start", "scan_end", "compliance_yes", "compliance_no", \ "compliance_incomplete", "compliant", NULL } +#else +#define REPORT_ITERATOR_FILTER_COLUMNS \ + { ANON_GET_ITERATOR_FILTER_COLUMNS, "task_id", "name", "creation_time", \ + "date", "status", "task", "severity", "false_positive", "log", "low", \ + "medium", "high", "hosts", "result_hosts", "fp_per_host", "log_per_host", \ + "low_per_host", "medium_per_host", "high_per_host", "duration", \ + "duration_per_host", "start_time", "end_time", "scan_start", "scan_end", \ + "compliance_yes", "compliance_no", "compliance_incomplete", \ + "compliant", NULL } +#endif /** * @brief Report iterator columns. */ @@ -22165,6 +22413,7 @@ report_add_results_array (report_t report, GArray *results) /** * @brief Report iterator columns. */ +#if CVSS3_RATINGS == 1 #define REPORT_ITERATOR_WHERE_COLUMNS \ { \ { "run_status_name (scan_run_status)", "status", KEYWORD_TYPE_STRING }, \ @@ -22311,7 +22560,141 @@ report_add_results_array (report_t report, GArray *results) }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ } - +#else +#define REPORT_ITERATOR_WHERE_COLUMNS \ + { \ + { "run_status_name (scan_run_status)", "status", KEYWORD_TYPE_STRING }, \ + { \ + "(SELECT uuid FROM tasks WHERE tasks.id = task)", \ + "task_id", \ + KEYWORD_TYPE_STRING \ + }, \ + { "creation_time", "date", KEYWORD_TYPE_INTEGER }, \ + { "(SELECT name FROM tasks WHERE tasks.id = task)", "task" }, \ + { \ + "report_severity (id, opts.override, opts.min_qod)", \ + "severity", \ + KEYWORD_TYPE_DOUBLE \ + }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod," \ + " 'False Positive')", \ + "false_positive", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod, 'Log')", \ + "log", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod, 'Low')", \ + "low", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod, 'Medium')", \ + "medium", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_severity_count (id, opts.override, opts.min_qod, 'High')", \ + "high", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(SELECT name FROM users WHERE users.id = reports.owner)", \ + "_owner", \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "report_host_count (id)", \ + "hosts", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_result_host_count (id, opts.min_qod)", \ + "result_hosts", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'False Positive') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "fp_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'Log') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "log_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'Low') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "low_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'Medium') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "medium_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "coalesce (report_severity_count (id, opts.override, opts.min_qod," \ + " 'High') * 1.0" \ + " / nullif (report_result_host_count (id, opts.min_qod), 0),"\ + " 0)", \ + "high_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(CASE WHEN (start_time IS NULL or end_time IS NULL)" \ + " THEN NULL ELSE end_time - start_time END)", \ + "duration", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(CASE WHEN (start_time IS NULL or end_time IS NULL" \ + " or report_result_host_count (id, opts.min_qod) = 0)" \ + " THEN NULL" \ + " ELSE (end_time - start_time)" \ + " / report_result_host_count (id, opts.min_qod) END)", \ + "duration_per_host", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_compliance_count (id, 'YES')", \ + "compliance_yes", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_compliance_count (id, 'NO')", \ + "compliance_no", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_compliance_count (id, 'INCOMPLETE')", \ + "compliance_incomplete", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "report_compliance_status (id)", \ + "compliant", \ + KEYWORD_TYPE_STRING \ + }, \ + { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ + } +#endif /** * @brief Generate the extra_tables string for a report iterator. * @@ -22621,11 +23004,13 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append_printf (levels_sql, " AND severity_in_levels (%s", new_severity_sql); +#if CVSS3_RATINGS == 1 if (strchr (levels, 'c')) { g_string_append (levels_sql, ", 'critical'"); count++; } +#endif if (strchr (levels, 'h')) { g_string_append (levels_sql, ", 'high'"); @@ -22660,7 +23045,11 @@ where_levels_auto (const char *levels, const char *new_severity_sql) g_string_append (levels_sql, ")"); +#if CVSS3_RATINGS == 1 if (count == 6) +#else + if (count == 5) +#endif { /* All levels. */ g_string_free (levels_sql, TRUE); @@ -23354,7 +23743,11 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod = filter_term_min_qod (filter); levels = filter_term_value (filter, "levels"); if (levels == NULL) +#if CVSS3_RATINGS == 1 levels = g_strdup ("chmlgdf"); +#else + levels = g_strdup ("hmlgdf"); +#endif compliance_levels = filter_term_value (filter, "compliance_levels"); // Build clause fragments @@ -23380,7 +23773,7 @@ results_extra_where (int trash, report_t report, const gchar* host, min_qod_clause = where_qod (min_qod); - levels_clause = where_levels_auto (levels ? levels : "chmlgdf", + levels_clause = where_levels_auto (levels, given_new_severity_sql ? given_new_severity_sql : new_severity_sql); @@ -25883,6 +26276,7 @@ report_severity_data (report_t report, const char *host, * * @param[in] report_id ID of report. * @param[out] criticals Number of critical messages. + * Only if CVSS3_RATINGS is enabled. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -25895,8 +26289,16 @@ report_severity_data (report_t report, const char *host, * @return 0 on success, -1 on error. */ int -report_counts (const char* report_id, int* criticals, int* holes, int* infos, - int* logs, int* warnings, int* false_positives, double* severity, +report_counts (const char* report_id, +#if CVSS3_RATINGS == 1 + int* criticals, +#endif + int* holes, + int* infos, + int* logs, + int* warnings, + int* false_positives, + double* severity, int override, int min_qod) { report_t report; @@ -25908,8 +26310,13 @@ report_counts (const char* report_id, int* criticals, int* holes, int* infos, // TODO Check if report was found. get = report_results_get_data (1, -1, override, min_qod); +#if CVSS3_RATINGS == 1 ret = report_counts_id (report, criticals, holes, infos, logs, warnings, false_positives, severity, get, NULL); +#else + ret = report_counts_id (report, holes, infos, logs, warnings, + false_positives, severity, get, NULL); +#endif get_data_reset (get); free (get); return ret; @@ -26080,6 +26487,7 @@ cache_report_counts (report_t report, int override, int min_qod, * * @param[in] report Report. * @param[out] criticals Number of critical messages. + * Only if CVSS3_RATINGS is enabled. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -26089,6 +26497,7 @@ cache_report_counts (report_t report, int override, int min_qod, * @param[in] get Get data. * @param[in] host Host to which to limit the count. * @param[out] filtered_criticals Number of critical messages after filtering. + * Only if CVSS3_RATINGS is enabled. * @param[out] filtered_holes Number of hole messages after filtering. * @param[out] filtered_infos Number of info messages after filtering. * @param[out] filtered_logs Number of log messages after filtering. @@ -26100,13 +26509,26 @@ cache_report_counts (report_t report, int override, int min_qod, * @return 0 on success, -1 on error. */ static int -report_counts_id_full (report_t report, int* criticals, int* holes, int* infos, - int* logs, int* warnings, int* false_positives, +report_counts_id_full (report_t report, +#if CVSS3_RATINGS == 1 + int* criticals, +#endif + int* holes, + int* infos, + int* logs, + int* warnings, + int* false_positives, double* severity, - const get_data_t* get, const char* host, - int* filtered_criticals, int* filtered_holes, - int* filtered_infos, int* filtered_logs, - int* filtered_warnings, int* filtered_false_positives, + const get_data_t* get, + const char* host, +#if CVSS3_RATINGS == 1 + int* filtered_criticals, +#endif + int* filtered_holes, + int* filtered_infos, + int* filtered_logs, + int* filtered_warnings, + int* filtered_false_positives, double* filtered_severity) { const char *filter; @@ -26115,13 +26537,19 @@ report_counts_id_full (report_t report, int* criticals, int* holes, int* infos, int filter_cacheable, unfiltered_requested, filtered_requested, cache_exists; int override, min_qod_int; severity_data_t severity_data, filtered_severity_data; - +#if CVSS3_RATINGS == 1 unfiltered_requested = (criticals || holes || warnings || infos || logs || false_positives || severity); filtered_requested = (filtered_criticals || filtered_holes || filtered_warnings || filtered_infos || filtered_logs || filtered_false_positives || filtered_severity); - +#else + unfiltered_requested = (holes || warnings || infos || logs || false_positives + || severity); + filtered_requested = (filtered_holes || filtered_warnings || filtered_infos + || filtered_logs || filtered_false_positives + || filtered_severity); +#endif if (current_credentials.uuid == NULL || strcmp (current_credentials.uuid, "") == 0) g_warning ("%s: called by NULL or dummy user", __func__); @@ -26213,6 +26641,7 @@ report_counts_id_full (report_t report, int* criticals, int* holes, int* infos, ? &filtered_severity_data : NULL); } +#if CVSS3_RATINGS == 1 severity_data_level_counts (&severity_data, NULL, false_positives, logs, infos, warnings, holes, criticals); @@ -26220,6 +26649,15 @@ report_counts_id_full (report_t report, int* criticals, int* holes, int* infos, NULL, filtered_false_positives, filtered_logs, filtered_infos, filtered_warnings, filtered_holes, filtered_criticals); +#else + severity_data_level_counts (&severity_data, + NULL, false_positives, + logs, infos, warnings, holes); + severity_data_level_counts (&filtered_severity_data, + NULL, filtered_false_positives, + filtered_logs, filtered_infos, + filtered_warnings, filtered_holes); +#endif if (severity) *severity = severity_data.max; @@ -26391,6 +26829,7 @@ report_compliance_counts (report_t report, * * @param[in] report Report. * @param[out] criticals Number of critical messages. + * Only if CVSS3_RATINGS is enabled. * @param[out] holes Number of hole messages. * @param[out] infos Number of info messages. * @param[out] logs Number of log messages. @@ -26403,14 +26842,29 @@ report_compliance_counts (report_t report, * @return 0 on success, -1 on error. */ int -report_counts_id (report_t report, int* criticals, int* holes, int* infos, - int* logs, int* warnings, int* false_positives, - double* severity, const get_data_t *get, const char *host) +report_counts_id (report_t report, +#if CVSS3_RATINGS == 1 + int* criticals, +#endif + int* holes, + int* infos, + int* logs, + int* warnings, + int* false_positives, + double* severity, + const get_data_t *get, + const char *host) { int ret; +#if CVSS3_RATINGS == 1 ret = report_counts_id_full (report, NULL, NULL, NULL, NULL, NULL, NULL, NULL, get, host, criticals, holes, infos, logs, warnings, false_positives, severity); +#else + ret = report_counts_id_full (report, NULL, NULL, NULL, NULL, NULL, NULL, + get, host, holes, infos, logs, warnings, + false_positives, severity); +#endif return ret; } @@ -26452,8 +26906,13 @@ report_severity (report_t report, int overrides, int min_qod) { g_debug ("%s: could not get max from cache", __func__); get_data_t *get = report_results_get_data (1, -1, overrides, min_qod); +#if CVSS3_RATINGS == 1 report_counts_id (report, NULL, NULL, NULL, NULL, NULL, NULL, &severity, get, NULL); +#else + report_counts_id (report, NULL, NULL, NULL, NULL, + NULL, &severity, get, NULL); +#endif get_data_reset (get); free (get); } @@ -28168,6 +28627,7 @@ host_summary_append (GString *host_summary_buffer, const char *host, * @param[in] host_summary_buffer Host sumary buffer. * @param[in] f_host_ports Hashtable for host ports. * @param[in] f_host_criticals Hashtable for host criticals. + * Only available if CVSS3_RATINGS is enabled. * @param[in] f_host_holes Hashtable for host holes. * @param[in] f_host_warnings Hashtable for host host warnings. * @param[in] f_host_infos Hashtable for host infos. @@ -28188,7 +28648,9 @@ print_report_host_xml (FILE *stream, int lean, GString *host_summary_buffer, GHashTable *f_host_ports, +#if CVSS3_RATINGS == 1 GHashTable *f_host_criticals, +#endif GHashTable *f_host_holes, GHashTable *f_host_warnings, GHashTable *f_host_infos, @@ -28272,12 +28734,15 @@ print_report_host_xml (FILE *stream, } else { - int criticals_count, holes_count, warnings_count, infos_count; + int holes_count, warnings_count, infos_count; int logs_count, false_positives_count; + int criticals_count = 0; +#if CVSS3_RATINGS == 1 criticals_count = GPOINTER_TO_INT (g_hash_table_lookup ( f_host_criticals, current_host)); +#endif holes_count = GPOINTER_TO_INT (g_hash_table_lookup ( f_host_holes, current_host)); @@ -28301,7 +28766,9 @@ print_report_host_xml (FILE *stream, "%d" "" "%d" +#if CVSS3_RATINGS == 1 "%d" +#endif "%d" "%d" "%d" @@ -28318,7 +28785,9 @@ print_report_host_xml (FILE *stream, ports_count, (criticals_count + holes_count + warnings_count + infos_count + logs_count + false_positives_count), +#if CVSS3_RATINGS == 1 criticals_count, +#endif holes_count, holes_count, warnings_count, @@ -28564,24 +29033,26 @@ init_delta_iterator (report_t report, iterator_t *results, report_t delta, * @param[in] result_hosts_only Whether to only include hosts with results. * @param[in] orig_filtered_result_count Result count. * @param[in] filtered_result_count Result count. - * @param[in] orig_f_criticals Result count. - * @param[in] f_criticals Result count. - * @param[in] orig_f_infos Result count. - * @param[in] f_holes Result count. - * @param[in] orig_f_infos Result count. - * @param[in] f_infos Result count. - * @param[in] orig_f_logs Result count. - * @param[in] f_logs Result count. - * @param[in] orig_f_warnings Result count. - * @param[in] f_warnings Result count. - * @param[in] orig_f_false_positives Result count. - * @param[in] f_false_positives Result count. - * @param[in] f_compliance_yes filtered compliant count. - * @param[in] f_compliance_no filtered incompliant count. - * @param[in] f_compliance_incomplete filtered incomplete count. - * @param[in] f_compliance_undefined filtered undefined count. - * @param[in] f_compliance_count total filtered compliance count. - * @param[in] result_hosts Result hosts. + * @param[in] orig_f_criticals Result count. + * Only available if CVSS3_RATINGS is enabled. + * @param[in] f_criticals Result count. + * Only available if CVSS3_RATINGS is enabled. + * @param[in] orig_f_infos Result count. + * @param[in] f_holes Result count. + * @param[in] orig_f_infos Result count. + * @param[in] f_infos Result count. + * @param[in] orig_f_logs Result count. + * @param[in] f_logs Result count. + * @param[in] orig_f_warnings Result count. + * @param[in] f_warnings Result count. + * @param[in] orig_f_false_positives Result count. + * @param[in] f_false_positives Result count. + * @param[in] f_compliance_yes filtered compliant count. + * @param[in] f_compliance_no filtered incompliant count. + * @param[in] f_compliance_incomplete filtered incomplete count. + * @param[in] f_compliance_undefined filtered undefined count. + * @param[in] f_compliance_count total filtered compliance count. + * @param[in] result_hosts Result hosts. * * @return 0 on success, -1 error. */ @@ -28594,7 +29065,9 @@ print_report_delta_xml (FILE *out, iterator_t *results, const char *sort_field, int result_hosts_only, int *orig_filtered_result_count, int *filtered_result_count, +#if CVSS3_RATINGS == 1 int *orig_f_criticals, int *f_criticals, +#endif int *orig_f_holes, int *f_holes, int *orig_f_infos, int *f_infos, int *orig_f_logs, int *f_logs, @@ -28607,9 +29080,10 @@ print_report_delta_xml (FILE *out, iterator_t *results, { GString *buffer = g_string_new (""); GTree *ports; - *orig_f_holes = *f_holes; +#if CVSS3_RATINGS == 1 *orig_f_criticals = *f_criticals; +#endif *orig_f_infos = *f_infos; *orig_f_logs = *f_logs; *orig_f_warnings = *f_warnings; @@ -28658,11 +29132,13 @@ print_report_delta_xml (FILE *out, iterator_t *results, level = result_iterator_level (results); (*orig_filtered_result_count)++; (*filtered_result_count)++; +#if CVSS3_RATINGS == 1 if (strcmp (level, "Critical") == 0) { (*orig_f_criticals)++; (*f_criticals)++; } +#endif if (strcmp (level, "High") == 0) { (*orig_f_holes)++; @@ -28804,8 +29280,8 @@ print_report_xml_start (report_t report, report_t delta, task_t task, array_t *result_hosts; int reuse_result_iterator; iterator_t results, delta_results; - int criticals, holes, infos, logs, warnings, false_positives; - int f_criticals, f_holes, f_infos, f_logs, f_warnings, f_false_positives; + int criticals = 0, holes, infos, logs, warnings, false_positives; + int f_criticals = 0, f_holes, f_infos, f_logs, f_warnings, f_false_positives; int orig_f_criticals, orig_f_holes, orig_f_infos, orig_f_logs; int orig_f_warnings, orig_f_false_positives, orig_filtered_result_count; int search_phrase_exact, apply_overrides, count_filtered; @@ -28815,10 +29291,13 @@ print_report_xml_start (report_t report, report_t delta, task_t task, GString *filters_buffer, *filters_extra_buffer, *host_summary_buffer; gchar *term_value; GHashTable *f_host_ports; - GHashTable *f_host_criticals, *f_host_holes, *f_host_warnings, *f_host_infos; + GHashTable *f_host_holes, *f_host_warnings, *f_host_infos; GHashTable *f_host_logs, *f_host_false_positives; GHashTable *f_host_compliant, *f_host_notcompliant; GHashTable *f_host_incomplete, *f_host_undefined; + #if CVSS3_RATINGS == 1 + GHashTable *f_host_criticals = NULL; + #endif task_status_t run_status; gchar *tsk_usage_type = NULL; int f_compliance_yes, f_compliance_no; @@ -28839,7 +29318,6 @@ print_report_xml_start (report_t report, report_t delta, task_t task, orig_f_false_positives = orig_f_warnings = orig_f_logs = orig_f_infos = 0; orig_f_holes = orig_f_criticals = 0; f_host_ports = NULL; - f_host_criticals = NULL; f_host_holes = NULL; f_host_warnings = NULL; f_host_infos = NULL; @@ -28919,7 +29397,11 @@ print_report_xml_start (report_t report, report_t delta, task_t task, max_results = manage_max_rows (max_results); + #if CVSS3_RATINGS == 1 levels = levels ? levels : g_strdup ("chmlgdf"); + #else + levels = levels ? levels : g_strdup ("hmlgdf"); + #endif if (task && (task_uuid (task, &tsk_uuid) || task_usage_type(task, &tsk_usage_type))) { @@ -29035,15 +29517,22 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { if (delta == 0) { - int total_criticals, total_holes, total_infos, total_logs; + int total_criticals = 0, total_holes, total_infos, total_logs; int total_warnings, total_false_positives; get_data_t *all_results_get; all_results_get = report_results_get_data (1, -1, 0, 0); +#if CVSS3_RATINGS == 1 report_counts_id (report, &total_criticals, &total_holes, &total_infos, &total_logs, &total_warnings, &total_false_positives, NULL, all_results_get, NULL); +#else + report_counts_id (report, &total_holes, &total_infos, + &total_logs, &total_warnings, + &total_false_positives, NULL, all_results_get, + NULL); +#endif total_result_count = total_criticals + total_holes + total_infos + total_logs + total_warnings + total_false_positives; @@ -29064,8 +29553,13 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { /* Beware, we're using the full variables temporarily here, but * report_counts_id counts the filtered results. */ +#if CVSS3_RATINGS == 1 report_counts_id (report, &criticals, &holes, &infos, &logs, &warnings, &false_positives, NULL, get, NULL); +#else + report_counts_id (report, &holes, &infos, &logs, &warnings, + &false_positives, NULL, get, NULL); +#endif filtered_result_count = criticals + holes + infos + logs + warnings + false_positives; @@ -29134,8 +29628,10 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { +#if CVSS3_RATINGS == 1 if (strchr (levels, 'c')) g_string_append (filters_extra_buffer, "Critical"); +#endif if (strchr (levels, 'h')) g_string_append (filters_extra_buffer, "High"); if (strchr (levels, 'm')) @@ -29449,20 +29945,34 @@ print_report_xml_start (report_t report, report_t delta, task_t task, { /* We're getting all the filtered results, so we can count them as we * print them, to save time. */ - +#if CVSS3_RATINGS == 1 report_counts_id_full (report, &criticals, &holes, &infos, &logs, - &warnings, &false_positives, &severity, - get, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + &warnings, &false_positives, &severity, + get, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL); +#else + report_counts_id_full (report, &holes, &infos, &logs, + &warnings, &false_positives, &severity, + get, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); +#endif f_criticals = f_holes = f_infos = f_logs = f_warnings = 0; f_false_positives = f_severity = 0; } else +#if CVSS3_RATINGS == 1 report_counts_id_full (report, &criticals, &holes, &infos, &logs, - &warnings, &false_positives, &severity, - get, NULL, - &f_criticals, &f_holes, &f_infos, &f_logs, - &f_warnings, &f_false_positives, &f_severity); + &warnings, &false_positives, &severity, + get, NULL, + &f_criticals, &f_holes, &f_infos, &f_logs, + &f_warnings, &f_false_positives, &f_severity); +#else + report_counts_id_full (report, &holes, &infos, &logs, + &warnings, &false_positives, &severity, + get, NULL, &f_holes, &f_infos, &f_logs, + &f_warnings, &f_false_positives, &f_severity); +#endif } /* Results. */ @@ -29526,8 +30036,10 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { +#if CVSS3_RATINGS == 1 f_host_criticals = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +#endif f_host_holes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); f_host_warnings = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -29542,6 +30054,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (delta && get->details) { +#if CVSS3_RATINGS == 1 if (print_report_delta_xml (out, &results, delta_states, ignore_pagination ? 0 : first_result, ignore_pagination ? -1 : max_results, @@ -29564,6 +30077,29 @@ print_report_xml_start (report_t report, report_t delta, task_t task, &f_compliance_undefined, &f_compliance_count, result_hosts)) +#else + if (print_report_delta_xml (out, &results, delta_states, + ignore_pagination ? 0 : first_result, + ignore_pagination ? -1 : max_results, + task, notes, + notes_details, overrides, + overrides_details, sort_order, + sort_field, result_hosts_only, + &orig_filtered_result_count, + &filtered_result_count, + &orig_f_holes, &f_holes, + &orig_f_infos, &f_infos, + &orig_f_logs, &f_logs, + &orig_f_warnings, &f_warnings, + &orig_f_false_positives, + &f_false_positives, + &f_compliance_yes, + &f_compliance_no, + &f_compliance_incomplete, + &f_compliance_undefined, + &f_compliance_count, + result_hosts)) +#endif goto failed_delta_report; } else if (get->details) @@ -29661,12 +30197,14 @@ print_report_xml_start (report_t report, report_t delta, task_t task, if (count_filtered) f_logs++; } +#if CVSS3_RATINGS == 1 else if (strcasecmp (level, "critical") == 0) { f_host_result_counts = f_host_criticals; if (count_filtered) f_criticals++; } +#endif else if (strcasecmp (level, "high") == 0) { f_host_result_counts = f_host_holes; @@ -29781,7 +30319,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, PRINT (out, "" "%i" +#if CVSS3_RATINGS == 1 "%i" +#endif "%i" "%i" "%i" @@ -29794,7 +30334,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, "" "", orig_filtered_result_count, +#if CVSS3_RATINGS == 1 (strchr (levels, 'c') ? orig_f_criticals : 0), +#endif (strchr (levels, 'h') ? orig_f_holes : 0), (strchr (levels, 'h') ? orig_f_holes : 0), (strchr (levels, 'l') ? orig_f_infos : 0), @@ -29814,10 +30356,12 @@ print_report_xml_start (report_t report, report_t delta, task_t task, "%i" "%i" "%i" +#if CVSS3_RATINGS == 1 "" "%i" "%i" "" +#endif "%i%i" "%i%i" "%i%i" @@ -29833,8 +30377,10 @@ print_report_xml_start (report_t report, report_t delta, task_t task, total_result_count, total_result_count, filtered_result_count, +#if CVSS3_RATINGS == 1 criticals, (strchr (levels, 'c') ? f_criticals : 0), +#endif holes, (strchr (levels, 'h') ? f_holes : 0), holes, @@ -29885,26 +30431,44 @@ print_report_xml_start (report_t report, report_t delta, task_t task, present = next (&hosts); if (present) { - if (print_report_host_xml (out, - &hosts, - result_host, - tsk_usage_type, - lean, - host_summary_buffer, - f_host_ports, - f_host_criticals, - f_host_holes, - f_host_warnings, - f_host_infos, - f_host_logs, - f_host_false_positives, - f_host_compliant, - f_host_notcompliant, - f_host_incomplete, - f_host_undefined)) - +#if CVSS3_RATINGS == 1 + if (print_report_host_xml (out, + &hosts, + result_host, + tsk_usage_type, + lean, + host_summary_buffer, + f_host_ports, + f_host_criticals, + f_host_holes, + f_host_warnings, + f_host_infos, + f_host_logs, + f_host_false_positives, + f_host_compliant, + f_host_notcompliant, + f_host_incomplete, + f_host_undefined)) +#else + if (print_report_host_xml (out, + &hosts, + result_host, + tsk_usage_type, + lean, + host_summary_buffer, + f_host_ports, + f_host_holes, + f_host_warnings, + f_host_infos, + f_host_logs, + f_host_false_positives, + f_host_compliant, + f_host_notcompliant, + f_host_incomplete, + f_host_undefined)) +#endif { - goto failed_print_report_host; + goto failed_print_report_host; } } cleanup_iterator (&hosts); @@ -29916,23 +30480,42 @@ print_report_xml_start (report_t report, report_t delta, task_t task, init_report_host_iterator (&hosts, report, NULL, 0); while (next (&hosts)) { +#if CVSS3_RATINGS == 1 if (print_report_host_xml (out, - &hosts, - NULL, - tsk_usage_type, - lean, - host_summary_buffer, - f_host_ports, - f_host_criticals, - f_host_holes, - f_host_warnings, - f_host_infos, - f_host_logs, - f_host_false_positives, - f_host_compliant, - f_host_notcompliant, - f_host_incomplete, - f_host_undefined)) + &hosts, + NULL, + tsk_usage_type, + lean, + host_summary_buffer, + f_host_ports, + f_host_criticals, + f_host_holes, + f_host_warnings, + f_host_infos, + f_host_logs, + f_host_false_positives, + f_host_compliant, + f_host_notcompliant, + f_host_incomplete, + f_host_undefined)) +#else + if (print_report_host_xml (out, + &hosts, + NULL, + tsk_usage_type, + lean, + host_summary_buffer, + f_host_ports, + f_host_holes, + f_host_warnings, + f_host_infos, + f_host_logs, + f_host_false_positives, + f_host_compliant, + f_host_notcompliant, + f_host_incomplete, + f_host_undefined)) +#endif goto failed_print_report_host; } cleanup_iterator (&hosts); @@ -29946,7 +30529,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { +#if CVSS3_RATINGS == 1 g_hash_table_destroy (f_host_criticals); +#endif g_hash_table_destroy (f_host_holes); g_hash_table_destroy (f_host_warnings); g_hash_table_destroy (f_host_infos); @@ -30074,7 +30659,9 @@ print_report_xml_start (report_t report, report_t delta, task_t task, } else { +#if CVSS3_RATINGS == 1 g_hash_table_destroy (f_host_criticals); +#endif g_hash_table_destroy (f_host_holes); g_hash_table_destroy (f_host_warnings); g_hash_table_destroy (f_host_infos); @@ -31038,8 +31625,9 @@ parse_osp_report (task_t task, report_t report, const char *report_xml) * @return "up", "down", "more", "less", "same" or if too few reports "". */ static const char * -task_trend_calc (int criticals_a, int holes_a, int warns_a, int infos_a, double severity_a, - int criticals_b, int holes_b, int warns_b, int infos_b, double severity_b) +task_trend_calc (int criticals_a, int holes_a, int warns_a, int infos_a, + double severity_a, int criticals_b, int holes_b, int warns_b, + int infos_b, double severity_b) { int threat_a, threat_b; @@ -31142,9 +31730,10 @@ task_trend_calc (int criticals_a, int holes_a, int warns_a, int infos_a, double * @return "up", "down", "more", "less", "same" or if too few reports "". */ const char * -task_iterator_trend_counts (iterator_t *iterator, int criticals_a, int holes_a, int warns_a, - int infos_a, double severity_a, int criticals_b, int holes_b, - int warns_b, int infos_b, double severity_b) +task_iterator_trend_counts (iterator_t *iterator, int criticals_a, int holes_a, + int warns_a, int infos_a, double severity_a, + int criticals_b, int holes_b, int warns_b, + int infos_b, double severity_b) { /* Ensure there are enough reports. */ if (task_iterator_finished_reports (iterator) <= 1) @@ -38329,9 +38918,15 @@ create_note (const char* active, const char* nvt, const char* text, if (text == NULL) return -1; - if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") - && strcmp (threat, "Medium") && strcmp (threat, "Low") - && strcmp (threat, "Log") && strcmp (threat, "")) + if (threat +#if CVSS3_RATINGS == 1 + && strcmp (threat, "Critical") +#endif + && strcmp (threat, "High") + && strcmp (threat, "Medium") + && strcmp (threat, "Low") + && strcmp (threat, "Log") + && strcmp (threat, "")) return -1; quoted_text = sql_insert (text); @@ -38351,8 +38946,10 @@ create_note (const char* active, const char* nvt, const char* text, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; +#if CVSS3_RATINGS == 1 else if (strcmp (threat, "Critical") == 0) severity_dbl = 0.1; +#endif else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -38587,9 +39184,15 @@ modify_note (const gchar *note_id, const char *active, const char *nvt, if (nvt && !nvt_exists (nvt)) return 4; - if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") - && strcmp (threat, "Medium") && strcmp (threat, "Low") - && strcmp (threat, "Log") && strcmp (threat, "Alarm") + if (threat +#if CVSS3_RATINGS == 1 + && strcmp (threat, "Critical") +#endif + && strcmp (threat, "High") + && strcmp (threat, "Medium") + && strcmp (threat, "Low") + && strcmp (threat, "Log") + && strcmp (threat, "Alarm") && strcmp (threat, "")) return -1; @@ -38614,8 +39217,10 @@ modify_note (const gchar *note_id, const char *active, const char *nvt, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; +#if CVSS3_RATINGS == 1 else if (strcmp (threat, "Critical") == 0) severity_dbl = 0.1; +#endif else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39322,16 +39927,29 @@ create_override (const char* active, const char* nvt, const char* text, if (port && validate_results_port (port)) return 2; - if (threat && strcmp (threat, "Critical") && strcmp (threat, "High") - && strcmp (threat, "Medium") && strcmp (threat, "Low") - && strcmp (threat, "Log") && strcmp (threat, "Alarm") + if (threat +#if CVSS3_RATINGS == 1 + && strcmp (threat, "Critical") +#endif + && strcmp (threat, "High") + && strcmp (threat, "Medium") + && strcmp (threat, "Low") + && strcmp (threat, "Log") + && strcmp (threat, "Alarm") && strcmp (threat, "")) return -1; - if (new_threat && strcmp (threat, "Critical") && strcmp (new_threat, "High") - && strcmp (new_threat, "Medium") && strcmp (new_threat, "Low") - && strcmp (new_threat, "Log") && strcmp (new_threat, "False Positive") - && strcmp (new_threat, "Alarm") && strcmp (new_threat, "")) + if (new_threat +#if CVSS3_RATINGS == 1 + && strcmp (new_threat, "Critical") +#endif + && strcmp (new_threat, "High") + && strcmp (new_threat, "Medium") + && strcmp (new_threat, "Low") + && strcmp (new_threat, "Log") + && strcmp (new_threat, "False Positive") + && strcmp (new_threat, "Alarm") + && strcmp (new_threat, "")) return -1; severity_dbl = 0.0; @@ -39347,8 +39965,10 @@ create_override (const char* active, const char* nvt, const char* text, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; +#if CVSS3_RATINGS == 1 else if (strcmp (threat, "Critical") == 0) severity_dbl = 0.1; +#endif else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39381,10 +40001,15 @@ create_override (const char* active, const char* nvt, const char* text, { if (strcmp (new_threat, "Alarm") == 0) new_severity_dbl = 10.0; +#if CVSS3_RATINGS == 1 else if (strcmp (new_threat, "Critical") == 0) new_severity_dbl = 10.0; + else if (strcmp (new_threat, "High") == 0) + new_severity_dbl = 8.9; +#else else if (strcmp (new_threat, "High") == 0) new_severity_dbl = 10.0; +#endif else if (strcmp (new_threat, "Medium") == 0) new_severity_dbl = 5.0; else if (strcmp (new_threat, "Low") == 0) @@ -39701,8 +40326,10 @@ modify_override (const gchar *override_id, const char *active, const char *nvt, { if (strcmp (threat, "Alarm") == 0) severity_dbl = 0.1; +#if CVSS3_RATINGS == 1 else if (strcmp (threat, "Critical") == 0) severity_dbl = 0.1; +#endif else if (strcmp (threat, "High") == 0) severity_dbl = 0.1; else if (strcmp (threat, "Medium") == 0) @@ -39735,10 +40362,15 @@ modify_override (const gchar *override_id, const char *active, const char *nvt, { if (strcmp (new_threat, "Alarm") == 0) new_severity_dbl = 10.0; +#if CVSS3_RATINGS == 1 else if (strcmp (new_threat, "Critical") == 0) new_severity_dbl = 10.0; + else if (strcmp (new_threat, "High") == 0) + new_severity_dbl = 8.9; +#else else if (strcmp (new_threat, "High") == 0) new_severity_dbl = 10.0; +#endif else if (strcmp (new_threat, "Medium") == 0) new_severity_dbl = 5.0; else if (strcmp (new_threat, "Low") == 0) diff --git a/src/manage_utils.c b/src/manage_utils.c index 5bb51df2b..569ac8e36 100644 --- a/src/manage_utils.c +++ b/src/manage_utils.c @@ -210,9 +210,10 @@ level_min_severity (const char *level) return SEVERITY_FP; else if (strcasecmp (level, "Error") == 0) return SEVERITY_ERROR; - - if (strcasecmp (level, "critical") == 0) +#if CVSS3_RATINGS == 1 + else if (strcasecmp (level, "critical") == 0) return 9.0; +#endif else if (strcasecmp (level, "high") == 0) return 7.0; else if (strcasecmp (level, "medium") == 0) @@ -242,11 +243,15 @@ level_max_severity (const char *level) return SEVERITY_FP; else if (strcasecmp (level, "Error") == 0) return SEVERITY_ERROR; - - if (strcasecmp (level, "critical") == 0) +#if CVSS3_RATINGS == 1 + else if (strcasecmp (level, "critical") == 0) return 10.0; else if (strcasecmp (level, "high") == 0) return 8.9; +#else + else if (strcasecmp (level, "high") == 0) + return 10.0; +#endif else if (strcasecmp (level, "medium") == 0) return 6.9; else if (strcasecmp (level, "low") == 0) From 26590f496969ca9a0223127b21ad1c832156d517 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Thu, 12 Dec 2024 12:10:31 +0100 Subject: [PATCH 62/64] Update GMP documentation conditionally on feature switch --- CMakeLists.txt | 12 + src/schema_formats/XML/GMP.xml.in | 393 +++++++++++++++++++++++++++++- 2 files changed, 401 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f91fd6af..e6c9eb3a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,18 @@ if (NOT CVSS3_RATINGS) endif (NOT CVSS3_RATINGS) add_definitions (-DCVSS3_RATINGS=${CVSS3_RATINGS}) +if (CVSS3_RATINGS EQUAL 1) + set(IF_CVSS3_RATINGS "") + set(ENDIF_CVSS3_RATINGS "") + set(IF_NOT_CVSS3_RATINGS "") +elseif (CVSS3_RATINGS EQUAL 0) + set(IF_CVSS3_RATINGS "") + set(IF_NOT_CVSS3_RATINGS "") + set(ENDIF_NOT_CVSS3_RATINGS "") +endif() + message ("-- Install prefix: ${CMAKE_INSTALL_PREFIX}") message ("-- Log file: ${GVMD_LOG_FILE}") diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 7b2bfc493..97b37fec4 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -115,6 +115,19 @@ along with this program. If not, see . text + @IF_CVSS3_RATINGS@ + + levels + A string selecting severity levels that may include the characters c, h, m, l, g and f + + The meanings of the letters for each level are: "c" for "critical", + "h" for "high", "m" for "medium", "l" for "low", "g" for "log" and + "f" for "false positive". + + xsd:token { pattern = "c?h?m?l?g?f?" } + + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ levels A string selecting severity levels that may include the characters h, m, l, g and f @@ -125,6 +138,7 @@ along with this program. If not, see . xsd:token { pattern = "h?m?l?g?f?" } + @ENDIF_NOT_CVSS3_RATINGS@ name A name @@ -2231,6 +2245,9 @@ along with this program. If not, see . Level filter + @IF_CVSS3_RATINGS@ + Critical + @ENDIF_CVSS3_RATINGS@ High Medium Low @@ -2366,10 +2383,22 @@ along with this program. If not, see . text full filtered + @IF_CVSS3_RATINGS@ + critical + @ENDIF_CVSS3_RATINGS@ hole + @IF_CVSS3_RATINGS@ + high + @ENDIF_CVSS3_RATINGS@ info + @IF_CVSS3_RATINGS@ + low + @ENDIF_CVSS3_RATINGS@ log warning + @IF_CVSS3_RATINGS@ + medium + @ENDIF_CVSS3_RATINGS@ full @@ -2381,10 +2410,35 @@ along with this program. If not, see . Number of results after filtering integer + @IF_CVSS3_RATINGS@ + + critical + + Number of "critical" results (threat level critical) + + + full + filtered + + + full + Total number of results + integer + + + filtered + Number of results after filtering + integer + + + @ENDIF_CVSS3_RATINGS@ hole Number of "hole" results (threat level High) + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use high instead + @ENDIF_CVSS3_RATINGS@ full @@ -2401,10 +2455,35 @@ along with this program. If not, see . integer + @IF_CVSS3_RATINGS@ + + high + + Number of "high" results (threat level High) + + + full + filtered + + + full + Total number of results + integer + + + filtered + Number of results after filtering + integer + + + @ENDIF_CVSS3_RATINGS@ info Number of "info" results (threat level Low) + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use low instead + @ENDIF_CVSS3_RATINGS@ full @@ -2421,6 +2500,28 @@ along with this program. If not, see . integer + @IF_CVSS3_RATINGS@ + + low + + Number of "low" results (threat level Low) + + + full + filtered + + + full + Total number of results + integer + + + filtered + Number of results after filtering + integer + + + @ENDIF_CVSS3_RATINGS@ log @@ -2445,6 +2546,30 @@ along with this program. If not, see . warning Number of "warning" results (threat level Medium) + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use medium instead + @ENDIF_CVSS3_RATINGS@ + + + full + filtered + + + full + Total number of results + integer + + + filtered + Number of results after filtering + integer + + + @IF_CVSS3_RATINGS@ + + medium + + Number of "medium" results (threat level Medium) full @@ -2461,6 +2586,7 @@ along with this program. If not, see . integer + @ENDIF_CVSS3_RATINGS@ compliance_count @@ -2915,10 +3041,22 @@ along with this program. If not, see . page + @IF_CVSS3_RATINGS@ + critical + @ENDIF_CVSS3_RATINGS@ hole - warning + @IF_CVSS3_RATINGS@ + high + @ENDIF_CVSS3_RATINGS@ info + @IF_CVSS3_RATINGS@ + low + @ENDIF_CVSS3_RATINGS@ log + warning + @IF_CVSS3_RATINGS@ + medium + @ENDIF_CVSS3_RATINGS@ false_positive @@ -2926,9 +3064,30 @@ along with this program. If not, see . Total number of results for current host on current page integer + @IF_CVSS3_RATINGS@ + + critical + + Number of "critical" results (level "Critical") + + + page + + + page + Number of results on current page + integer + + + @ENDIF_CVSS3_RATINGS@ hole - Number of "hole" results (level "High") + + Number of "hole" results (level "High") + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use high instead + @ENDIF_CVSS3_RATINGS@ + page @@ -2938,9 +3097,30 @@ along with this program. If not, see . integer + @IF_CVSS3_RATINGS@ + + high + + Number of "high" results (level "High") + + + page + + + page + Number of results on current page + integer + + + @ENDIF_CVSS3_RATINGS@ warning - Number of "warning" results (level "Medium") + + Number of "warning" results (level "Medium") + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use medium instead + @ENDIF_CVSS3_RATINGS@ + page @@ -2950,9 +3130,43 @@ along with this program. If not, see . integer + @IF_CVSS3_RATINGS@ + + medium + + Number of "medium" results (level "Medium") + + + page + + + page + Number of results on current page + integer + + + @ENDIF_CVSS3_RATINGS@ info - Number of "info" results (level "Low") + + Number of "info" results (level "Low") + @IF_CVSS3_RATINGS@ + ,will be deprecated. Use low instead + @ENDIF_CVSS3_RATINGS@ + + + page + + + page + Number of results on current page + integer + + + @IF_CVSS3_RATINGS@ + + low + Number of "low" results (level "Low") page @@ -2962,6 +3176,7 @@ along with this program. If not, see . integer + @ENDIF_CVSS3_RATINGS@ log Number of "log" results @@ -18319,6 +18534,13 @@ END:VCALENDAR integer Number of high severity results + @IF_CVSS3_RATINGS@ + + critical + integer + Number of critical severity results + + @ENDIF_CVSS3_RATINGS@ hosts integer @@ -18354,6 +18576,13 @@ END:VCALENDAR integer Number of high severity results per host with results + @IF_CVSS3_RATINGS@ + + critical_per_host + integer + Number of critical severity results per host with results + + @ENDIF_CVSS3_RATINGS@ start_time iso_time @@ -18661,6 +18890,9 @@ END:VCALENDAR first=1 rows=-1 sort=name + @IF_CVSS3_RATINGS@ + Critical + @ENDIF_CVSS3_RATINGS@ High Medium Low @@ -18705,6 +18937,41 @@ END:VCALENDAR 10 10 + @IF_CVSS3_RATINGS@ + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 7 + 7 + + + 7 + 7 + + + 0 + 0 + + + 3 + 3 + + + 3 + 3 + + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ 0 0 @@ -18721,6 +18988,7 @@ END:VCALENDAR 3 3 + @ENDIF_NOT_CVSS3_RATINGS@ dik mm @@ -22666,6 +22934,13 @@ END:VCALENDAR integer Number of high severity results + @IF_CVSS3_RATINGS@ + + critical + integer + Number of critical severity results + + @ENDIF_CVSS3_RATINGS@ hosts integer @@ -22701,6 +22976,13 @@ END:VCALENDAR integer Number of high severity results per host with results + @IF_CVSS3_RATINGS@ + + critical_per_host + integer + Number of critical severity results per host with results + + @ENDIF_CVSS3_RATINGS@ target name @@ -23246,9 +23528,20 @@ END:VCALENDAR false_positive log + @IF_CVSS3_RATINGS@ info + low warning + medium hole + high + critical + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + info + warning + hole + @ENDIF_NOT_CVSS3_RATINGS@ false_positive @@ -23261,15 +23554,46 @@ END:VCALENDAR info integer + @IF_CVSS3_RATINGS@ + This will be deprecated. Use low instead + @ENDIF_CVSS3_RATINGS@ + + @IF_CVSS3_RATINGS@ + + low + integer + @ENDIF_CVSS3_RATINGS@ warning integer + @IF_CVSS3_RATINGS@ + This will be deprecated. Use medium instead + @ENDIF_CVSS3_RATINGS@ + @IF_CVSS3_RATINGS@ + + medium + integer + + @ENDIF_CVSS3_RATINGS@ hole integer + @IF_CVSS3_RATINGS@ + This will be deprecated. Use high instead + @ENDIF_CVSS3_RATINGS@ + @IF_CVSS3_RATINGS@ + + high + integer + + + critical + integer + + @ENDIF_CVSS3_RATINGS@ severity @@ -23502,10 +23826,22 @@ END:VCALENDAR Mon Feb 1 19:11:20 2010 + @IF_CVSS3_RATINGS@ + 0 0 + 0 7 + 7 0 3 + 3 + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + 0 + 7 + 0 + 3 + @ENDIF_NOT_CVSS3_RATINGS@ 5.0 @@ -23577,10 +23913,22 @@ END:VCALENDAR Mon Feb 1 19:11:20 2010 + @IF_CVSS3_RATINGS@ + 0 0 + 0 7 + 7 0 3 + 3 + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + 0 + 7 + 0 + 3 + @ENDIF_NOT_CVSS3_RATINGS@ 5.0 @@ -23593,20 +23941,44 @@ END:VCALENDAR Mon Feb 1 18:51:38 2010 Done + @IF_CVSS3_RATINGS@ + 0 0 + 0 7 + 7 0 3 + 3 + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + 0 + 7 + 0 + 3 + @ENDIF_NOT_CVSS3_RATINGS@ Mon Feb 1 19:11:20 2010 Done + @IF_CVSS3_RATINGS@ + 0 0 + 0 7 + 7 0 3 + 3 + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + 0 + 7 + 0 + 3 + @ENDIF_NOT_CVSS3_RATINGS@ 5.0 @@ -23697,11 +24069,24 @@ END:VCALENDAR 2019-04-24T14:26:01+02:00 2019-04-24T14:50:59+02:00 + @IF_CVSS3_RATINGS@ + 0 1 + 1 0 + 0 77 8 + 8 + 0 + @ENDIF_CVSS3_RATINGS@ + @IF_NOT_CVSS3_RATINGS@ + 1 + 0 + 77 + 8 0 + @ENDIF_NOT_CVSS3_RATINGS@ 9.0 From c375385ae364c17a768ff06dd3292155872bb6dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Fri, 3 Jan 2025 12:07:31 +0100 Subject: [PATCH 63/64] Remove: Drop obsolete comment from prod Dockerfile xml split tool from xml-twig-tools packages isn't used anymore. Therefore the comment is obsolete. Replaces #2321 --- .docker/prod.Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/.docker/prod.Dockerfile b/.docker/prod.Dockerfile index 1872962b8..6141b6ce3 100644 --- a/.docker/prod.Dockerfile +++ b/.docker/prod.Dockerfile @@ -72,9 +72,6 @@ ARG DEBIAN_FRONTEND=noninteractive # s/mime email encryption # gpgsm -# Loading scap and cert data -# xml-twig-tools - # Required for set up certificates for GVM # gnutls-bin From 25dff8611bbfd2bc5f78abde6cb4ffa81d4a59bd Mon Sep 17 00:00:00 2001 From: Moritz Schlarb Date: Mon, 26 Aug 2024 15:50:51 +0200 Subject: [PATCH 64/64] Fix: Correctly use test conditions in .docker/setup-mta.sh Added dollar signs to have the tests actually look at variable values and not for the plain strings which leads to them being always true! --- .docker/setup-mta.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.docker/setup-mta.sh b/.docker/setup-mta.sh index 51aaa00ea..e27d763f1 100644 --- a/.docker/setup-mta.sh +++ b/.docker/setup-mta.sh @@ -1,19 +1,19 @@ #!/bin/bash # Make any changes only when MTA_HOST has been set -if [ -n MTA_HOST ]; then +if [ -n "$MTA_HOST" ]; then echo "setting up configuration file for mail agent" CONFIG="/etc/msmtprc" echo "host $MTA_HOST" > $CONFIG - [ -n MTA_PORT ] && echo "port $MTA_PORT" >> $CONFIG - [ -n MTA_TLS ] && echo "tls $MTA_TLS" >> $CONFIG - [ -n MTA_STARTTLS ] && echo "tls_starttls $MTA_STARTTLS" >> $CONFIG - [ -n MTA_TLS_CERTCHECK ] && echo "tls_certcheck $MTA_TLS_CERTCHECK" >> $CONFIG - [ -n MTA_AUTH ] && echo "auth $MTA_AUTH" >> $CONFIG - [ -n MTA_USER ] && echo "user $MTA_USER" >> $CONFIG - [ -n MTA_FROM ] && echo "from $MTA_FROM" >> $CONFIG - [ -n MTA_PASSWORD ] && echo "password $MTA_PASSWORD" >> $CONFIG - [ -n MTA_LOGFILE ] && echo "logfile $MTA_LOGFILE" >> $CONFIG + [ -n "$MTA_PORT" ] && echo "port $MTA_PORT" >> $CONFIG + [ -n "$MTA_TLS" ] && echo "tls $MTA_TLS" >> $CONFIG + [ -n "$MTA_STARTTLS" ] && echo "tls_starttls $MTA_STARTTLS" >> $CONFIG + [ -n "$MTA_TLS_CERTCHECK" ] && echo "tls_certcheck $MTA_TLS_CERTCHECK" >> $CONFIG + [ -n "$MTA_AUTH" ] && echo "auth $MTA_AUTH" >> $CONFIG + [ -n "$MTA_USER" ] && echo "user $MTA_USER" >> $CONFIG + [ -n "$MTA_FROM" ] && echo "from $MTA_FROM" >> $CONFIG + [ -n "$MTA_PASSWORD" ] && echo "password $MTA_PASSWORD" >> $CONFIG + [ -n "$MTA_LOGFILE" ] && echo "logfile $MTA_LOGFILE" >> $CONFIG chown gvmd:mail $CONFIG chmod 750 $CONFIG fi