diff --git a/CHANGELOG.md b/CHANGELOG.md index bab1f22b6..73a798664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -122,6 +122,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Deprecated ### Removed ### Fixed +- Fix VTs hash check and add --dump-vt-verification [#1611](https://github.com/greenbone/gvmd/pull/1611) - Fix memory errors in modify_permission [#1613](https://github.com/greenbone/gvmd/pull/1613) [Unreleased]: https://github.com/greenbone/gvmd/compare/v20.8.2...gvmd-20.08 diff --git a/src/gvmd.c b/src/gvmd.c index 6aa6d6dc6..d00f8eff9 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -1787,6 +1787,7 @@ gvmd (int argc, char** argv) static gboolean decrypt_all_credentials = FALSE; static gboolean disable_password_policy = FALSE; static gboolean disable_scheduling = FALSE; + static gboolean dump_vt_verification = FALSE; static gboolean get_roles = FALSE; static gboolean get_users = FALSE; static gboolean get_scanners = FALSE; @@ -1915,6 +1916,10 @@ gvmd (int argc, char** argv) &disable_scheduling, "Disable task scheduling.", NULL }, + { "dump-vt-verification", '\0', 0, G_OPTION_ARG_NONE, + &dump_vt_verification, + "Dump the string the VTs verification hash is calculated from.", + NULL }, { "encrypt-all-credentials", '\0', 0, G_OPTION_ARG_NONE, &encrypt_all_credentials, "(Re-)Encrypt all credentials.", @@ -2568,6 +2573,25 @@ gvmd (int argc, char** argv) } return EXIT_SUCCESS; } + + if (dump_vt_verification) + { + int ret; + + proctitle_set ("gvmd: --dump-vt-verification"); + + if (option_lock (&lockfile_checking)) + return EXIT_FAILURE; + + ret = manage_dump_vt_verification (log_config, &database); + log_config_free (); + if (ret) + { + printf ("Failed to dump VT verification data.\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } if (create_scanner) { diff --git a/src/manage.h b/src/manage.h index 1b3d99f77..7641b4f8a 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3674,6 +3674,9 @@ manage_update_nvts_osp (const gchar *); int manage_rebuild (GSList *, const db_conn_info_t *); +int +manage_dump_vt_verification (GSList *, const db_conn_info_t *); + /* Wizards. */ diff --git a/src/manage_pg.c b/src/manage_pg.c index 00715dfc1..554d0d36d 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -843,6 +843,35 @@ manage_create_sql_functions () /* Functions in SQL. */ + sql ("CREATE OR REPLACE FUNCTION vts_verification_str () RETURNS text AS $$" + " WITH pref_str AS (" + " SELECT name," + " substring(name, '^(.*?):') AS oid," + " substring (name, '^.*?:([^:]+):') AS pref_id," + " (substring (name, '^.*?:([^:]+):')" + " || substring (name," + " '^[^:]*:[^:]*:[^:]*:(.*)')" + " || value) AS pref" + " FROM nvt_preferences" + " )," + " nvt_str AS (" + " SELECT (SELECT nvts.oid" + " || max(modification_time)" + " || coalesce (string_agg(pref_str.pref, ''" + " ORDER BY (pref_id" + " COLLATE \"C.UTF-8\"))," + " ''))" + " AS vt_string" + " FROM nvts" + " LEFT JOIN pref_str ON nvts.oid = pref_str.oid" + " GROUP BY nvts.oid" + " ORDER BY (nvts.oid COLLATE \"C.UTF-8\") ASC" + " )" + " SELECT coalesce (string_agg (nvt_str.vt_string, ''), '')" + " FROM nvt_str" + "$$ LANGUAGE SQL" + " STABLE;"); + sql ("CREATE OR REPLACE FUNCTION t () RETURNS boolean AS $$" " SELECT true;" "$$ LANGUAGE SQL" diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 50f359bfb..bff3504bc 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -1594,35 +1594,10 @@ update_nvts_from_vts (entity_t *get_vts_response, * All values are concatenated without a separator. */ db_vts_hash - = sql_string ("WITH pref_str AS (" - " SELECT name," - " substring(name, '^(.*?):') AS oid," - " substring (name, '^.*?:([^:]+):') AS pref_id," - " (substring (name, '^.*?:([^:]+):')" - " || substring (name," - " '^[^:]*:[^:]*:[^:]*:(.*)')" - " || value) AS pref" - " FROM nvt_preferences" - " )," - " nvt_str AS (" - " SELECT (SELECT nvts.oid" - " || max(modification_time)" - " || coalesce (string_agg(pref_str.pref, ''" - " ORDER BY pref_id)," - " ''))" - " AS vt_string" - " FROM nvts" - " LEFT JOIN pref_str ON nvts.oid = pref_str.oid" - " GROUP BY nvts.oid" - " ORDER BY nvts.oid ASC" - " )" - " SELECT encode" - " (digest" - " (coalesce (string_agg (nvt_str.vt_string, '')," - " '')," - " 'sha256')," - " 'hex')" - " FROM nvt_str;"); + = sql_string ("SELECT encode (" + " digest (vts_verification_str (), 'SHA256')," + " 'hex'" + " );"); if (strcmp (osp_vt_hash, db_vts_hash ? db_vts_hash : "")) { @@ -2224,3 +2199,47 @@ manage_rebuild (GSList *log_config, const db_conn_info_t *database) return ret; } + +/** + * @brief Dump the string used to calculate the VTs verification hash + * to stdout. + * + * @param[in] log_config Log configuration. + * @param[in] database Location of manage database. + * + * @return 0 success, -1 error, -2 database is wrong version, + * -3 database needs to be initialised from server, -5 sync active. + */ +int +manage_dump_vt_verification (GSList *log_config, + const db_conn_info_t *database) +{ + int ret; + static lockfile_t lockfile; + char *verification_str; + + switch (feed_lockfile_lock_timeout (&lockfile)) + { + case 1: + printf ("A feed sync is already running.\n"); + return -5; + case -1: + printf ("Error getting sync lock.\n"); + return -1; + } + + ret = manage_option_setup (log_config, database); + if (ret) + { + feed_lockfile_unlock (&lockfile); + return ret; + } + + verification_str = sql_string ("SELECT vts_verification_str ();"); + printf ("%s\n", verification_str); + + feed_lockfile_unlock (&lockfile); + manage_option_cleanup (); + + return 0; +} \ No newline at end of file