From 55f8abdda7a51fc82d3576f4883d5a3d2b703901 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sat, 10 Aug 2019 14:43:46 +0200 Subject: [PATCH 1/8] Handle solution and solutuion_type explicite in db This prepares to have both not anymore in the pipe-separated tag list. However, this patch makes the solution appear twice in the nvts table for the time being. Just like solution_type already. This patch expects that there is a additional column in the nvt table "solution." A migrator is forthcoming, for testing this can be done: ALTER TABLE IF EXISTS nvts ADD COLUMN solution text; --- src/manage_sql_nvts.c | 76 +++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index a7c3ed1ba..2fcdbe6c8 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -186,7 +186,7 @@ insert_nvt (const nvti_t *nvti) gchar *qod_str, *qod_type, *cve; gchar *quoted_name, *quoted_cve, *quoted_tag; gchar *quoted_cvss_base, *quoted_qod_type, *quoted_family, *value; - gchar *quoted_solution_type; + gchar *quoted_solution, *quoted_solution_type; int creation_time, modification_time, qod, i; cve = nvti_refs (nvti, "cve", "", 0); @@ -196,6 +196,11 @@ insert_nvt (const nvti_t *nvti) g_free (cve); + quoted_solution = sql_quote (nvti_solution (nvti) ? + nvti_solution (nvti) : ""); + quoted_solution_type = sql_quote (nvti_solution_type (nvti) ? + nvti_solution_type (nvti) : ""); + if (nvti_tag (nvti)) { gchar **split, **point; @@ -243,6 +248,25 @@ insert_nvt (const nvti_t *nvti) } g_strfreev (split); + /* Add the elements that are expected as part of the pipe-separated tag list + * via API although internally already explicitely stored. Once the API is + * extended to have these elements explicitely, they do not need to be + * added to this string anymore. */ + if (nvti_solution (nvti)) + { + if (tag->str) + g_string_append_printf (tag, "|solution=%s", nvti_solution (nvti)); + else + g_string_append_printf (tag, "solution=%s", nvti_solution (nvti)); + } + if (nvti_solution_type (nvti)) + { + if (tag->str) + g_string_append_printf (tag, "|solution_type=%s", nvti_solution_type (nvti)); + else + g_string_append_printf (tag, "solution_type=%s", nvti_solution_type (nvti)); + } + quoted_tag = sql_quote (tag->str); g_string_free (tag, TRUE); } @@ -305,15 +329,6 @@ insert_nvt (const nvti_t *nvti) } g_free (value); - value = tag_value (nvti_tag (nvti), "solution_type"); - if (value) - { - quoted_solution_type = sql_quote (value); - g_free (value); - } - else - quoted_solution_type = g_strdup (""); - if (sql_int ("SELECT EXISTS (SELECT * FROM nvts WHERE oid = '%s');", nvti_oid (nvti))) sql ("DELETE FROM nvts WHERE oid = '%s';", nvti_oid (nvti)); @@ -321,12 +336,12 @@ insert_nvt (const nvti_t *nvti) sql ("INSERT into nvts (oid, name," " cve, tag, category, family, cvss_base," " creation_time, modification_time, uuid, solution_type," - " qod, qod_type)" + " solution, qod, qod_type)" " VALUES ('%s', '%s', '%s'," - " '%s', %i, '%s', '%s', %i, %i, '%s', '%s', %d, '%s');", + " '%s', %i, '%s', '%s', %i, %i, '%s', '%s', '%s', %d, '%s');", nvti_oid (nvti), quoted_name, quoted_cve, quoted_tag, nvti_category (nvti), quoted_family, quoted_cvss_base, creation_time, - modification_time, nvti_oid (nvti), quoted_solution_type, + modification_time, nvti_oid (nvti), quoted_solution_type, quoted_solution, qod, quoted_qod_type); sql ("DELETE FROM vt_refs where vt_oid = '%s';", nvti_oid (nvti)); @@ -353,6 +368,7 @@ insert_nvt (const nvti_t *nvti) g_free (quoted_tag); g_free (quoted_cvss_base); g_free (quoted_family); + g_free (quoted_solution); g_free (quoted_solution_type); g_free (quoted_qod_type); } @@ -1025,24 +1041,6 @@ get_tag (entity_t vt) first = 0; } - child = entity_child (vt, "solution"); - if (child) - { - const gchar *type; - - g_string_append_printf (tag, - "%ssolution=%s", - first ? "" : "|", - entity_text (child)); - first = 0; - - type = entity_attribute (child, "type"); - if (type == NULL) - g_debug ("%s: SOLUTION missing type", __FUNCTION__); - else - g_string_append_printf (tag, "|solution_type=%s", type); - } - child = entity_child (vt, "severities"); if (child) { @@ -1208,7 +1206,7 @@ nvti_from_vt (entity_t vt) { nvti_t *nvti = nvti_new (); const char *id; - entity_t name, detection, refs, ref, custom, family, category; + entity_t name, detection, solution, refs, ref, custom, family, category; entities_t children; gchar *tag, *cvss_base, *parsed_tags; @@ -1236,6 +1234,20 @@ nvti_from_vt (entity_t vt) nvti_set_qod_type (nvti, entity_attribute (detection, "qod_type")); } + solution = entity_child (vt, "solution"); + if (solution) + { + const gchar *type; + + nvti_set_solution (nvti, entity_text (solution)); + + type = entity_attribute (solution, "type"); + if (type == NULL) + g_debug ("%s: SOLUTION missing type", __FUNCTION__); + else + nvti_set_solution_type (nvti, type); + } + refs = entity_child (vt, "refs"); if (refs == NULL) { From 00156a577789a08b32069200c3884684ea0dc421 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sat, 10 Aug 2019 15:02:28 +0200 Subject: [PATCH 2/8] Add migrator for extending nvt with previous tags. This one adds the solution. --- src/manage_migrators.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/manage_migrators.c b/src/manage_migrators.c index 870778a46..52b42511c 100644 --- a/src/manage_migrators.c +++ b/src/manage_migrators.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2018 Greenbone Networks GmbH +/* Copyright (C) 2013-2019 Greenbone Networks GmbH * * SPDX-License-Identifier: GPL-2.0-or-later * @@ -1162,6 +1162,38 @@ migrate_213_to_214 () return 0; } +/** + * @brief Migrate the database from version 215 to version 216. + * + * @return 0 success, -1 error. + */ +int +migrate_215_to_216 () +{ + sql_begin_immediate (); + + /* Ensure that the database is currently version 215. */ + + if (manage_db_version () != 215) + { + sql_rollback (); + return -1; + } + + /* Update the database. */ + + /* Extend table "nvts" with additional column "solution" */ + sql ("ALTER TABLE IF EXISTS nvts ADD COLUMN solution text;"); + + /* Set the database version to 216. */ + + set_db_version (216); + + sql_commit (); + + return 0; +} + #undef UPDATE_DASHBOARD_SETTINGS /** From 23f80d6f2a4a045b0a89a344d9fe5eee50162ae0 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 08:46:42 +0200 Subject: [PATCH 3/8] Add result iterator for nvt solution,solution_type This allows to access solution and solution_type when iterating over results. --- src/manage.h | 6 ++++++ src/manage_sql.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/manage.h b/src/manage.h index 4086e209f..2f4e0e493 100644 --- a/src/manage.h +++ b/src/manage.h @@ -1444,6 +1444,12 @@ result_iterator_nvt_oid (iterator_t*); const char* result_iterator_nvt_name (iterator_t *); +const char* +result_iterator_nvt_solution (iterator_t *); + +const char* +result_iterator_nvt_solution_type (iterator_t *); + const char* result_iterator_nvt_family (iterator_t *); diff --git a/src/manage_sql.c b/src/manage_sql.c index ce1b62361..6c50dc43a 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -15550,7 +15550,7 @@ update_nvti_cache () nvti_cache = nvtis_new (); init_iterator (&nvts, - "SELECT oid, name, family, cvss_base, tag FROM nvts;"); + "SELECT oid, name, family, cvss_base, tag, solution, solution_type FROM nvts;"); while (next (&nvts)) { iterator_t refs; @@ -15561,6 +15561,8 @@ update_nvti_cache () nvti_set_family (nvti, iterator_string (&nvts, 2)); nvti_set_cvss_base (nvti, iterator_string (&nvts, 3)); nvti_set_tag (nvti, iterator_string (&nvts, 4)); + nvti_set_solution (nvti, iterator_string (&nvts, 5)); + nvti_set_solution_type (nvti, iterator_string (&nvts, 6)); init_iterator (&refs, "SELECT type, ref_id, ref_text" @@ -24300,6 +24302,43 @@ result_iterator_nvt_name (iterator_t *iterator) return NULL; } +/** + * @brief Get the NVT solution from a result iterator. + * + * @param[in] iterator Iterator. + * + * @return The solution of the NVT that produced the result, or NULL on error. + */ +const char* +result_iterator_nvt_solution (iterator_t *iterator) +{ + nvti_t *nvti; + if (iterator->done) return NULL; + nvti = lookup_nvti (result_iterator_nvt_oid (iterator)); + if (nvti) + return nvti_solution (nvti); + return NULL; +} + +/** + * @brief Get the NVT solution_type from a result iterator. + * + * @param[in] iterator Iterator. + * + * @return The solution_type of the NVT that produced the result, + * or NULL on error. + */ +const char* +result_iterator_nvt_solution_type (iterator_t *iterator) +{ + nvti_t *nvti; + if (iterator->done) return NULL; + nvti = lookup_nvti (result_iterator_nvt_oid (iterator)); + if (nvti) + return nvti_solution_type (nvti); + return NULL; +} + /** * @brief Get the NVT family from a result iterator. * From 21ba0e9f2e87656fa037e2ddcfe781d6bd3b1b23 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 11:26:08 +0200 Subject: [PATCH 4/8] Add nvt iterators for solution and solution_type. --- src/manage.h | 3 +++ src/manage_sql_nvts.c | 20 ++++++++++++++++++++ src/manage_sql_nvts.h | 1 + 3 files changed, 24 insertions(+) diff --git a/src/manage.h b/src/manage.h index 2f4e0e493..885b1cbd1 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2014,6 +2014,9 @@ nvt_iterator_qod (iterator_t*); const char* nvt_iterator_qod_type ( iterator_t *iterator ); +const char* +nvt_iterator_solution (iterator_t*); + const char* nvt_iterator_solution_type (iterator_t*); diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 2fcdbe6c8..318913e27 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -870,6 +870,26 @@ DEF_ACCESS (nvt_iterator_qod, GET_ITERATOR_COLUMN_COUNT + 10); */ DEF_ACCESS (nvt_iterator_qod_type, GET_ITERATOR_COLUMN_COUNT + 11); +/** + * @brief Get the solution_type from an NVT iterator. + * + * @param[in] iterator Iterator. + * + * @return Solution Type, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (nvt_iterator_solution_type, GET_ITERATOR_COLUMN_COUNT + 12); + +/** + * @brief Get the solution from an NVT iterator. + * + * @param[in] iterator Iterator. + * + * @return Solution, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +DEF_ACCESS (nvt_iterator_solution, GET_ITERATOR_COLUMN_COUNT + 14); + /** * @brief Get the default timeout of an NVT. * diff --git a/src/manage_sql_nvts.h b/src/manage_sql_nvts.h index d152b2fe0..0f503ccc1 100644 --- a/src/manage_sql_nvts.h +++ b/src/manage_sql_nvts.h @@ -55,6 +55,7 @@ { "qod_type", NULL, KEYWORD_TYPE_STRING }, \ { "solution_type", NULL, KEYWORD_TYPE_STRING }, \ { "tag", "script_tags", KEYWORD_TYPE_STRING}, \ + { "solution", NULL, KEYWORD_TYPE_STRING}, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ } From 2ea97b71cb55db50e30efae4078f37a621d03ae1 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 12:28:12 +0200 Subject: [PATCH 5/8] get_nvts: Append solution/solution_type to tag This also serves get_info for type NVT. The explicit elements "solution" and "solution_type" are appended to the pipe-separated tag element of the nvt. This is a temporary solution until the XML structure of a NVT has explicit solution and solution_type elements. Once that is established, we don't need to append them to the tags anymore. --- src/manage.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/manage.c b/src/manage.c index b699f8156..c844d16b8 100644 --- a/src/manage.c +++ b/src/manage.c @@ -7374,7 +7374,7 @@ get_nvti_xml (iterator_t *nvts, int details, int pref_count, if (details) { int tag_count; - GString *refs_str, *tags_str, *buffer; + GString *refs_str, *tags_str, *buffer, *nvt_tags; iterator_t cert_refs_iterator, tags; gchar *tag_name_esc, *tag_value_esc, *tag_comment_esc; char *default_timeout = nvt_default_timeout (oid); @@ -7384,6 +7384,28 @@ get_nvti_xml (iterator_t *nvts, int details, int pref_count, #undef DEF + nvt_tags = g_string_new (tag_text); + g_free (tag_text); + + /* Add the elements that are expected as part of the pipe-separated tag list + * via API although internally already explicitely stored. Once the API is + * extended to have these elements explicitely, they do not need to be + * added to this string anymore. */ + if (nvt_iterator_solution (nvts)) + { + if (nvt_tags->str) + g_string_append_printf (nvt_tags, "|solution=%s", nvt_iterator_solution (nvts)); + else + g_string_append_printf (nvt_tags, "solution=%s", result_iterator_nvt_solution (nvts)); + } + if (nvt_iterator_solution_type (nvts)) + { + if (nvt_tags->str) + g_string_append_printf (nvt_tags, "|solution_type=%s", nvt_iterator_solution_type (nvts)); + else + g_string_append_printf (nvt_tags, "solution_type=%s", nvt_iterator_solution_type (nvts)); + } + refs_str = g_string_new (""); if (manage_cert_loaded()) @@ -7495,12 +7517,12 @@ get_nvti_xml (iterator_t *nvts, int details, int pref_count, nvt_iterator_qod (nvts), nvt_iterator_qod_type (nvts), refs_str->str, - tag_text, + nvt_tags->str, pref_count, timeout ? timeout : "", default_timeout ? default_timeout : ""); g_free (family_text); - g_free (tag_text); + g_string_free(nvt_tags, 1); g_string_free(refs_str, 1); g_string_free(tags_str, 1); From ba5fc61156042992a9b0d31210967d5020f28931 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 12:38:01 +0200 Subject: [PATCH 6/8] Append solution(_type) to nvt of get_results This appends the explicit stored solution and solutions_type to the pipe-separated tag element. Once the solution and solution_type are explicit elements of the XML definition, this can be dropped. --- src/gmp.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gmp.c b/src/gmp.c index 0c3b35a99..d199c4928 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -10170,10 +10170,30 @@ results_xml_append_nvt (iterator_t *results, GString *buffer, int cert_loaded) else { const char *cvss_base = result_iterator_nvt_cvss_base (results); + GString *tags = g_string_new (result_iterator_nvt_tag (results)); if (!cvss_base && !strcmp (oid, "0")) cvss_base = "0.0"; + /* Add the elements that are expected as part of the pipe-separated tag list + * via API although internally already explicitely stored. Once the API is + * extended to have these elements explicitely, they do not need to be + * added to this string anymore. */ + if (result_iterator_nvt_solution (results)) + { + if (tags->str) + g_string_append_printf (tags, "|solution=%s", result_iterator_nvt_solution (results)); + else + g_string_append_printf (tags, "solution=%s", result_iterator_nvt_solution (results)); + } + if (result_iterator_nvt_solution_type (results)) + { + if (tags->str) + g_string_append_printf (tags, "|solution_type=%s", result_iterator_nvt_solution_type (results)); + else + g_string_append_printf (tags, "solution_type=%s", result_iterator_nvt_solution_type (results)); + } + buffer_xml_append_printf (buffer, "" "nvt" @@ -10185,7 +10205,7 @@ results_xml_append_nvt (iterator_t *results, GString *buffer, int cert_loaded) result_iterator_nvt_name (results) ?: oid, result_iterator_nvt_family (results) ?: "", cvss_base ?: "", - result_iterator_nvt_tag (results) ?: ""); + tags->str ?: ""); buffer_xml_append_printf (buffer, ""); result_iterator_nvt_refs_append (buffer, results); @@ -10193,6 +10213,8 @@ results_xml_append_nvt (iterator_t *results, GString *buffer, int cert_loaded) result_iterator_has_cert_bunds (results), result_iterator_has_dfn_certs (results)); buffer_xml_append_printf (buffer, ""); + + g_string_free (tags, TRUE); } } From 4ac7224b6eb5ce10ac1baf953797b7ce311ae136 Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 14:10:35 +0200 Subject: [PATCH 7/8] Don't add special tags anymore into database. Since solution and solution_type are now appended to the tag string for API compaitibility where the respective XML is created, we do not need to store them into the tag in the database anymmore! --- src/manage_sql_nvts.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 318913e27..1f928c207 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -248,25 +248,6 @@ insert_nvt (const nvti_t *nvti) } g_strfreev (split); - /* Add the elements that are expected as part of the pipe-separated tag list - * via API although internally already explicitely stored. Once the API is - * extended to have these elements explicitely, they do not need to be - * added to this string anymore. */ - if (nvti_solution (nvti)) - { - if (tag->str) - g_string_append_printf (tag, "|solution=%s", nvti_solution (nvti)); - else - g_string_append_printf (tag, "solution=%s", nvti_solution (nvti)); - } - if (nvti_solution_type (nvti)) - { - if (tag->str) - g_string_append_printf (tag, "|solution_type=%s", nvti_solution_type (nvti)); - else - g_string_append_printf (tag, "solution_type=%s", nvti_solution_type (nvti)); - } - quoted_tag = sql_quote (tag->str); g_string_free (tag, TRUE); } From 08cd580f88c219f1cfd16d98458875f74734436a Mon Sep 17 00:00:00 2001 From: Jan-Oliver Wagner Date: Sun, 11 Aug 2019 14:12:09 +0200 Subject: [PATCH 8/8] Add migrator to add column solution to table nvts. --- CMakeLists.txt | 2 +- src/manage_migrators.c | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbcd70aa0..9c810c609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ include (CPack) ## Variables -set (GVMD_DATABASE_VERSION 215) +set (GVMD_DATABASE_VERSION 216) set (GVMD_SCAP_DATABASE_VERSION 15) diff --git a/src/manage_migrators.c b/src/manage_migrators.c index 52b42511c..31483c2af 100644 --- a/src/manage_migrators.c +++ b/src/manage_migrators.c @@ -1163,18 +1163,18 @@ migrate_213_to_214 () } /** - * @brief Migrate the database from version 215 to version 216. + * @brief Migrate the database from version 214 to version 215. * * @return 0 success, -1 error. */ int -migrate_215_to_216 () +migrate_214_to_215 () { sql_begin_immediate (); - /* Ensure that the database is currently version 215. */ + /* Ensure that the database is currently version 214. */ - if (manage_db_version () != 215) + if (manage_db_version () != 214) { sql_rollback (); return -1; @@ -1182,33 +1182,31 @@ migrate_215_to_216 () /* Update the database. */ - /* Extend table "nvts" with additional column "solution" */ - sql ("ALTER TABLE IF EXISTS nvts ADD COLUMN solution text;"); + /* The column nbefile was removed from reports. */ + sql ("ALTER TABLE reports DROP COLUMN nbefile;"); - /* Set the database version to 216. */ + /* Set the database version to 215 */ - set_db_version (216); + set_db_version (215); sql_commit (); return 0; } -#undef UPDATE_DASHBOARD_SETTINGS - /** - * @brief Migrate the database from version 214 to version 215. + * @brief Migrate the database from version 215 to version 216. * * @return 0 success, -1 error. */ int -migrate_214_to_215 () +migrate_215_to_216 () { sql_begin_immediate (); - /* Ensure that the database is currently version 214. */ + /* Ensure that the database is currently version 215. */ - if (manage_db_version () != 214) + if (manage_db_version () != 215) { sql_rollback (); return -1; @@ -1216,18 +1214,20 @@ migrate_214_to_215 () /* Update the database. */ - /* The column nbefile was removed from reports. */ - sql ("ALTER TABLE reports DROP COLUMN nbefile;"); + /* Extend table "nvts" with additional column "solution" */ + sql ("ALTER TABLE IF EXISTS nvts ADD COLUMN solution text;"); - /* Set the database version to 215 */ + /* Set the database version to 216. */ - set_db_version (215); + set_db_version (216); sql_commit (); return 0; } +#undef UPDATE_DASHBOARD_SETTINGS + /** * @brief The oldest version for which migration is supported */ @@ -1247,6 +1247,7 @@ static migrator_t database_migrators[] = { {213, migrate_212_to_213}, {214, migrate_213_to_214}, {215, migrate_214_to_215}, + {216, migrate_215_to_216}, /* End marker. */ {-1, NULL}};