diff --git a/CHANGELOG.md b/CHANGELOG.md index bc7d0424c..4b246b8d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Update SCAP and CERT feed info in sync scripts [#809](https://github.com/greenbone/gvmd/pull/809) - Try authentication when verifying GMP scanners [#837](https://github.com/greenbone/gvmd/pull/837) - Try importing private keys with libssh if GnuTLS fails [#841](https://github.com/greenbone/gvmd/pull/841) +- Require Postgres 9.6 as a minimum [#872](https://github.com/greenbone/gvmd/pull/872) ### Fixed - Consider results_trash when deleting users [#799](https://github.com/greenbone/gvmd/pull/799) diff --git a/INSTALL.md b/INSTALL.md index 278fe968f..ef49a8600 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -17,7 +17,7 @@ Prerequisites: * glib-2.0 >= 2.42 * gnutls >= 3.2.15 * libgvm_base, libgvm_util, libgvm_osp, libgvm_gmp >= 11.0.0 -* PostgreSQL database +* PostgreSQL database >= 9.6 * pkg-config * libical >= 1.0.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72f792c74..c913db8f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,14 @@ find_package (PostgreSQL REQUIRED) if (NOT PostgreSQL_FOUND) message (SEND_ERROR "The PostgreSQL library is required.") endif (NOT PostgreSQL_FOUND) +string (REGEX MATCH "^[ \t]*\([0-9]+\)\\.\([0-9]+\)\(.*\)" TEMP ${PostgreSQL_VERSION_STRING}) +if (NOT CMAKE_MATCH_1) + message (SEND_ERROR "Error matching PostgreSQL version.") +elseif ((CMAKE_MATCH_1 EQUAL 9 AND CMAKE_MATCH_2 LESS 6) + OR (CMAKE_MATCH_1 LESS 9)) + message (SEND_ERROR "PostgreSQL version >= 9.6 is required") + message (STATUS "PostgreSQL version ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}${CMAKE_MATCH_3}") +endif (NOT CMAKE_MATCH_1) message (STATUS "Looking for gpgme...") find_library (GPGME gpgme) diff --git a/src/manage_pg.c b/src/manage_pg.c index e91b9f964..555f5b231 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -3600,6 +3600,7 @@ manage_db_init (const gchar *name) sql ("CREATE TABLE scap.affected_products" " (cve INTEGER NOT NULL," " cpe INTEGER NOT NULL," + " UNIQUE (cve, cpe)," " FOREIGN KEY(cve) REFERENCES cves(id)," " FOREIGN KEY(cpe) REFERENCES cpes(id));"); sql ("CREATE INDEX afp_cpe_idx" @@ -3696,7 +3697,7 @@ manage_db_init (const gchar *name) /* Init tables. */ sql ("INSERT INTO scap.meta (name, value)" - " VALUES ('database_version', '15');"); + " VALUES ('database_version', '16');"); sql ("INSERT INTO scap.meta (name, value)" " VALUES ('last_update', '0');"); } diff --git a/src/manage_sql.c b/src/manage_sql.c index a8b8d4096..a7227d6bf 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -21040,16 +21040,8 @@ result_nvt_notice (const gchar *nvt) { if (nvt == NULL) return; - if (sql_int ("SELECT current_setting ('server_version_num')::integer;") - < 90500) - sql ("INSERT into result_nvts (nvt)" - " SELECT '%s' WHERE NOT EXISTS (SELECT * FROM result_nvts" - " WHERE nvt = '%s');", - nvt, - nvt); - else - sql ("INSERT INTO result_nvts (nvt) VALUES ('%s') ON CONFLICT DO NOTHING;", - nvt); + sql ("INSERT INTO result_nvts (nvt) VALUES ('%s') ON CONFLICT DO NOTHING;", + nvt); } /** @@ -49313,7 +49305,6 @@ buffer_insert (GString *results_buffer, GString *result_nvts_buffer, const char* type, const char* description, report_t report, user_t owner) { - static int db_server_version_num = 0; gchar *nvt_revision, *severity; gchar *quoted_hostname, *quoted_descr, *quoted_qod_type; int qod, first; @@ -49321,9 +49312,6 @@ buffer_insert (GString *results_buffer, GString *result_nvts_buffer, assert (report); - if (db_server_version_num == 0) - db_server_version_num = sql_server_version (); - if (nvt && strcmp (nvt, "") && (find_nvt (nvt, &nvt_id) || nvt_id <= 0)) { g_warning ("NVT '%s' not found. Result not created", nvt); @@ -49392,25 +49380,15 @@ buffer_insert (GString *results_buffer, GString *result_nvts_buffer, " description, uuid, qod, qod_type, result_nvt," " report)" " VALUES"); - if (db_server_version_num >= 90500) - g_string_append (result_nvts_buffer, - "INSERT INTO result_nvts (nvt) VALUES "); - } - - if (db_server_version_num < 90500) - g_string_append_printf - (result_nvts_buffer, - "INSERT into result_nvts (nvt)" - " SELECT '%s' WHERE NOT EXISTS (SELECT * FROM result_nvts" - " WHERE nvt = '%s');\n", - nvt, - nvt); - else - g_string_append_printf - (result_nvts_buffer, - "%s ('%s')", - first ? "" : ",", - nvt); + g_string_append (result_nvts_buffer, + "INSERT INTO result_nvts (nvt) VALUES "); + } + + g_string_append_printf + (result_nvts_buffer, + "%s ('%s')", + first ? "" : ",", + nvt); g_string_append_printf (results_buffer, "%s" @@ -49447,9 +49425,8 @@ update_from_slave_insert (GString *results_buffer, GString *result_nvts_buffer, { if (result_nvts_buffer && strlen (result_nvts_buffer->str)) { - if (sql_server_version () >= 90500) - g_string_append (result_nvts_buffer, - " ON CONFLICT (nvt) DO NOTHING;"); + g_string_append (result_nvts_buffer, + " ON CONFLICT (nvt) DO NOTHING;"); sql ("%s", result_nvts_buffer->str); g_string_truncate (result_nvts_buffer, 0); diff --git a/src/manage_sql_secinfo.c b/src/manage_sql_secinfo.c index 58889b229..c7ade0a88 100644 --- a/src/manage_sql_secinfo.c +++ b/src/manage_sql_secinfo.c @@ -1517,8 +1517,20 @@ update_dfn_xml (const gchar *xml_path, int last_cert_update, quoted_refnum = sql_quote (entity_text (refnum)); quoted_title = sql_quote (entity_text (title)); quoted_summary = sql_quote (entity_text (summary)); - sql ("SELECT merge_dfn_cert_adv" - " ('%s', %i, %i, '%s', '%s', %i);", + sql ("INSERT INTO cert.dfn_cert_advs" + " (uuid, name, comment, creation_time," + " modification_time, title, summary, cve_refs)" + " VALUES" + " ('%s', '%s', '', %i, %i, '%s', '%s', %i)" + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.uuid," + " comment = ''," + " creation_time = EXCLUDED.creation," + " modification_time = EXCLUDED.modification," + " title = EXCLUDED.title," + " summary = EXCLUDED.summary," + " cve_refs = EXCLUDED.cve_refs;", + quoted_refnum, quoted_refnum, parse_iso_time (entity_text (published)), parse_iso_time (entity_text (updated)), @@ -1803,8 +1815,20 @@ update_bund_xml (const gchar *xml_path, int last_cert_update, quoted_title = sql_quote (entity_text (title)); quoted_summary = sql_quote (summary->str); g_string_free (summary, TRUE); - sql ("SELECT merge_bund_adv" - " ('%s', %i, %i, '%s', '%s', %i);", + sql ("INSERT INTO cert.cert_bund_advs" + " (uuid, name, comment, creation_time," + " modification_time, title, summary, cve_refs)" + " VALUES" + " ('%s', '%s', '', %i, %i, '%s', '%s', %i)" + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.uuid," + " comment = ''," + " creation_time = EXCLUDED.creation_time," + " modification_time = EXCLUDED.modification_time," + " title = EXCLUDED.title," + " summary = EXCLUDED.summary," + " cve_refs = EXCLUDED.cve_refs;", + quoted_refnum, quoted_refnum, parse_iso_time (entity_text (date)), parse_iso_time (entity_text (date)), @@ -2096,8 +2120,21 @@ update_scap_cpes (int last_scap_update) g_free (name_tilde); quoted_status = sql_quote (status); quoted_nvd_id = sql_quote (nvd_id); - sql ("SELECT merge_cpe" - " ('%s', '%s', %i, %i, '%s', %s, '%s');", + sql ("INSERT INTO scap.cpes" + " (uuid, name, title, creation_time," + " modification_time, status, deprecated_by_id," + " nvd_id)" + " VALUES" + " ('%s', '%s', '%s', %i, %i, '%s', %s, '%s')" + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.name," + " title = EXCLUDED.title," + " 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;", + quoted_name, quoted_name, quoted_title, parse_iso_time (modification_date), @@ -2394,9 +2431,28 @@ update_cve_xml (const gchar *xml_path, int last_scap_update, g_free (software_tilde); time_modified = parse_iso_time (entity_text (last_modified)); time_published = parse_iso_time (entity_text (published)); - sql ("SELECT merge_cve" - " ('%s', '%s', %i, %i, %s, '%s', '%s', '%s', '%s'," - " '%s', '%s', '%s', '%s');", + sql ("INSERT INTO scap.cves" + " (uuid, name, creation_time, modification_time," + " cvss, description, vector, complexity," + " authentication, confidentiality_impact," + " integrity_impact, availability_impact, products)" + " VALUES" + " ('%s', '%s', %i, %i, %s, '%s', '%s', '%s', '%s'," + " '%s', '%s', '%s', '%s')" + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.name," + " creation_time = EXCLUDED.creation_time," + " modification_time = EXCLUDED.modification_time," + " cvss = EXCLUDED.cvss," + " description = EXCLUDED.description," + " vector = EXCLUDED.vector," + " complexity = EXCLUDED.complexity," + " authentication = EXCLUDED.authentication," + " confidentiality_impact" + " = EXCLUDED.confidentiality_impact," + " integrity_impact = EXCLUDED.integrity_impact," + " availability_impact = EXCLUDED.availability_impact," + " products = EXCLUDED.products;", quoted_id, quoted_id, time_published, @@ -2451,13 +2507,22 @@ update_cve_xml (const gchar *xml_path, int last_scap_update, quoted_product = sql_quote (product_tilde); g_free (product_tilde); - sql ("SELECT merge_cpe_name ('%s', '%s', %i, %i)", + sql ("INSERT INTO scap.cpes" + " (uuid, name, creation_time," + " modification_time)" + " VALUES" + " ('%s', '%s', %i, %i)" + " ON CONFLICT (uuid)" + " DO UPDATE SET name = EXCLUDED.name;", quoted_product, quoted_product, time_published, time_modified); - sql ("SELECT merge_affected_product" - " (%llu," - " (SELECT id FROM cpes" - " WHERE name='%s'))", + sql ("INSERT INTO scap.affected_products" + " (cve, cpe)" + " VALUES" + " (%llu," + " (SELECT id FROM cpes" + " WHERE name='%s'))" + " ON CONFLICT (cve, cpe) DO NOTHING;", cve_rowid, quoted_product); transaction_size ++; increment_transaction_size (&transaction_size); @@ -3052,9 +3117,27 @@ update_ovaldef_xml (gchar **file_and_date, int last_scap_update, else quoted_status = sql_quote (""); - sql ("SELECT merge_ovaldef ('%s', '%s', '', %i, %i, %i, %i," - " '%s', '%s', '%s', '%s', '%s'," - " %i);", + sql ("INSERT INTO scap.ovaldefs" + " (uuid, name, comment, creation_time," + " modification_time, version, deprecated, def_class," + " title, description, xml_file, status," + " max_cvss, cve_refs)" + " VALUES ('%s', '%s', '', %i, %i, %i, %i, '%s', '%s'," + " '%s', '%s', '%s', 0.0, %i)" + " ON CONFLICT (uuid) DO UPDATE" + " SET name = EXCLUDED.name," + " comment = EXCLUDED.comment," + " creation_time = EXCLUDED.creation_time," + " modification_time = EXCLUDED.modification_time," + " version = EXCLUDED.version," + " deprecated = EXCLUDED.deprecated," + " def_class = EXCLUDED.def_class," + " title = EXCLUDED.title," + " description = EXCLUDED.description," + " xml_file = EXCLUDED.xml_file," + " status = EXCLUDED.status," + " max_cvss = 0.0," + " cve_refs = EXCLUDED.cve_refs;", quoted_id, quoted_oval_id, definition_date_oldest == 0 @@ -4120,6 +4203,12 @@ check_scap_db_version () g_info ("Reinitialization of the database necessary"); return manage_db_reinit ("scap"); break; + case 15: + sql ("ALTER TABLE scap.affected_products ADD UNIQUE (cve, cpe);"); + sql ("UPDATE scap.meta" + " SET value = '16'" + " WHERE name = 'database_version';"); + break; } return 0; } diff --git a/src/sql.h b/src/sql.h index 3990f1058..14ed47830 100644 --- a/src/sql.h +++ b/src/sql.h @@ -31,9 +31,6 @@ /* Helpers. */ -int -sql_server_version (); - const char * sql_schema (); diff --git a/src/sql_pg.c b/src/sql_pg.c index 4c52717b2..fb4a2dce2 100644 --- a/src/sql_pg.c +++ b/src/sql_pg.c @@ -87,17 +87,6 @@ static PGconn *conn = NULL; /* Helpers. */ -/** - * @brief Get the server version number. - * - * @return The version as an integer. - */ -int -sql_server_version () -{ - return sql_int ("SELECT current_setting ('server_version_num')::integer;"); -} - /** * @brief Get main schema name. * @@ -365,6 +354,15 @@ sql_open (const char *database) g_debug ("%s: socket: %i", __FUNCTION__, PQsocket (conn)); g_debug ("%s: postgres version: %i", __FUNCTION__, PQserverVersion (conn)); + if (PQserverVersion (conn) < 90600) + { + g_warning ("%s: PostgreSQL version 9.6 (90600) or higher is required", + __FUNCTION__); + g_warning ("%s: Current version is %i", __FUNCTION__, + PQserverVersion (conn)); + goto fail; + } + return 0; fail: