From 6a1cee45b0b35f057de2c2d0292d0936b04da4fd Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 1 Jul 2024 15:02:56 -0300 Subject: [PATCH 01/13] Add: functions to handle an Openvasd scan task --- src/CMakeLists.txt | 28 +- src/gvmd.c | 4 + src/manage.c | 757 +++++++++++++++++++++++++++++++++++++++ src/manage.h | 9 +- src/manage_sql.c | 380 +++++++++++++++++++- src/manage_sql.h | 3 + src/manage_sql_configs.c | 5 + 7 files changed, 1166 insertions(+), 20 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5e8c79c0..3cd3da580 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,7 +91,7 @@ else (WITH_LIBTHEIA) set (OPT_THEIA_TGT "") endif (WITH_LIBTHEIA) -include_directories (${LIBGVM_GMP_INCLUDE_DIRS} +include_directories (${LIBGVM_GMP_INCLUDE_DIRS} ${LIBGVM_OPENVASD_INCLUDE_DIRS} ${LIBGVM_BASE_INCLUDE_DIRS} ${LIBGVM_UTIL_INCLUDE_DIRS} ${LIBGVM_OSP_INCLUDE_DIRS} ${LIBBSD_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS}) @@ -313,34 +313,34 @@ add_executable (gvmd target_link_libraries (gvmd m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-sql-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (gmp-tickets-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} - ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) -target_link_libraries (gvm-pg-server ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} + ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) +target_link_libraries (gvm-pg-server ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_OPENVASD_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) set_target_properties (gvmd PROPERTIES LINKER_LANGUAGE C) set_target_properties (manage-test PROPERTIES LINKER_LANGUAGE C) diff --git a/src/gvmd.c b/src/gvmd.c index 0fbe8051b..737a0f568 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -2836,6 +2836,8 @@ gvmd (int argc, char** argv, char *env[]) type = SCANNER_TYPE_OPENVAS; else if (!strcasecmp (scanner_type, "OSP-Sensor")) type = SCANNER_TYPE_OSP_SENSOR; + else if (!strcasecmp (scanner_type, "Openvasd")) + type = SCANNER_TYPE_OPENVASD; else { type = atoi (scanner_type); @@ -2878,6 +2880,8 @@ gvmd (int argc, char** argv, char *env[]) type = SCANNER_TYPE_OPENVAS; else if (!strcasecmp (scanner_type, "OSP-Sensor")) type = SCANNER_TYPE_OSP_SENSOR; + else if (!strcasecmp (scanner_type, "Openvasd")) + type = SCANNER_TYPE_OPENVASD; else { type = atoi (scanner_type); diff --git a/src/manage.c b/src/manage.c index fca82209f..79ca62f88 100644 --- a/src/manage.c +++ b/src/manage.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -4016,6 +4017,11 @@ slave_get_relay (const char *original_host, return ret; } + +/* Prototype */ +static int +run_openvasd_task (task_t task, int from, char **report_id); + /** * @brief Start or resume a task. * @@ -4078,6 +4084,9 @@ run_task (const char *task_id, char **report_id, int from) || scanner_type (scanner) == SCANNER_TYPE_OSP_SENSOR) return run_osp_task (task, from, report_id); + if (scanner_type (scanner) == SCANNER_TYPE_OPENVASD) + return run_openvasd_task (task, from, report_id); + return -1; // Unknown scanner type } @@ -4204,6 +4213,9 @@ stop_task_internal (task_t task) return 0; } +static int +stop_openvasd_task (task_t task); + /** * @brief Initiate stopping a task. * @@ -4230,6 +4242,9 @@ stop_task (const char *task_id) || scanner_type (task_scanner (task)) == SCANNER_TYPE_OSP_SENSOR) return stop_osp_task (task); + if (scanner_type (task_scanner (task)) == SCANNER_TYPE_OPENVASD) + return stop_openvasd_task (task); + return stop_task_internal (task); } @@ -8201,3 +8216,745 @@ delete_resource (const char *type, const char *resource_id, int ultimate) assert (0); return -1; } + +/* Openvasd */ + +/** + * @brief Stop an Openvasd task. + * + * @param[in] task The task. + * + * @return 0 on success, else -1. + */ +static int +stop_openvasd_task (task_t task) +{ + int ret = -1; + report_t scan_report; + char *scan_id; + task_t previous_task; + report_t previous_report; + + scanner_t scanner; + openvasd_resp_t response; + openvasd_connector_t connector = NULL; + + previous_task = current_scanner_task; + previous_report = global_current_report; + + scan_report = task_running_report (task); + scan_id = report_uuid (scan_report); + if (!scan_id) + goto end_stop_openvasd; + scanner = task_scanner (task); + connector = openvasd_scanner_connect (scanner, scan_id); + if (!connector) + goto end_stop_openvasd; + + current_scanner_task = task; + global_current_report = task_running_report (task); + set_task_run_status (task, TASK_STATUS_STOP_REQUESTED); + response = openvasd_stop_scan (&connector); + if (response->code < 0) + { + g_free (scan_id); + goto end_stop_openvasd; + } + + response = openvasd_delete_scan (&connector); + g_free (scan_id); + +end_stop_openvasd: + openvasd_connector_free(&connector); + set_task_end_time_epoch (task, time (NULL)); + set_task_run_status (task, TASK_STATUS_STOPPED); + if (scan_report) + { + set_scan_end_time_epoch (scan_report, time (NULL)); + set_report_scan_run_status (scan_report, TASK_STATUS_STOPPED); + } + current_scanner_task = previous_task; + global_current_report = previous_report; + if (ret) + return -1; + return 0; +} + +/** + * @brief Launch an OpenVAS via Openvasd task. + * + * @param[in] task The task. + * @param[in] target The target. + * @param[in] scan_id The scan uuid. + * @param[in] from 0 start from beginning, 1 continue from stopped, + * 2 continue if stopped else start from beginning. + * @param[out] error Error return. + * + * @return An http code on success, -1 if error. + */ +static int +launch_openvasd_openvas_task (task_t task, target_t target, const char *scan_id, + int from, char **error) +{ + openvasd_connector_t connection; + char *hosts_str, *ports_str, *exclude_hosts_str, *finished_hosts_str; + gchar *clean_hosts, *clean_exclude_hosts, *clean_finished_hosts_str; + int alive_test, reverse_lookup_only, reverse_lookup_unify; + int arp = 0, icmp = 0, tcp_ack = 0, tcp_syn = 0, consider_alive = 0; + openvasd_target_t *openvasd_target; + GSList *openvasd_targets, *vts; + GHashTable *vts_hash_table; + openvasd_credential_t *ssh_credential, *smb_credential, *esxi_credential; + openvasd_credential_t *snmp_credential; + gchar *max_checks, *max_hosts, *hosts_ordering; + GHashTable *scanner_options; + openvasd_resp_t response; + int ret, empty; + config_t config; + iterator_t scanner_prefs_iter, families, prefs; + + connection = NULL; + config = task_config (task); + + alive_test = 0; + reverse_lookup_unify = 0; + reverse_lookup_only = 0; + + /* Prepare the report */ + if (from) + { + ret = prepare_osp_scan_for_resume (task, scan_id, error); + if (ret == 0) + return 0; + else if (ret == -1) + return -1; + finished_hosts_str = report_finished_hosts_str (global_current_report); + clean_finished_hosts_str = clean_hosts_string (finished_hosts_str); + } + else + { + finished_hosts_str = NULL; + clean_finished_hosts_str = NULL; + } + + /* Set up target(s) */ + hosts_str = target_hosts (target); + ports_str = target_port_range (target); + exclude_hosts_str = target_exclude_hosts (target); + + clean_hosts = clean_hosts_string (hosts_str); + clean_exclude_hosts = clean_hosts_string (exclude_hosts_str); + + alive_test = 0; + if (target_alive_tests (target) > 0) + alive_test = target_alive_tests (target); + + if (target_reverse_lookup_only (target) != NULL) + reverse_lookup_only = atoi (target_reverse_lookup_only (target)); + + if (target_reverse_lookup_unify (target) != NULL) + reverse_lookup_unify = atoi (target_reverse_lookup_unify (target)); + + if (finished_hosts_str) + { + gchar *new_exclude_hosts; + + new_exclude_hosts = g_strdup_printf ("%s,%s", + clean_exclude_hosts, + clean_finished_hosts_str); + free (clean_exclude_hosts); + clean_exclude_hosts = new_exclude_hosts; + } + + openvasd_target = openvasd_target_new (scan_id, clean_hosts, ports_str, + clean_exclude_hosts, + reverse_lookup_unify, + reverse_lookup_only); + if (finished_hosts_str) + openvasd_target_set_finished_hosts (openvasd_target, finished_hosts_str); + + if (alive_test & ALIVE_TEST_ARP) + arp = 1; + if (alive_test & ALIVE_TEST_ICMP) + icmp = 1; + if (alive_test & ALIVE_TEST_TCP_ACK_SERVICE) + tcp_ack = 1; + if (alive_test & ALIVE_TEST_TCP_SYN_SERVICE) + tcp_syn = 1; + if (alive_test & ALIVE_TEST_CONSIDER_ALIVE) + consider_alive = 1; + + openvasd_target_add_alive_test_methods (openvasd_target, icmp, tcp_syn, + tcp_ack, arp, consider_alive); + + free (hosts_str); + free (ports_str); + free (exclude_hosts_str); + free (finished_hosts_str); + g_free (clean_hosts); + g_free (clean_exclude_hosts); + g_free (clean_finished_hosts_str); + openvasd_targets = g_slist_append (NULL, openvasd_target); + + ssh_credential = (openvasd_credential_t *) target_osp_ssh_credential (target); + if (ssh_credential) + openvasd_target_add_credential (openvasd_target, ssh_credential); + + smb_credential = (openvasd_credential_t *) target_osp_smb_credential (target); + if (smb_credential) + openvasd_target_add_credential (openvasd_target, smb_credential); + + esxi_credential = + (openvasd_credential_t *) target_osp_esxi_credential (target); + if (esxi_credential) + openvasd_target_add_credential (openvasd_target, esxi_credential); + + snmp_credential = + (openvasd_credential_t *) target_osp_snmp_credential (target); + if (snmp_credential) + openvasd_target_add_credential (openvasd_target, snmp_credential); + + /* Initialize vts table for vulnerability tests and their preferences */ + vts = NULL; + vts_hash_table + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + /* Value is freed in vts list. */ + NULL); + + /* Setup of vulnerability tests (without preferences) */ + init_family_iterator (&families, 0, NULL, 1); + empty = 1; + while (next (&families)) + { + const char *family = family_iterator_name (&families); + if (family) + { + iterator_t nvts; + init_nvt_iterator (&nvts, 0, config, family, NULL, 1, NULL); + while (next (&nvts)) + { + const char *oid; + openvasd_vt_single_t *new_vt; + + empty = 0; + oid = nvt_iterator_oid (&nvts); + new_vt = openvasd_vt_single_new (oid); + + vts = g_slist_prepend (vts, new_vt); + g_hash_table_replace (vts_hash_table, g_strdup (oid), new_vt); + } + cleanup_iterator (&nvts); + } + } + cleanup_iterator (&families); + + if (empty) { + if (error) + *error = g_strdup ("Exiting because VT list is empty " + "(e.g. feed not synced yet)"); + g_slist_free_full (openvasd_targets, (GDestroyNotify) openvasd_target_free); + // Credentials are freed with target + g_slist_free_full (vts, (GDestroyNotify) openvasd_vt_single_free); + return -1; + } + + /* Setup general scanner preferences */ + scanner_options + = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + init_preference_iterator (&scanner_prefs_iter, config, "SERVER_PREFS"); + while (next (&scanner_prefs_iter)) + { + const char *name, *value; + name = preference_iterator_name (&scanner_prefs_iter); + value = preference_iterator_value (&scanner_prefs_iter); + if (name && value && !g_str_has_prefix (name, "timeout.")) + { + const char *openvasd_value; + + // Workaround for boolean scanner preferences + if (strcmp (value, "0") == 0) + openvasd_value = "no"; + else if (strcmp (value, "1") == 0) + openvasd_value = "yes"; + else + openvasd_value = value; + g_hash_table_replace (scanner_options, + g_strdup (name), + g_strdup (openvasd_value)); + } + /* Timeouts are stored as SERVER_PREFS, but are actually + script preferences. This prefs is converted into a + script preference to be sent to the scanner. */ + else if (name && value && g_str_has_prefix (name, "timeout.")) + { + char **oid = NULL; + openvasd_vt_single_t *openvasd_vt = NULL; + + oid = g_strsplit (name, ".", 2); + openvasd_vt = g_hash_table_lookup (vts_hash_table, oid[1]); + if (openvasd_vt) + openvasd_vt_single_add_value (openvasd_vt, "0", value); + g_strfreev (oid); + } + + } + cleanup_iterator (&scanner_prefs_iter); + + /* Setup user-specific scanner preference */ + add_user_scan_preferences (scanner_options); + + /* Setup general task preferences */ + max_checks = task_preference_value (task, "max_checks"); + g_hash_table_insert (scanner_options, g_strdup ("max_checks"), + max_checks ? max_checks : g_strdup (MAX_CHECKS_DEFAULT)); + + max_hosts = task_preference_value (task, "max_hosts"); + g_hash_table_insert (scanner_options, g_strdup ("max_hosts"), + max_hosts ? max_hosts : g_strdup (MAX_HOSTS_DEFAULT)); + + hosts_ordering = task_hosts_ordering (task); + if (hosts_ordering) + g_hash_table_insert (scanner_options, g_strdup ("hosts_ordering"), + hosts_ordering); + + /* Setup VT preferences */ + init_preference_iterator (&prefs, config, "PLUGINS_PREFS"); + while (next (&prefs)) + { + const char *full_name, *value; + openvasd_vt_single_t *openvasd_vt; + gchar **split_name; + + full_name = preference_iterator_name (&prefs); + value = preference_iterator_value (&prefs); + split_name = g_strsplit (full_name, ":", 4); + + openvasd_vt = NULL; + if (split_name && split_name[0] && split_name[1] && split_name[2]) + { + const char *oid = split_name[0]; + const char *pref_id = split_name[1]; + const char *type = split_name[2]; + gchar *openvasd_value = NULL; + + if (strcmp (type, "checkbox") == 0) + { + if (strcmp (value, "yes") == 0) + openvasd_value = g_strdup ("1"); + else + openvasd_value = g_strdup ("0"); + } + else if (strcmp (type, "radio") == 0) + { + gchar** split_value; + split_value = g_strsplit (value, ";", 2); + openvasd_value = g_strdup (split_value[0]); + g_strfreev (split_value); + } + else if (strcmp (type, "file") == 0) + openvasd_value = g_base64_encode ((guchar*) value, strlen (value)); + + openvasd_vt = g_hash_table_lookup (vts_hash_table, oid); + if (openvasd_vt) + openvasd_vt_single_add_value (openvasd_vt, pref_id, + openvasd_value ? openvasd_value : value); + g_free (openvasd_value); + } + + g_strfreev (split_name); + } + cleanup_iterator (&prefs); + g_hash_table_destroy (vts_hash_table); + + /* Start the scan */ + connection = openvasd_scanner_connect (task_scanner (task), scan_id); + if (!connection) + { + if (error) + *error = g_strdup ("Could not connect to Scanner"); + g_slist_free_full (openvasd_targets, + (GDestroyNotify) openvasd_target_free); + // Credentials are freed with target + g_slist_free_full (vts, (GDestroyNotify) openvasd_vt_single_free); + g_hash_table_destroy (scanner_options); + return -1; + } + + gchar *scan_config = NULL; + scan_config = + openvasd_build_scan_config_json(openvasd_target, scanner_options, vts); + + response = openvasd_start_scan (&connection, scan_config); + openvasd_target_free(openvasd_target); + // Credentials are freed with target + g_slist_free_full (vts, (GDestroyNotify) openvasd_vt_single_free); + g_hash_table_destroy (scanner_options); + ret = response->code; + openvasd_response_free (response); + + return ret; +} + +/** + * @brief Handle an ongoing Openvasd scan, until success or failure. + * + * @param[in] task The task. + * @param[in] report The report. + * @param[in] scan_id The UUID of the scan on the scanner. + * + * @return 0 if success, -1 if error, -2 if scan was stopped, + * -3 if the scan was interrupted, -4 already stopped. + */ +static int +handle_openvasd_scan (task_t task, report_t report, const char *scan_id) +{ + int rc; + scanner_t scanner; + gboolean started, queued_status_updated; + int retry, connection_retry; + openvasd_resp_t response; + openvasd_connector_t connector; + + scanner = task_scanner (task); + connector = openvasd_scanner_connect (scanner, scan_id); + response = NULL; + started = FALSE; + queued_status_updated = FALSE; + connection_retry = get_scanner_connection_retry (); + + retry = connection_retry; + rc = -1; + while (retry >= 0) + { + int run_status, progress; + + run_status = task_run_status (task); + if (run_status == TASK_STATUS_STOPPED + || run_status == TASK_STATUS_STOP_REQUESTED) + { + rc = -4; + break; + } + + progress = openvasd_get_scan_progress (&connector); + + if (progress < 0 || progress > 100) + { + if (retry > 0 && progress == -1) + { + retry--; + g_warning ("Connection lost with the scanner." + "Trying again in 1 second."); + gvm_sleep (1); + continue; + } + else if (progress == -2) + { + rc = -2; + break; + } + result_t result = make_osp_result + (task, "", "", "", + threat_message_type ("Error"), + "Erroneous scan progress value", "", "", + QOD_DEFAULT, NULL, NULL); + report_add_result (report, result); + response = openvasd_delete_scan(&connector); + rc = -1; + break; + } + else + { + /* Get the full openvasd report. */ + progress = openvasd_get_scan_progress (&connector); + + if (progress < 0 || progress > 100) + { + if (retry > 0 && progress == -1) + { + retry--; + g_warning ("Connection lost with the scanner. " + "Trying again in 1 second."); + gvm_sleep (1); + continue; + } + else if (progress == -2) + { + rc = -2; + break; + } + result_t result = make_osp_result + (task, "", "", "", + threat_message_type ("Error"), + "Erroneous scan progress value", "", "", + QOD_DEFAULT, NULL, NULL); + report_add_result (report, result); + rc = -1; + break; + } + else + { + GSList *results = NULL; + static unsigned long result_start = 0; + static unsigned long result_end = -1; // get up to the end + openvasd_status_t current_status; + time_t start_time, end_time; + openvasd_scan_status_t openvasd_scan_status; + + set_report_slave_progress (report, progress); + + openvasd_parsed_results (&connector, result_start, + result_end, &results); + result_start += g_slist_length (results); + + gvm_sleep(1); + openvasd_scan_status = openvasd_parsed_scan_status (&connector); + start_time = openvasd_scan_status->start_time; + end_time = openvasd_scan_status->end_time; + current_status = openvasd_scan_status->status; + progress = openvasd_scan_status->progress; + g_free (openvasd_scan_status); + + if (g_slist_length(results)) + { + parse_openvasd_report (task, report, results, + start_time, end_time); + } + if (current_status == OPENVASD_SCAN_STATUS_STORED) + { + if (queued_status_updated == FALSE) + { + set_task_run_status (task, TASK_STATUS_QUEUED); + set_report_scan_run_status (global_current_report, + TASK_STATUS_QUEUED); + queued_status_updated = TRUE; + } + } + else if (current_status == OPENVASD_SCAN_STATUS_FAILED) + { + result_t result = make_osp_result + (task, "", "", "", + threat_message_type ("Error"), + "Task interrupted unexpectedly", "", "", + QOD_DEFAULT, NULL, NULL); + report_add_result (report, result); + response = openvasd_delete_scan (&connector); + rc = -3; + break; + } + else if (progress >= 0 && progress < 100 + && current_status == OPENVASD_SCAN_STATUS_STOPPED) + { + if (retry > 0) + { + retry--; + g_warning ("Connection lost with the scanner. " + "Trying again in 1 second."); + gvm_sleep (1); + continue; + } + + result_t result = make_osp_result + (task, "", "", "", + threat_message_type ("Error"), + "Scan stopped unexpectedly by the server", "", "", + QOD_DEFAULT, NULL, NULL); + report_add_result (report, result); + response = openvasd_delete_scan (&connector); + rc = -1; + break; + } + else if (progress == 100 + && current_status == OPENVASD_SCAN_STATUS_SUCCEEDED) + { + response = openvasd_delete_scan (&connector); + rc = response->code; + break; + } + else if (current_status == OPENVASD_SCAN_STATUS_RUNNING + && started == FALSE) + { + set_task_run_status (task, TASK_STATUS_RUNNING); + set_report_scan_run_status (global_current_report, + TASK_STATUS_RUNNING); + started = TRUE; + } + } + } + + retry = connection_retry; + gvm_sleep (5); + } + openvasd_response_free (response); + openvasd_connector_free(&connector); + return rc; +} + + +/** + * @brief Fork a child to handle an Openvasd scan's fetching and inserting. + * + * @param[in] task The task. + * @param[in] target The target. + * @param[in] from 0 start from beginning, 1 continue from stopped, + * 2 continue if stopped else start from beginning. + * @param[out] report_id_return UUID of the report. + * + * @return Parent returns with 0 if success, -1 if failure. Child process + * doesn't return and simply exits. + */ +static int +fork_openvasd_scan_handler (task_t task, target_t target, int from, + char **report_id_return) +{ + char *report_id, *error = NULL; + int rc; + + assert (task); + assert (target); + + if (report_id_return) + *report_id_return = NULL; + + if (run_osp_scan_get_report (task, from, &report_id)) + return -1; + + current_scanner_task = task; + set_task_run_status (task, TASK_STATUS_REQUESTED); + + switch (fork ()) + { + case 0: + init_sentry (); + break; + case -1: + /* Parent, failed to fork. */ + global_current_report = 0; + g_warning ("%s: Failed to fork: %s", + __func__, + strerror (errno)); + set_task_interrupted (task, + "Error forking scan handler." + " Interrupting scan."); + set_report_scan_run_status (global_current_report, + TASK_STATUS_INTERRUPTED); + global_current_report = (report_t) 0; + current_scanner_task = 0; + g_free (report_id); + return -9; + default: + /* Parent, successfully forked. */ + global_current_report = 0; + current_scanner_task = 0; + if (report_id_return) + *report_id_return = report_id; + else + g_free (report_id); + return 0; + } + + /* Child: Re-open DB after fork and periodically check scan progress. + * If progress == 100%: Parse the report results and other info then exit(0). + * Else, exit(1) in error cases like connection to scanner failure. + */ + reinit_manage_process (); + manage_session_init (current_credentials.uuid); + + rc = launch_openvasd_openvas_task (task, target, report_id, from, &error); + + if (rc < 0) + { + result_t result; + + g_warning ("Openvasd start_scan %s: %s", report_id, error); + result = make_osp_result (task, "", "", "", + threat_message_type ("Error"), + error, "", "", QOD_DEFAULT, NULL, NULL); + report_add_result (global_current_report, result); + set_task_run_status (task, TASK_STATUS_DONE); + set_report_scan_run_status (global_current_report, TASK_STATUS_DONE); + set_task_end_time_epoch (task, time (NULL)); + set_scan_end_time_epoch (global_current_report, time (NULL)); + + g_free (error); + g_free (report_id); + gvm_close_sentry (); + exit (-1); + } + + setproctitle ("Openvasd: Handling scan %s", report_id); + + rc = handle_openvasd_scan (task, global_current_report, report_id); + g_free (report_id); + + if (rc >= 0) + { + set_task_run_status (task, TASK_STATUS_PROCESSING); + set_report_scan_run_status (global_current_report, + TASK_STATUS_PROCESSING); + hosts_set_identifiers (global_current_report); + hosts_set_max_severity (global_current_report, NULL, NULL); + hosts_set_details (global_current_report); + set_task_run_status (task, TASK_STATUS_DONE); + set_report_scan_run_status (global_current_report, TASK_STATUS_DONE); + } + else if (rc == -1 || rc == -2) + { + set_task_run_status (task, TASK_STATUS_STOPPED); + set_report_scan_run_status (global_current_report, TASK_STATUS_STOPPED); + } + else if (rc == -3) + { + set_task_run_status (task, TASK_STATUS_INTERRUPTED); + set_report_scan_run_status (global_current_report, + TASK_STATUS_INTERRUPTED); + } + + set_task_end_time_epoch (task, time (NULL)); + set_scan_end_time_epoch (global_current_report, time (NULL)); + global_current_report = 0; + current_scanner_task = (task_t) 0; + gvm_close_sentry (); + exit (rc); +} + + +/** + * @brief Start a task on an Openvasd scanner. + * + * @param[in] task The task. + * @param[in] from 0 start from beginning, 1 continue from stopped, + * 2 continue if stopped else start from beginning. + * @param[out] report_id The report ID. + * + * @return 0 success, 99 permission denied, -1 error. + */ +static int +run_openvasd_task (task_t task, int from, char **report_id) +{ + target_t target; + + target = task_target (task); + if (target) + { + char *uuid; + target_t found; + + uuid = target_uuid (target); + if (find_target_with_permission (uuid, &found, "get_targets")) + { + g_free (uuid); + return -1; + } + g_free (uuid); + if (found == 0) + return 99; + } + + if (fork_openvasd_scan_handler (task, target, from, report_id)) + { + g_warning ("Couldn't fork Openvasd scan handler"); + return -1; + } + return 0; +} diff --git a/src/manage.h b/src/manage.h index df8f144a4..5be9849b1 100644 --- a/src/manage.h +++ b/src/manage.h @@ -39,6 +39,7 @@ #include #include #include +#include #include /** @@ -328,7 +329,8 @@ typedef enum scanner_type SCANNER_TYPE_CVE = 3, /* 4 was removed (SCANNER_TYPE_GMP). */ SCANNER_TYPE_OSP_SENSOR = 5, - SCANNER_TYPE_MAX = 6, + SCANNER_TYPE_OPENVASD = 6, + SCANNER_TYPE_MAX = 7, } scanner_type_t; int @@ -4047,4 +4049,9 @@ get_vt_verification_collation (); void set_vt_verification_collation (const char *); +/* Openvasd*/ +openvasd_connector_t +openvasd_scanner_connect (scanner_t, const char *); + + #endif /* not _GVMD_MANAGE_H */ diff --git a/src/manage_sql.c b/src/manage_sql.c index fc1bf3905..51cddef03 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -24,6 +24,8 @@ /** * @brief Enable extra GNU functions. */ +#include "manage.h" +#include #define _GNU_SOURCE #include "debug_utils.h" @@ -67,6 +69,8 @@ #include #include #include +#include +#include #include #include @@ -82,6 +86,7 @@ #include #include #include +#include #include "manage_report_configs.h" #undef G_LOG_DOMAIN @@ -20074,14 +20079,17 @@ nvt_severity (const char *nvt_id, const char *type) { char *severity = NULL; - if (strcasecmp (type, "Alarm") == 0 && nvt_id) + if ((strcasecmp (type, "alarm") == 0 || strcasecmp (type, "Alarm") == 0) && nvt_id) severity = sql_string ("SELECT coalesce(cvss_base, '0.0')" " FROM nvts WHERE uuid = '%s';", nvt_id); - else if (strcasecmp (type, "Alarm") == 0) + else if (strcasecmp (type, "Alarm") == 0 + || strcasecmp (type, "alarm") == 0) g_warning ("%s result type requires an NVT", type); - else if (strcasecmp (type, "Log Message") == 0) + else if (strcasecmp (type, "Log Message") == 0 + || strcasecmp (type, "log") == 0) severity = g_strdup (G_STRINGIFY (SEVERITY_LOG)); - else if (strcasecmp (type, "Error Message") == 0) + else if (strcasecmp (type, "Error Message") == 0 + || strcasecmp (type, "error") == 0) severity = g_strdup (G_STRINGIFY (SEVERITY_ERROR)); else g_warning ("Invalid result nvt type %s", type); @@ -42279,7 +42287,7 @@ create_scanner (const char* name, const char *comment, const char *host, if (!host || !port || !type) return 2; - if (*host == '/') + if (*host == '/' || *host == 'h') { unix_socket = 1; ca_pub = NULL; @@ -43507,6 +43515,7 @@ osp_scanner_connect (scanner_t scanner) return connection; } + /** * @brief Get an OSP Scanner's get_version info. * @@ -43605,6 +43614,11 @@ verify_scanner (const char *scanner_id, char **version) return 2; return 0; } + else if (scanner_iterator_type (&scanner) == SCANNER_TYPE_OPENVASD) + { + cleanup_iterator (&scanner); + return 0; + } else if (scanner_iterator_type (&scanner) == SCANNER_TYPE_CVE) { if (version) @@ -43662,6 +43676,9 @@ manage_get_scanners (GSList *log_config, const db_conn_info_t *database) case SCANNER_TYPE_OSP_SENSOR: scanner_type_str = "OSP-Sensor"; break; + case SCANNER_TYPE_OPENVASD: + scanner_type_str = "Openvasd"; + break; default: scanner_type_str = NULL; } @@ -60189,3 +60206,356 @@ cleanup_ids_for_table (const char *table) free (sequence_name); return 0; } + + +/** + * @brief Create a new connection to an OSP scanner. + * + * @param[in] scanner Scanner. + * + * @return New connection if success, NULL otherwise. + */ +openvasd_connector_t +openvasd_scanner_connect (scanner_t scanner, const char *scan_id) +{ + int port; + openvasd_connector_t connection; + char *server, *ca_pub, *key_pub, *key_priv; + + assert (scanner); + server = scanner_host (scanner); + port = scanner_port (scanner); + ca_pub = scanner_ca_pub (scanner); + key_pub = scanner_key_pub (scanner); + key_priv = scanner_key_priv (scanner); + + connection = openvasd_connector_new(); + + openvasd_connector_builder (&connection, OPENVASD_SERVER, server); + openvasd_connector_builder (&connection, OPENVASD_CA_CERT, ca_pub); + openvasd_connector_builder (&connection, OPENVASD_KEY, key_priv); + openvasd_connector_builder (&connection, OPENVASD_CERT, key_pub); + openvasd_connector_builder (&connection, OPENVASD_PORT, (void *) &port); + + if (scan_id && scan_id[0] != '\0') + openvasd_connector_builder (&connection, OPENVASD_SCAN_ID, scan_id); + + g_free (server); + g_free (ca_pub); + g_free (key_pub); + g_free (key_priv); + + return connection; +} + +/** + * @brief Generate the hash value for the fields of the result and + * check if openvasd result for report already exists + * + * @param[in] report Report. + * @param[in] task Task. + * @param[in] r_entity entity of the result. + * @param[out] entity_hash_value The generated hash value of r_entity. + * + * @return "1" if openvasd result already exists, else "0" + */ +static int +check_openvasd_result_exists (report_t report, task_t task, + openvasd_result_t res, char **entity_hash_value, + GHashTable *hashed_openvasd_results) +{ + GString *result_string; + int return_value = 0; + char *port_str = NULL; + if (res->port == 0 && res->detail_value && *res->detail_value) + port_str = g_strdup ("general/Host_Details"); + else if (res->port > 0) + { + char buf[6]; + snprintf (buf, sizeof(buf) , "%d", res->port); + port_str = g_strdup (buf); + } + else + port_str = ""; + + result_string = g_string_new (""); + g_string_append_printf (result_string, "host:%s\n" + "hostname:%s\n" + "type:%s\n" + "description:%s\n" + "port:%s",res->ip_address, res->hostname, + res->type, res->message, port_str); + + *entity_hash_value = get_md5_hash_from_string (result_string->str); + if (g_hash_table_contains (hashed_openvasd_results, *entity_hash_value)) + { + return_value = 1; + } + else + { + g_hash_table_insert (hashed_openvasd_results, + g_strdup(*entity_hash_value), + GINT_TO_POINTER(1)); + if (sql_int ("SELECT EXISTS" + " (SELECT * FROM results" + " WHERE report = %llu and hash_value = '%s');", + report, *entity_hash_value)) + { + const char *desc, *type, *severity = NULL, *host; + const char *hostname, *port = NULL, *path = NULL; + gchar *quoted_desc, *quoted_type, *quoted_host; + gchar *quoted_hostname, *quoted_port, *quoted_path; + double severity_double = 0.0; + int qod_int = QOD_DEFAULT; + + host = res->ip_address; + hostname = res->hostname; + type = res->type; + desc = res->message; + qod_int = QOD_DEFAULT; + + if (!severity || !strcmp (severity, "")) + { + if (!strcmp (type, severity_to_type (SEVERITY_ERROR))) + severity_double = SEVERITY_ERROR; + else + { + g_debug ("%s: Result without severity", __func__); + return 0; + } + } + else + { + severity_double = strtod (severity, NULL); + } + + quoted_host = sql_quote (host ?: ""); + quoted_hostname = sql_quote (hostname ?: ""); + quoted_type = sql_quote (type ?: ""); + quoted_desc = sql_quote (desc ?: ""); + quoted_port = sql_quote (port ?: ""); + quoted_path = sql_quote (path ?: ""); + + if (sql_int ("SELECT EXISTS" + " (SELECT * FROM results" + " WHERE report = %llu and hash_value = '%s'" + " and host = '%s' and hostname = '%s'" + " and type = '%s' and description = '%s'" + " and port = '%s' and severity = %1.1f" + " and qod = %d and path = '%s'" + " );", + report, *entity_hash_value, + quoted_host, quoted_hostname, + quoted_type, quoted_desc, + quoted_port, severity_double, + qod_int, quoted_path)) + { + g_info ("Captured duplicate result, report: %llu hash_value: %s", + report, *entity_hash_value); + g_debug ("Entity string: %s", result_string->str); + return_value = 1; + } + + g_free (quoted_host); + g_free (quoted_hostname); + g_free (quoted_type); + g_free (quoted_desc); + g_free (quoted_port); + g_free (quoted_path); + } + } + if (return_value) + { + g_debug ("Captured duplicate result, report: %llu hash_value: %s", + report, *entity_hash_value); + g_debug ("Entity string: %s", result_string->str); + } + g_string_free (result_string, TRUE); + return return_value; +} + +/* Struct to be sent as user data to the GFunc for adding results */ +struct report_aux { + GArray *results_array; + report_t report; + task_t task; + GHashTable *hash_results; + GHashTable *hash_hostdetails; +}; + +static void +add_openvasd_result_to_report (openvasd_result_t res, gpointer *results_aux) +{ + + struct report_aux *rep_aux = *results_aux; + result_t result; + char *type, *name, *severity, *host, *hostname, *test_id; + char *port = NULL, *path = NULL; + char *desc = NULL, *nvt_id = NULL, *severity_str = NULL; + int qod_int; + + type = res->type; + name = NULL; + severity = NULL; + test_id = res->oid; + host = res->ip_address; + hostname = res->hostname; + + if (res->port == 0 && res->detail_value && *res->detail_value) + port = g_strdup ("general/Host_Details"); + else if (res->port > 0) + { + char buf[6]; + snprintf(buf, sizeof(buf) , "%d", res->port); + port = g_strdup (buf); + } + + /* Add report host if it doesn't exist. */ + manage_report_host_add (rep_aux->report, host, 0, 0); + if (!strcmp (type, "host_detail")) + { + gchar *hash_value = NULL; + if (!check_host_detail_exists (rep_aux->report, host, "openvasd", "", + "Openvasd Host Detail", res->detail_name, + res->detail_value, &hash_value, + rep_aux->hash_hostdetails)) + { + + insert_report_host_detail (rep_aux->report, host, "openvasd", "", + "Openvasd Host Detail", res->detail_name, + res->detail_value, hash_value); + } + g_free (hash_value); + g_free (port); + return; + } + else if (g_str_has_prefix (test_id, "1.3.6.1.4.1.25623.1.")) + { + nvt_id = g_strdup (test_id); + severity_str = nvt_severity (test_id, type); + desc = res->message; + } + else + { + nvt_id = g_strdup (name); + desc = res->message; + } + qod_int = QOD_DEFAULT; + if (port && strcmp (port, "general/Host_Details") == 0) + { + /* TODO: This should probably be handled by the "Host Detail" + * result type with extra source info in OSP. + */ + if (manage_report_host_detail (rep_aux->report, host, desc, + rep_aux->hash_hostdetails)) + g_warning ("%s: Failed to add report detail for host '%s': %s", + __func__, host, desc); + } + else if (host && desc && (strcmp (type, "host_start") == 0)) + { + set_scan_host_start_time_ctime (rep_aux->report, host, desc); + } + else if (host && desc && (strcmp (type, "host_end") == 0)) + { + set_scan_host_end_time_ctime (rep_aux->report, host, desc); + add_assets_from_host_in_report (rep_aux->report, host); + } + else + { + char *hash_value; + if (!check_openvasd_result_exists (rep_aux->report, rep_aux->task, res, + &hash_value, rep_aux->hash_results)) + { + result = make_osp_result (rep_aux->task, + host ?: "", + hostname ?: "", + nvt_id ?: "", + type ?: "", + desc ?: "", + port ?: "", + severity_str ?: severity, + qod_int, + path ?: "", + hash_value); + g_array_append_val (rep_aux->results_array, result); + } + g_free (hash_value); + } + + g_free (port); + g_free (nvt_id); + + return; +} + +/** + * @brief Parse Openvasd results. + * + * @param[in] task Task. + * @param[in] report Report. + * @param[in] results Openvasd results. + */ +void +parse_openvasd_report (task_t task, report_t report, GSList *results, + time_t start_time, time_t end_time) +{ + char *defs_file = NULL; + gboolean has_results = FALSE; + GArray *results_array = NULL; + GHashTable *hashed_openvasd_results = NULL; + GHashTable *hashed_host_details = NULL; + struct report_aux *rep_aux; + + assert (task); + assert (report); + + hashed_openvasd_results = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); + + hashed_host_details = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + NULL); + + sql_begin_immediate (); + /* Set the report's start and end times. */ + + if (start_time) + set_scan_start_time_epoch (report, start_time); + + if (end_time) + set_scan_end_time_epoch (report, end_time); + + if (g_slist_length (results)) + has_results = TRUE; + + defs_file = task_definitions_file (task); + + results_array = g_array_new(TRUE, TRUE, sizeof(result_t)); + rep_aux = g_malloc0 (sizeof (struct report_aux)); + rep_aux->report = report; + rep_aux->task = task; + rep_aux->results_array = results_array; + rep_aux->hash_results = hashed_openvasd_results; + rep_aux->hash_hostdetails = hashed_host_details; + + g_slist_foreach(results, (GFunc) add_openvasd_result_to_report, &rep_aux); + + if (has_results) + { + sql ("UPDATE reports SET modification_time = m_now() WHERE id = %llu;", + report); + report_add_results_array (report, results_array); + } + + sql_commit (); + if (results_array && has_results) + g_array_free (results_array, TRUE); + + g_hash_table_destroy (hashed_openvasd_results); + g_hash_table_destroy (hashed_host_details); + g_free (defs_file); + g_free (rep_aux); +} diff --git a/src/manage_sql.h b/src/manage_sql.h index b9db9cb99..ab23ce4be 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -25,6 +25,7 @@ #define _GVMD_MANAGE_SQL_H #include +#include #include "manage.h" #include "manage_utils.h" @@ -542,4 +543,6 @@ cleanup_nvt_sequences (); int cleanup_ids_for_table (const char *); +void +parse_openvasd_report (task_t, report_t, GSList *, time_t, time_t); #endif /* not _GVMD_MANAGE_SQL_H */ diff --git a/src/manage_sql_configs.c b/src/manage_sql_configs.c index 28e2bb10e..034bb3f31 100644 --- a/src/manage_sql_configs.c +++ b/src/manage_sql_configs.c @@ -2762,6 +2762,8 @@ create_task_check_scanner_type (scanner_t scanner) return 1; if (stype == SCANNER_TYPE_OSP_SENSOR) return 1; + if (stype == SCANNER_TYPE_OPENVASD) + return 1; return 0; } @@ -2831,6 +2833,9 @@ modify_task_check_config_scanner (task_t task, const char *config_id, if (stype == SCANNER_TYPE_OSP_SENSOR) return 0; + if (stype == SCANNER_TYPE_OPENVASD) + return 0; + /* Default Scanner with OpenVAS Config. */ if (scanner == 0) return 0; From 9e6e7fc80cf420879fc8d6e84e30d59f3537a407 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 17 Jul 2024 09:10:45 -0300 Subject: [PATCH 02/13] fix stop scan --- src/manage.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/manage.c b/src/manage.c index 79ca62f88..e363efcce 100644 --- a/src/manage.c +++ b/src/manage.c @@ -8229,7 +8229,7 @@ delete_resource (const char *type, const char *resource_id, int ultimate) static int stop_openvasd_task (task_t task) { - int ret = -1; + int ret = 0; report_t scan_report; char *scan_id; task_t previous_task; @@ -8241,15 +8241,20 @@ stop_openvasd_task (task_t task) previous_task = current_scanner_task; previous_report = global_current_report; - scan_report = task_running_report (task); scan_id = report_uuid (scan_report); if (!scan_id) - goto end_stop_openvasd; + { + ret = -1; + goto end_stop_openvasd; + } scanner = task_scanner (task); connector = openvasd_scanner_connect (scanner, scan_id); if (!connector) - goto end_stop_openvasd; + { + ret = -1; + goto end_stop_openvasd; + } current_scanner_task = task; global_current_report = task_running_report (task); @@ -8257,13 +8262,12 @@ stop_openvasd_task (task_t task) response = openvasd_stop_scan (&connector); if (response->code < 0) { + ret = -1; g_free (scan_id); goto end_stop_openvasd; } - response = openvasd_delete_scan (&connector); g_free (scan_id); - end_stop_openvasd: openvasd_connector_free(&connector); set_task_end_time_epoch (task, time (NULL)); @@ -8275,9 +8279,8 @@ stop_openvasd_task (task_t task) } current_scanner_task = previous_task; global_current_report = previous_report; - if (ret) - return -1; - return 0; + + return ret; } /** From f38d97066083aaf88419dd94e0c7fdc1dd83e877 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 17 Jul 2024 11:26:44 -0300 Subject: [PATCH 03/13] Handle resume task --- src/manage.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/manage.c b/src/manage.c index e363efcce..710d0352a 100644 --- a/src/manage.c +++ b/src/manage.c @@ -8283,6 +8283,126 @@ stop_openvasd_task (task_t task) return ret; } +/** + * @brief Prepare a report for resuming an OSP scan + * + * @param[in] task The task of the scan. + * @param[in] scan_id The scan uuid. + * @param[out] error Error return. + * + * @return 0 scan finished or still running, + * 1 scan must be started, + * -1 error + */ +static int +prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, + char **error) +{ + openvasd_connector_t connection; + + openvasd_scan_status_t status; + openvasd_resp_t response; + + assert (task); + assert (scan_id); + assert (global_current_report); + assert (error); + + connection = openvasd_scanner_connect (task_scanner (task), scan_id); + if (!connection) + { + *error = g_strdup ("Could not connect to Openvasd Scanner"); + return -1; + } + status = openvasd_parsed_scan_status (&connection); + + if (status->status == OPENVASD_SCAN_STATUS_ERROR) + { + if (status->response_code == 404) + { + g_debug ("%s: Scan %s not found", __func__, scan_id); + openvasd_connector_free (&connection); + trim_partial_report (global_current_report); + return 1; + } + g_warning ("%s: Error getting status of scan %s: %ld", + __func__, scan_id, status->response_code); + openvasd_connector_free (&connection); + return -1; + } + else if (status->status == OPENVASD_SCAN_STATUS_RUNNING + || status->status == OPENVASD_SCAN_STATUS_REQUESTED) + { + g_debug ("%s: Scan %s queued or running", __func__, scan_id); + /* It would be possible to simply continue getting the results + * from the scanner, but gvmd may have crashed while receiving + * or storing the results, so some may be missing. */ + response = openvasd_stop_scan (&connection); + if (response->code != 204) + { + *error = g_strdup_printf ("Failed to stop old report: %ld", + response->code); + openvasd_connector_free (&connection); + openvasd_response_free(response); + return -1; + } + response = openvasd_delete_scan (&connection); + if (response->code != 204) + { + *error = g_strdup_printf ("Failed to delete old report: %ld", + response->code); + openvasd_response_free(response); + openvasd_connector_free (&connection); + return -1; + } + openvasd_connector_free (&connection); + trim_partial_report (global_current_report); + return 1; + } + else if (status->status == OPENVASD_SCAN_STATUS_SUCCEEDED) + { + /* OSP can't stop an already finished/interrupted scan, + * but it must be delete to be resumed. */ + g_debug ("%s: Scan %s finished", __func__, scan_id); + response = openvasd_delete_scan (&connection); + if (response->code != 204) + { + *error = g_strdup_printf ("Failed to delete old report: %ld", + response->code); + openvasd_response_free(response); + openvasd_connector_free (&connection); + return -1; + } + openvasd_connector_free (&connection); + trim_partial_report (global_current_report); + return 1; + } + else if (status->status == OPENVASD_SCAN_STATUS_STOPPED + || status->status == OPENVASD_SCAN_STATUS_FAILED) + { + g_debug ("%s: Scan %s stopped or interrupted", + __func__, scan_id); + response = openvasd_delete_scan (&connection); + if (response->code != 204) + { + *error = g_strdup_printf ("Failed to delete old report: %ld", + response->code); + openvasd_response_free(response); + openvasd_connector_free (&connection); + return -1; + } + openvasd_connector_free (&connection); + trim_partial_report (global_current_report); + return 1; + } + + g_warning ("%s: Unexpected scanner status %d", __func__, status->status); + *error = g_strdup_printf ("Unexpected scanner status %d", status->status); + openvasd_connector_free (&connection); + + return -1; +} + /** * @brief Launch an OpenVAS via Openvasd task. * @@ -8326,7 +8446,7 @@ launch_openvasd_openvas_task (task_t task, target_t target, const char *scan_id, /* Prepare the report */ if (from) { - ret = prepare_osp_scan_for_resume (task, scan_id, error); + ret = prepare_openvasd_scan_for_resume (task, scan_id, error); if (ret == 0) return 0; else if (ret == -1) From 53a73c7ca2b59e9b549d6e1e7f153951a261ebe9 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 29 Jul 2024 14:00:38 -0300 Subject: [PATCH 04/13] handle feed update --- src/gvmd.c | 6 +- src/manage.c | 70 ++++++++ src/manage_sql.h | 5 + src/manage_sql_nvts.c | 383 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 461 insertions(+), 3 deletions(-) diff --git a/src/gvmd.c b/src/gvmd.c index 737a0f568..c58ec12c7 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -1106,11 +1106,15 @@ handle_sigabrt_simple (int signal) static int update_nvt_cache_osp (const gchar *update_socket) { +#ifdef OPENVASD + setproctitle ("Openvasd: Updating NVT cache"); +#else setproctitle ("OSP: Updating NVT cache"); - +#endif return manage_update_nvts_osp (update_socket); } + /** * @brief Update NVT cache in forked child, retrying if scanner loading. * diff --git a/src/manage.c b/src/manage.c index 710d0352a..3aabb86bd 100644 --- a/src/manage.c +++ b/src/manage.c @@ -7434,6 +7434,50 @@ nvts_feed_info_internal (const gchar *update_socket, return 0; } +/** + * @brief Get VTs feed information from a scanner. + * + * @param[in] scanner_uuid The uuid of the scanner to be used. + * @param[out] vts_version Output of scanner feed version. + * + * @return 0 success, 1 connection to scanner failed, 2 scanner still starting, + * -1 other error. + */ +static int +nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, + gchar **vts_version) +{ + scanner_t scan; + openvasd_connector_t connector = NULL; + openvasd_resp_t resp = NULL; + int ret; + if (find_resource_no_acl ("scanner", scanner_uuid, &scan)) + return -1; + + connector = openvasd_scanner_connect (scan, NULL); + if (!connector) + return 1; + + resp = openvasd_get_health_ready (&connector); + if (resp->code == -1) + { + g_warning ("%s: failed to connect to %s:%d", __func__, + scanner_host (scan), scanner_port (scan)); + ret = 1; + } + else if (resp->code == 503) + ret = 2; + else + { + *vts_version = g_strdup (resp->header); + ret = 0; + } + + openvasd_response_free (resp); + openvasd_connector_free (&connector); + return ret; +} + /** * @brief Get VTs feed information from the scanner using VT update socket. * @@ -7449,11 +7493,17 @@ int nvts_feed_info (gchar **vts_version, gchar **feed_name, gchar **feed_vendor, gchar **feed_home) { +#if OPENVASD == 1 + return nvts_feed_info_internal_from_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, + vts_version); +#else return nvts_feed_info_internal (get_osp_vt_update_socket (), vts_version, feed_name, feed_vendor, feed_home); + +#endif } /** @@ -7513,10 +7563,30 @@ nvts_check_feed (int *lockfile_in_use, int *self_test_exit_error, char **self_test_error_msg) { +#if OPENVASD == 1 + int ret = 0; + char *vts_version = NULL; + + ret = nvts_feed_info_internal_from_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, + &vts_version); + self_test_exit_error = 0; + *self_test_error_msg = NULL; + if (ret == 0 && vts_version) + lockfile_in_use = 0; + else if (ret == 2) + { + ret = 0; + *lockfile_in_use = 1; + } + + return ret; + +#else return nvts_check_feed_internal (get_osp_vt_update_socket (), lockfile_in_use, self_test_exit_error, self_test_error_msg); +#endif } /** diff --git a/src/manage_sql.h b/src/manage_sql.h index ab23ce4be..7153bf158 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -98,6 +98,11 @@ */ #define SCANNER_UUID_DEFAULT "08b69003-5fc2-4037-a479-93b440211c73" +/** + * @brief UUID of 'Openvasd Default' scanner. + */ +#define SCANNER_UUID_OPENVASD_DEFAULT "8154d8e3-30ee-4959-9151-1863c89a8e62" + /** * @brief UUID of 'CVE' scanner. */ diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 04e9cf3c8..f367cb6b1 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -26,6 +26,10 @@ /** * @brief Enable extra GNU functions. */ +#include "base/nvti.h" +#include "manage.h" +#include "openvasd/openvasd.h" +#include "openvasd/jsonutils.h" #define _GNU_SOURCE #include @@ -1594,6 +1598,91 @@ update_preferences_from_vt (element_t vt, const gchar *oid, GList **preferences) return 0; } +/** + * @brief Update NVT from an NVTI structure + * + * @param[in] vt OSP GET_VTS VT element. + * @param[in] oid OID of NVT. + * @param[in] preferences All NVT preferences. + * + * @return 0 success, -1 error. + */ +static int +update_preferences_from_json_nvt (nvti_t *nvti, GList **preferences) +{ + assert (preferences); + + int prefs_count = nvti_pref_len(nvti); + for (int j = 0; j < prefs_count; j++) + { + int id; + char *char_id, *type, *name, *def; + const nvtpref_t *pref = NULL; + + pref = nvti_pref (nvti, j); + + id = nvtpref_id (pref); + char_id = g_strdup_printf ("%d", id); + type = nvtpref_type (pref); + name = nvtpref_name (pref); + def = nvtpref_default (pref); + + if (type == NULL) + { + GString *debug = g_string_new (""); + g_warning ("%s: PARAM missing type attribute for OID: %s", + __func__, nvti_oid(nvti)); + g_string_free (debug, TRUE); + } + else if (id < 0) + { + GString *debug = g_string_new (""); + g_warning ("%s: PARAM missing id attribute for OID: %s", + __func__, nvti_oid(nvti)); + g_string_free (debug, TRUE); + } + else if (name == NULL) + { + GString *debug = g_string_new (""); + g_warning ("%s: PARAM missing NAME for OID: %s", + __func__, nvti_oid (nvti)); + g_string_free (debug, TRUE); + } + else + { + gchar *full_name; + preference_t *preference; + + full_name = g_strdup_printf ("%s:%d:%s:%s", + nvti_oid (nvti), + id, + type, + name); + + blank_control_chars (full_name); + preference = g_malloc0 (sizeof (preference_t)); + preference->free_strings = 1; + preference->name = full_name; + if (def) + preference->value = g_strdup (def); + else + preference->value = g_strdup (""); + preference->nvt_oid = g_strdup (nvti_oid(nvti)); + preference->id = g_strdup (char_id); + preference->type = g_strdup (type); + preference->pref_name = name; + *preferences = g_list_prepend (*preferences, preference); + } + + g_free (type); + g_free (name); + g_free (char_id); + g_free (def); + } + + return 0; +} + /** * @brief Create NVTI structure from VT XML. * @@ -2053,6 +2142,132 @@ update_nvts_from_vts (element_t *get_vts_response, return 0; } +/** + * @brief Update NVTs from Json response + * + * @param[in] get_vts_response Openvasd VTS response. + * @param[in] scanner_feed_version Version of feed from scanner. + * @param[in] rebuild Whether we're rebuilding the tables. + * + * @return 0 success, 1 VT integrity check failed, -1 error + */ +static int +update_nvts_from_json_vts (jreader_t *get_vts_response, + const gchar *scanner_feed_version, + int rebuild) +{ + GList *preferences; + int count_modified_vts, count_new_vts; + time_t feed_version_epoch; + batch_t *vt_refs_batch, *vt_sevs_batch; + + count_modified_vts = 0; + count_new_vts = 0; + + feed_version_epoch = nvts_feed_version_epoch(); + + //osp_vt_hash = element_attribute (vts, "sha256_hash"); + + sql_begin_immediate (); + + if (rebuild) { + sql ("DROP TABLE IF EXISTS vt_refs_rebuild;"); + sql ("DROP TABLE IF EXISTS vt_severities_rebuild;"); + sql ("DROP TABLE IF EXISTS nvt_preferences_rebuild;"); + sql ("DROP TABLE IF EXISTS nvts_rebuild;"); + + create_tables_nvt ("_rebuild"); + } + else if (sql_int ("SELECT coalesce ((SELECT CAST (value AS INTEGER)" + " FROM meta" + " WHERE name = 'checked_preferences')," + " 0);") + == 0) + /* We're in the first NVT sync after migrating preference names. + * + * If a preference was removed from an NVT then the preference will be in + * nvt_preferences in the old format, but we will not get a new version + * of the preference name from the sync. For example "Alle Dateien + * Auflisten" was removed from 1.3.6.1.4.1.25623.1.0.94023. + * + * If a preference was not in the migrator then the new version of the + * preference would be inserted alongside the old version, resulting in a + * duplicate when the name of the old version was corrected. + * + * To solve both cases, we remove all nvt_preferences. */ + sql ("TRUNCATE nvt_preferences;"); + + vt_refs_batch = batch_start (vt_ref_insert_size); + vt_sevs_batch = batch_start (vt_sev_insert_size); + + nvti_t *nvti = gvm_jnode_parse_vt (*get_vts_response); + while (nvti) + { + if (nvti == NULL) + continue; + + if (nvti_creation_time (nvti) > feed_version_epoch) + count_new_vts += 1; + else + count_modified_vts += 1; + + insert_nvt (nvti, rebuild, vt_refs_batch, vt_sevs_batch); + + preferences = NULL; + if (update_preferences_from_json_nvt (nvti, &preferences)) + { + sql_rollback (); + return -1; + } + if (rebuild == 0) + sql ("DELETE FROM nvt_preferences%s WHERE name LIKE '%s:%%';", + rebuild ? "_rebuild" : "", + nvti_oid (nvti)); + insert_nvt_preferences_list (preferences, rebuild); + g_list_free_full (preferences, (GDestroyNotify) preference_free); + + nvti_free (nvti); + nvti = gvm_jnode_parse_vt (*get_vts_response); + } + + batch_end (vt_refs_batch); + batch_end (vt_sevs_batch); + + if (rebuild) { + sql ("DROP VIEW IF EXISTS results_autofp;"); + sql ("DROP VIEW vulns;"); + sql ("DROP TABLE nvts, nvt_preferences, vt_refs, vt_severities;"); + + sql ("ALTER TABLE vt_refs_rebuild RENAME TO vt_refs;"); + sql ("ALTER TABLE vt_severities_rebuild RENAME TO vt_severities;"); + sql ("ALTER TABLE nvt_preferences_rebuild RENAME TO nvt_preferences;"); + sql ("ALTER TABLE nvts_rebuild RENAME TO nvts;"); + + create_view_vulns (); + create_view_result_vt_epss (); + } + + set_nvts_check_time (count_new_vts, count_modified_vts); + + set_nvts_feed_version (scanner_feed_version); + + if (check_config_families ()) + g_warning ("%s: Error updating config families." + " One or more configs refer to an outdated family of an NVT.", + __func__); + update_all_config_caches (); + + g_info ("Updating VTs in database ... %i new VTs, %i changed VTs", + count_new_vts, count_modified_vts); + + sql_commit (); + + g_warning ("%s: No SHA-256 hash received from scanner, skipping check.", + __func__); + + return 0; +} + /** * @brief Check that preference names are in the new format. * @@ -2229,6 +2444,7 @@ nvt_severity_iterator_score (iterator_t *iterator) */ DEF_ACCESS (nvt_severity_iterator_value, 4); + /** * @brief Update VTs via OSP. * @@ -2397,6 +2613,157 @@ update_nvt_cache_osp (const gchar *update_socket, gchar *db_feed_version, return 0; } +/** + * @brief Update VTs via Openvasd. + * + * @param[in] openvasd_uuid UUID of Openvasd to connect to. + * @param[in] db_feed_version Feed version from meta table. + * @param[in] scanner_feed_version Feed version from scanner. + * @param[in] rebuild Whether to rebuild the NVT tables from scratch. + * + * @return 0 success, 1 VT integrity check failed, -1 error. + */ +static int +update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, + gchar *scanner_feed_version, int rebuild) +{ + openvasd_connector_t connector = NULL; + openvasd_resp_t resp; + scanner_t scan; + + time_t old_nvts_last_modified; + int ret; + + if (rebuild + || db_feed_version == NULL + || strcmp (db_feed_version, "") == 0 + || strcmp (db_feed_version, "0") == 0) + old_nvts_last_modified = 0; + else + old_nvts_last_modified + = (time_t) sql_int64_0 ("SELECT max(modification_time) FROM nvts"); + + + /* Update NVTs. */ + if (find_resource_no_acl ("scanner", SCANNER_UUID_OPENVASD_DEFAULT, &scan)) + return -1; + + connector = openvasd_scanner_connect (scan, NULL); + if (!connector) + { + g_warning ("%s: failed to connect to scanner (%s)", __func__, + openvasd_uuid); + return -1; + } + + resp = openvasd_get_vts (&connector); + if (resp->code != 200) + { + g_warning ("%s: failed to get VTs", __func__); + return -1; + } + + jparser_t parser; + jreader_t reader; + + parser = gvm_parse_jnode (); + gvm_read_jnode (resp->body, parser, &reader); + + ret = update_nvts_from_json_vts (&reader, scanner_feed_version, rebuild); + gvm_close_jnode_reader (reader); + gvm_close_jnode_parser (parser); + + openvasd_response_free (resp); + openvasd_connector_free (&connector); + + if (ret) + return ret; + + /* Update scanner preferences */ + // TODO: update scanner preferences + + /* Update the cache of report counts. */ + + reports_clear_count_cache_dynamic (); + + /* Tell the main process to update its NVTi cache. */ + sql ("UPDATE %s.meta SET value = 1 WHERE name = 'update_nvti_cache';", + sql_schema ()); + + g_info ("Updating VTs in database ... done (%i VTs).", + sql_int ("SELECT count (*) FROM nvts;")); + + if (sql_int ("SELECT coalesce ((SELECT CAST (value AS INTEGER)" + " FROM meta" + " WHERE name = 'checked_preferences')," + " 0);") + == 0) + { + check_old_preference_names ("config_preferences"); + check_old_preference_names ("config_preferences_trash"); + + /* Force update of names in new format in case hard-coded names + * used by migrators are outdated */ + old_nvts_last_modified = 0; + + sql ("INSERT INTO meta (name, value)" + " VALUES ('checked_preferences', 1)" + " ON CONFLICT (name) DO UPDATE SET value = EXCLUDED.value;"); + } + + check_preference_names (0, old_nvts_last_modified); + check_preference_names (1, old_nvts_last_modified); + + check_whole_only_in_configs (); + + return 0; +} + +/** + * @brief Get VTs feed information from a scanner. + * + * @param[in] scanner_uuid The uuid of the scanner to be used. + * @param[out] vts_version Output of scanner feed version. + * + * @return 0 success, 1 connection to scanner failed, 2 scanner still starting, + * -1 other error. + */ +static int +nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, + gchar **vts_version) +{ + scanner_t scan; + openvasd_connector_t connector = NULL; + openvasd_resp_t resp = NULL; + int ret; + if (find_resource_no_acl ("scanner", scanner_uuid, &scan)) + return -1; + + connector = openvasd_scanner_connect (scan, NULL); + if (!connector) + return 1; + + resp = openvasd_get_health_ready (&connector); + if (resp->code == -1) + { + g_warning ("%s: failed to connect to %s:%d", __func__, + scanner_host (scan), scanner_port (scan)); + ret = 1; + } + else if (resp->code == 503) + ret = 2; + else + { + *vts_version = g_strdup (resp->header); + ret = 0; + } + + openvasd_response_free (resp); + openvasd_connector_free (&connector); + return ret; +} + + /** * @brief Get the VTs feed version from an OSP scanner. * @@ -2453,7 +2820,8 @@ nvts_feed_version_status_internal (const gchar *update_socket, gchar **db_feed_version_out, gchar **scanner_feed_version_out) { - gchar *db_feed_version, *scanner_feed_version; + gchar *db_feed_version = NULL; + gchar *scanner_feed_version = NULL; if (db_feed_version_out) *db_feed_version_out = NULL; @@ -2465,12 +2833,19 @@ nvts_feed_version_status_internal (const gchar *update_socket, if (db_feed_version_out && db_feed_version) *db_feed_version_out = g_strdup (db_feed_version); +#if OPENVASD == 1 + nvts_feed_info_internal_from_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, + &scanner_feed_version); +#else scanner_feed_version = osp_scanner_feed_version (update_socket); +#endif + g_debug ("%s: scanner_feed_version: %s", __func__, scanner_feed_version); if (scanner_feed_version == NULL) { g_free (db_feed_version); return -1; } + if (scanner_feed_version_out && scanner_feed_version) *scanner_feed_version_out = g_strdup (scanner_feed_version); @@ -2532,9 +2907,13 @@ manage_update_nvt_cache_osp (const gchar *update_socket) scanner_feed_version, db_feed_version, sql_int ("SELECT count (*) FROM nvts;")); +#if OPENVASD == 1 + ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, db_feed_version, + scanner_feed_version, 0); +#else ret = update_nvt_cache_osp (update_socket, db_feed_version, scanner_feed_version, 0); - +#endif g_free (db_feed_version); g_free (scanner_feed_version); return ret; From 1c8467e1b020b584a4ad27c3e9ae5d542770f1c1 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 31 Jul 2024 09:13:32 -0300 Subject: [PATCH 05/13] Add: get scanner preferences --- src/manage_sql_nvts.c | 59 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index f367cb6b1..ccfa09835 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2674,14 +2674,69 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, gvm_close_jnode_parser (parser); openvasd_response_free (resp); - openvasd_connector_free (&connector); if (ret) - return ret; + { + openvasd_connector_free (&connector); + return ret; + } /* Update scanner preferences */ // TODO: update scanner preferences + resp = openvasd_get_vts (&connector); + if (resp->code != 200) + { + g_warning ("%s: failed to get scanner preferences", __func__); + return -1; + } + GSList *scan_prefs = NULL; + + openvasd_parsed_scans_preferences (&connector, &scan_prefs); + g_debug ("There %d scan preferences", g_slist_length (scan_prefs)); + openvasd_connector_free (&connector); + + GString *prefs_sql; + GSList *point; + int first; + + point = scan_prefs; + first = 1; + + prefs_sql = g_string_new ("INSERT INTO nvt_preferences (name, value)" + " VALUES"); + while (point) + { + openvasd_param_t *param; + gchar *quoted_name, *quoted_value; + + param = point->data; + quoted_name = sql_quote (openvasd_param_id (param)); + quoted_value = sql_quote (openvasd_param_default (param)); + + g_string_append_printf (prefs_sql, + "%s ('%s', '%s')", + first ? "" : ",", + quoted_name, + quoted_value); + first = 0; + point = g_slist_next (point); + g_free (quoted_name); + g_free (quoted_value); + } + g_slist_free_full (scan_prefs, (GDestroyNotify) openvasd_param_free); + + g_string_append (prefs_sql, + " ON CONFLICT (name)" + " DO UPDATE SET value = EXCLUDED.value;"); + + if (first == 0) + { + sql ("%s", prefs_sql->str); + } + + g_string_free (prefs_sql, TRUE); + /* Update the cache of report counts. */ reports_clear_count_cache_dynamic (); From 0dbd036db0af9f77a1d34a6ca67f9aecf69cc19e Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 31 Jul 2024 12:01:21 -0300 Subject: [PATCH 06/13] fix add host detail to report --- src/manage_sql.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 51cddef03..a55b44c0e 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -60401,7 +60401,8 @@ add_openvasd_result_to_report (openvasd_result_t res, gpointer *results_aux) host = res->ip_address; hostname = res->hostname; - if (res->port == 0 && res->detail_value && *res->detail_value) + if (res && res->port == 0 && !strcmp (type, "host_detail") && + res->detail_value && *res->detail_value) port = g_strdup ("general/Host_Details"); else if (res->port > 0) { @@ -60425,6 +60426,7 @@ add_openvasd_result_to_report (openvasd_result_t res, gpointer *results_aux) "Openvasd Host Detail", res->detail_name, res->detail_value, hash_value); } + desc = res->message; g_free (hash_value); g_free (port); return; From 44e364a82c4b89d2e1cc69cb9db7652b00a5540e Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 5 Aug 2024 11:51:36 -0300 Subject: [PATCH 07/13] Add: handle --rebuid option --- src/gmp.c | 55 +++++++++++++++++++++++++++++++++++++++++++ src/manage_sql.c | 42 +++++++++++++++++++++++++++++++++ src/manage_sql.h | 2 ++ src/manage_sql_nvts.c | 40 ++++++++++++++++++++++++------- 4 files changed, 130 insertions(+), 9 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index b90c1ff54..42225940c 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -16816,6 +16816,61 @@ handle_get_scanners (gmp_parser_t *gmp_parser, GError **error) g_free (desc); g_slist_free (params); } + if ((scanner_iterator_type (&scanners) == SCANNER_TYPE_OPENVASD) + && get_scanners_data->get.details) + { + char *s_name = NULL, *s_ver = NULL; + char *d_name = NULL, *d_ver = NULL; + char *p_name = NULL, *p_ver = NULL, *desc = NULL; + GSList *params = NULL, *nodes; + + if (!openvasd_get_details_from_iterator (&scanners, &desc, ¶ms)) + { + SENDF_TO_CLIENT_OR_FAIL + ("Openvasd0.1" + "OpenVAS23.4.1" + "SCANNER API0.1" + "Openvasd Sensor"); + + SENDF_TO_CLIENT_OR_FAIL (""); + nodes = params; + while (nodes) + { + openvasd_param_t *param = nodes->data; + g_warning("%s%s" + "%s%s" + "osp_%s%d", + openvasd_param_id (param), openvasd_param_name(param), + openvasd_param_default (param), openvasd_param_desc (param), + openvasd_param_type (param), openvasd_param_mandatory (param)); + SENDF_TO_CLIENT_OR_FAIL + ("%s%s" + "%s%s" + "osp_%s%d", + openvasd_param_id (param), openvasd_param_name(param), + openvasd_param_default (param), openvasd_param_desc (param), + openvasd_param_type (param), 1); + + osp_param_free (nodes->data); + nodes = nodes->next; + } + SENDF_TO_CLIENT_OR_FAIL (""); + } + else + SENDF_TO_CLIENT_OR_FAIL + ("" + "" + "" + ""); + g_free (s_name); + g_free (s_ver); + g_free (d_name); + g_free (d_ver); + g_free (p_name); + g_free (p_ver); + g_free (desc); + g_slist_free (params); + } else if (get_scanners_data->get.details) { SENDF_TO_CLIENT_OR_FAIL diff --git a/src/manage_sql.c b/src/manage_sql.c index a55b44c0e..411042fef 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -43579,6 +43579,48 @@ osp_get_details_from_iterator (iterator_t *iterator, char **desc, return 0; } +/** + * @brief Get an Openvasd Scanner's get_scanner_preferences info. + * + * @param[in] iterator Scanner object iterator. + * @param[out] desc Scanner description. + * @param[out] params Scanner parameters. + * + * @return 0 success, 1 for failure. + */ +int +openvasd_get_details_from_iterator (iterator_t *iterator, char **desc, + GSList **params) +{ + int port; + openvasd_connector_t connection; + const char *server, *ca_pub, *key_pub, *key_priv; + + assert (iterator); + server = scanner_iterator_host (iterator); + port = scanner_iterator_port (iterator); + ca_pub = scanner_iterator_ca_pub (iterator); + key_pub = scanner_iterator_key_pub (iterator); + key_priv = scanner_iterator_key_priv (iterator); + + connection = openvasd_connector_new(); + + openvasd_connector_builder (&connection, OPENVASD_SERVER, server); + openvasd_connector_builder (&connection, OPENVASD_CA_CERT, ca_pub); + openvasd_connector_builder (&connection, OPENVASD_KEY, key_priv); + openvasd_connector_builder (&connection, OPENVASD_CERT, key_pub); + openvasd_connector_builder (&connection, OPENVASD_PORT, (void *) &port); + + if (!connection) + return 1; + + *desc = g_strdup_printf("Openvasd Sensor on htt://%s:%d", server, port); + if (openvasd_parsed_scans_preferences (&connection, params) < 0) + return 1; + openvasd_connector_free (&connection); + return 0; +} + /** * @brief Verify a scanner. * diff --git a/src/manage_sql.h b/src/manage_sql.h index 7153bf158..f867c75d3 100644 --- a/src/manage_sql.h +++ b/src/manage_sql.h @@ -448,6 +448,8 @@ init_get_iterator (iterator_t*, const char *, const get_data_t *, column_t *, column_t *, const char **, int, const char *, const char *, int); +int openvasd_get_details_from_iterator (iterator_t *, char **, GSList **); + gchar * columns_build_select (column_t *); diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index ccfa09835..934e21a6b 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -27,6 +27,7 @@ * @brief Enable extra GNU functions. */ #include "base/nvti.h" +#include "glibconfig.h" #include "manage.h" #include "openvasd/openvasd.h" #include "openvasd/jsonutils.h" @@ -1456,6 +1457,7 @@ insert_nvt_preference (gpointer nvt_preference, gpointer rebuild) return; preference = (preference_t*) nvt_preference; + manage_nvt_preference_add (preference->name, preference->value, preference->nvt_oid, preference->id, preference->type, preference->pref_name, @@ -1623,9 +1625,9 @@ update_preferences_from_json_nvt (nvti_t *nvti, GList **preferences) id = nvtpref_id (pref); char_id = g_strdup_printf ("%d", id); - type = nvtpref_type (pref); - name = nvtpref_name (pref); - def = nvtpref_default (pref); + type = g_strdup (nvtpref_type (pref)); + name = g_strdup (nvtpref_name (pref)); + def = g_strdup (nvtpref_default (pref)); if (type == NULL) { @@ -1667,16 +1669,16 @@ update_preferences_from_json_nvt (nvti_t *nvti, GList **preferences) preference->value = g_strdup (def); else preference->value = g_strdup (""); - preference->nvt_oid = g_strdup (nvti_oid(nvti)); + preference->nvt_oid = g_strdup (nvti_oid (nvti)); preference->id = g_strdup (char_id); preference->type = g_strdup (type); - preference->pref_name = name; + preference->pref_name = g_strdup (name); *preferences = g_list_prepend (*preferences, preference); } - g_free (type); - g_free (name); g_free (char_id); + g_free (name); + g_free (type); g_free (def); } @@ -1707,6 +1709,7 @@ nvti_from_vt (element_t vt) nvti_free (nvti); return NULL; } + nvti_set_oid (nvti, id); g_free (id); @@ -3005,8 +3008,27 @@ manage_sync_nvts (int (*fork_update_nvt_cache) (pid_t*)) int update_or_rebuild_nvts (int update) { +gchar *db_feed_version, *scanner_feed_version; +#if OPENVASD + int ret = 0; + const char *update_socket = NULL; + nvts_feed_version_status_internal (update_socket, + &db_feed_version, + &scanner_feed_version); + + g_debug ("%s: db_feed_version: %s", __func__, db_feed_version); + + if (update == 0) + set_nvts_feed_version ("0"); + ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, db_feed_version, + scanner_feed_version, 0); + if (ret != 0) + ret = -1; + + return ret; + +#else const char *osp_update_socket; - gchar *db_feed_version, *scanner_feed_version; osp_connection_t *connection; int ret; gchar *error; @@ -3055,7 +3077,7 @@ update_or_rebuild_nvts (int update) { return -1; } - +#endif return 0; } From 6945b0c81cada18117042afe378db19a52f6e9df Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 26 Sep 2024 10:38:51 -0300 Subject: [PATCH 08/13] Use json pull lib instead --- src/CMakeLists.txt | 1 + src/manage_sql.c | 1 - src/manage_sql_nvts.c | 40 +++++++++++++++++++++++----------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cd3da580..79884d46e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ pkg_check_modules (LIBGVM_BASE REQUIRED libgvm_base>=22.12) pkg_check_modules (LIBGVM_UTIL REQUIRED libgvm_util>=22.12) pkg_check_modules (LIBGVM_OSP REQUIRED libgvm_osp>=22.12) pkg_check_modules (LIBGVM_GMP REQUIRED libgvm_gmp>=22.12) +pkg_check_modules (LIBGVM_OPENVASD REQUIRED libgvm_openvasd>=22.12) pkg_check_modules (GNUTLS REQUIRED gnutls>=3.2.15) pkg_check_modules (GLIB REQUIRED glib-2.0>=2.42) pkg_check_modules (LIBBSD REQUIRED libbsd) diff --git a/src/manage_sql.c b/src/manage_sql.c index 411042fef..6b31bad40 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -60463,7 +60463,6 @@ add_openvasd_result_to_report (openvasd_result_t res, gpointer *results_aux) res->detail_value, &hash_value, rep_aux->hash_hostdetails)) { - insert_report_host_detail (rep_aux->report, host, "openvasd", "", "Openvasd Host Detail", res->detail_name, res->detail_value, hash_value); diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 934e21a6b..f0de40f62 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -26,11 +26,10 @@ /** * @brief Enable extra GNU functions. */ -#include "base/nvti.h" + +#include #include "glibconfig.h" #include "manage.h" -#include "openvasd/openvasd.h" -#include "openvasd/jsonutils.h" #define _GNU_SOURCE #include @@ -40,6 +39,9 @@ #include #include +#include +#include +#include #include #include "manage_sql_nvts.h" @@ -2155,9 +2157,10 @@ update_nvts_from_vts (element_t *get_vts_response, * @return 0 success, 1 VT integrity check failed, -1 error */ static int -update_nvts_from_json_vts (jreader_t *get_vts_response, - const gchar *scanner_feed_version, - int rebuild) +update_nvts_from_json_vts (gvm_json_pull_parser_t *parser, + gvm_json_pull_event_t *event, + const gchar *scanner_feed_version, + int rebuild) { GList *preferences; int count_modified_vts, count_new_vts; @@ -2203,7 +2206,7 @@ update_nvts_from_json_vts (jreader_t *get_vts_response, vt_refs_batch = batch_start (vt_ref_insert_size); vt_sevs_batch = batch_start (vt_sev_insert_size); - nvti_t *nvti = gvm_jnode_parse_vt (*get_vts_response); + nvti_t *nvti = openvasd_parse_vt (parser,event); while (nvti) { if (nvti == NULL) @@ -2230,7 +2233,7 @@ update_nvts_from_json_vts (jreader_t *get_vts_response, g_list_free_full (preferences, (GDestroyNotify) preference_free); nvti_free (nvti); - nvti = gvm_jnode_parse_vt (*get_vts_response); + nvti = openvasd_parse_vt (parser, event); } batch_end (vt_refs_batch); @@ -2666,15 +2669,17 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, return -1; } - jparser_t parser; - jreader_t reader; - - parser = gvm_parse_jnode (); - gvm_read_jnode (resp->body, parser, &reader); + FILE *stream; + gvm_json_pull_event_t event; + gvm_json_pull_parser_t parser; - ret = update_nvts_from_json_vts (&reader, scanner_feed_version, rebuild); - gvm_close_jnode_reader (reader); - gvm_close_jnode_parser (parser); + stream = fmemopen (resp->body, strlen (resp->body), "r"); + gvm_json_pull_parser_init (&parser, stream); + gvm_json_pull_event_init (&event); + ret = update_nvts_from_json_vts (&parser, &event, scanner_feed_version, + rebuild); + fclose(stream); + gvm_json_pull_parser_cleanup (&parser); openvasd_response_free (resp); @@ -2966,7 +2971,8 @@ manage_update_nvt_cache_osp (const gchar *update_socket) sql_int ("SELECT count (*) FROM nvts;")); #if OPENVASD == 1 - ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, db_feed_version, + ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, + db_feed_version, scanner_feed_version, 0); #else ret = update_nvt_cache_osp (update_socket, db_feed_version, From 8ff78f6dc0a5e8d690e11f85ea68308173fdf564 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 8 Oct 2024 14:17:19 -0300 Subject: [PATCH 09/13] Receive the feed by chunks --- src/manage_sql_nvts.c | 244 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 198 insertions(+), 46 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index f0de40f62..30f5a0de2 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -26,6 +26,9 @@ /** * @brief Enable extra GNU functions. */ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#define _FILE_OFFSET_BITS 64 +#include #include #include "glibconfig.h" @@ -41,7 +44,6 @@ #include #include -#include #include #include "manage_sql_nvts.h" @@ -2147,18 +2149,111 @@ update_nvts_from_vts (element_t *get_vts_response, return 0; } + +/** + * @brief Struct containing the stream buffer. + */ +struct FILESTREAM { + char *stream_buffer; + size_t size_of_buffer; + size_t last_read; + size_t last_write; +}; + +/** + * @brief Hook function to read the stream file cookie + */ +static ssize_t +readcookie (void *stream_cookie, char *buf, size_t size) +{ + struct FILESTREAM *stream = stream_cookie; + size_t to_read = stream->last_write - stream->last_read; + if (to_read < 0) + to_read = 0; + + if (to_read > size) + to_read = size; + memcpy (buf, &stream->stream_buffer[stream->last_read], to_read); + + stream->last_read += to_read; + return to_read; +} + +/** + * @brief Hook function to close the stream file cookie + */ +static int +closecookie(void *filestream) +{ + struct FILESTREAM *stream = filestream; + g_free(stream->stream_buffer); + stream->size_of_buffer = 0; + stream->stream_buffer = NULL; + return 0; +} + +/** + * @brief Hook function to write the stream file cookie + */ +static ssize_t +writecookie (void *stream_cookie, const char *buf, size_t size) +{ + struct FILESTREAM *stream = stream_cookie; + size_t next_size = stream->last_write + size; + if (next_size > stream->size_of_buffer) + { + stream->size_of_buffer = next_size + GVM_JSON_PULL_PARSE_BUFFER_LIMIT; + stream->stream_buffer = g_realloc (stream->stream_buffer, + stream->size_of_buffer); + if (stream->stream_buffer == NULL) + { + g_message ("%s: Buffer overflow", __func__); + return 0; + } + } + + memcpy (&(stream->stream_buffer[stream->last_write]), buf, size); + stream->last_write+=size; + + return size; +} + +/** + * @brief Move non read data to beggining of the buffer + */ +static int move_buffer_data(struct FILESTREAM *filestream){ + char *auxbuf; + size_t non_read_chars_count = filestream->last_write - filestream->last_read; + + auxbuf = g_malloc0 (sizeof(char) * filestream->size_of_buffer); + if (auxbuf == NULL) + return -1; + + memcpy (auxbuf, &filestream->stream_buffer[filestream->last_read], + non_read_chars_count); + memset (filestream->stream_buffer, '\0', filestream->size_of_buffer); + memcpy (filestream->stream_buffer, auxbuf, non_read_chars_count); + + filestream->last_read = 0; + filestream->last_write = non_read_chars_count; + + g_free(auxbuf); + + return 0; +} + /** - * @brief Update NVTs from Json response + * @brief Update NVTs from Json response chunk by chunk * - * @param[in] get_vts_response Openvasd VTS response. + * @param[in] curl_hnd Curl handler to perform the request + * @param[in] res Struct containing the response chunks * @param[in] scanner_feed_version Version of feed from scanner. * @param[in] rebuild Whether we're rebuilding the tables. * * @return 0 success, 1 VT integrity check failed, -1 error */ static int -update_nvts_from_json_vts (gvm_json_pull_parser_t *parser, - gvm_json_pull_event_t *event, +update_nvts_from_json_vts (openvasd_connector_t *connector, const gchar *scanner_feed_version, int rebuild) { @@ -2206,36 +2301,112 @@ update_nvts_from_json_vts (gvm_json_pull_parser_t *parser, vt_refs_batch = batch_start (vt_ref_insert_size); vt_sevs_batch = batch_start (vt_sev_insert_size); - nvti_t *nvti = openvasd_parse_vt (parser,event); - while (nvti) + int running = 0; + openvasd_resp_t resp; + gvm_json_pull_event_t event; + gvm_json_pull_parser_t parser; + FILE *stream = NULL; + struct FILESTREAM *filestream; + nvti_t *nvti = NULL; + openvasd_curlm_t curl_hnd = NULL; + openvasd_stringstream res; + + init_openvasd_stringstream(&res); + resp = openvasd_get_vts_stream_init(connector, &curl_hnd, &res); + if (resp->code < 0) { - if (nvti == NULL) - continue; + g_warning ("%s: failed to get VTs", __func__); + return -1; + } - if (nvti_creation_time (nvti) > feed_version_epoch) - count_new_vts += 1; - else - count_modified_vts += 1; + cookie_io_functions_t cookiehooks = { + .read = readcookie, + .write = writecookie, + .seek = NULL, + .close = closecookie, + }; - insert_nvt (nvti, rebuild, vt_refs_batch, vt_sevs_batch); + filestream = g_malloc0 (sizeof(struct FILESTREAM)); + filestream->size_of_buffer = GVM_JSON_PULL_PARSE_BUFFER_LIMIT; + filestream->stream_buffer = + g_malloc0 (sizeof(char) * filestream->size_of_buffer); - preferences = NULL; - if (update_preferences_from_json_nvt (nvti, &preferences)) + stream = fopencookie (filestream, "a+", cookiehooks); + + gvm_json_pull_parser_init_full (&parser, stream, + GVM_JSON_PULL_PARSE_BUFFER_LIMIT, + GVM_JSON_PULL_READ_BUFFER_SIZE * 8); + gvm_json_pull_event_init (&event); + + // First run for initial data in the stream + running = openvasd_get_vts_stream (curl_hnd); + fwrite (res.ptr, 1, res.len, stream); + g_free (res.ptr); + init_openvasd_stringstream(&res); + int break_flag = 0; + while (running) + { + size_t non_read_count = 0; + // Ensure a big chunk of data. + // Realloc is expensive therefore we realloc with bigger chuncks + while (running > 0 && res.len < GVM_JSON_PULL_READ_BUFFER_SIZE * 8) + running = openvasd_get_vts_stream (curl_hnd); + + if (res.len > 0) { - sql_rollback (); - return -1; + move_buffer_data (filestream); + fwrite (res.ptr, 1, res.len, stream); + g_free (res.ptr); + init_openvasd_stringstream (&res); } - if (rebuild == 0) - sql ("DELETE FROM nvt_preferences%s WHERE name LIKE '%s:%%';", - rebuild ? "_rebuild" : "", - nvti_oid (nvti)); - insert_nvt_preferences_list (preferences, rebuild); - g_list_free_full (preferences, (GDestroyNotify) preference_free); - nvti_free (nvti); - nvti = openvasd_parse_vt (parser, event); + non_read_count = filestream->last_write - filestream->last_read; + // While streaming, parse some VTs and continue for a new chunk. + // If the stream is not running anymore, parse the remaining VTs. + while ((running && non_read_count > GVM_JSON_PULL_READ_BUFFER_SIZE * 8) || !running) + { + nvti = openvasd_parse_vt (&parser, &event); + if (nvti == NULL) + { + break_flag = 1; + break; + } + if (nvti_creation_time (nvti) > feed_version_epoch) + count_new_vts += 1; + else + count_modified_vts += 1; + + insert_nvt (nvti, rebuild, vt_refs_batch, vt_sevs_batch); + + preferences = NULL; + if (update_preferences_from_json_nvt (nvti, &preferences)) + { + sql_rollback (); + return -1; + } + if (rebuild == 0) + sql ("DELETE FROM nvt_preferences%s WHERE name LIKE '%s:%%';", + rebuild ? "_rebuild" : "", + nvti_oid (nvti)); + insert_nvt_preferences_list (preferences, rebuild); + g_list_free_full (preferences, (GDestroyNotify) preference_free); + + g_free(nvti); + non_read_count = filestream->last_write - filestream->last_read; + } + if (break_flag) + break; } + gvm_json_pull_event_cleanup(&event); + gvm_json_pull_parser_cleanup(&parser); + fclose(stream); + + g_free (res.ptr); + openvasd_curl_handler_close (&curl_hnd); + openvasd_response_free (resp); + + batch_end (vt_refs_batch); batch_end (vt_sevs_batch); @@ -2662,27 +2833,8 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, return -1; } - resp = openvasd_get_vts (&connector); - if (resp->code != 200) - { - g_warning ("%s: failed to get VTs", __func__); - return -1; - } - - FILE *stream; - gvm_json_pull_event_t event; - gvm_json_pull_parser_t parser; - - stream = fmemopen (resp->body, strlen (resp->body), "r"); - gvm_json_pull_parser_init (&parser, stream); - gvm_json_pull_event_init (&event); - ret = update_nvts_from_json_vts (&parser, &event, scanner_feed_version, + ret = update_nvts_from_json_vts (&connector, scanner_feed_version, rebuild); - fclose(stream); - gvm_json_pull_parser_cleanup (&parser); - - openvasd_response_free (resp); - if (ret) { openvasd_connector_free (&connector); From f71a376af19639c2c8746de8e9781f47e52b5449 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 16 Oct 2024 12:29:51 -0300 Subject: [PATCH 10/13] adjust to changes in gvm-libs/openvasd/ --- src/manage.c | 14 +++++++------- src/manage_sql_nvts.c | 32 +++++++++++++++----------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/manage.c b/src/manage.c index 3aabb86bd..bcf4e7135 100644 --- a/src/manage.c +++ b/src/manage.c @@ -7473,7 +7473,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, ret = 0; } - openvasd_response_free (resp); + openvasd_response_cleanup (resp); openvasd_connector_free (&connector); return ret; } @@ -8413,7 +8413,7 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, *error = g_strdup_printf ("Failed to stop old report: %ld", response->code); openvasd_connector_free (&connection); - openvasd_response_free(response); + openvasd_response_cleanup(response); return -1; } response = openvasd_delete_scan (&connection); @@ -8421,7 +8421,7 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); - openvasd_response_free(response); + openvasd_response_cleanup(response); openvasd_connector_free (&connection); return -1; } @@ -8439,7 +8439,7 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); - openvasd_response_free(response); + openvasd_response_cleanup(response); openvasd_connector_free (&connection); return -1; } @@ -8457,7 +8457,7 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); - openvasd_response_free(response); + openvasd_response_cleanup(response); openvasd_connector_free (&connection); return -1; } @@ -8783,7 +8783,7 @@ launch_openvasd_openvas_task (task_t task, target_t target, const char *scan_id, g_slist_free_full (vts, (GDestroyNotify) openvasd_vt_single_free); g_hash_table_destroy (scanner_options); ret = response->code; - openvasd_response_free (response); + openvasd_response_cleanup (response); return ret; } @@ -8978,7 +8978,7 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) retry = connection_retry; gvm_sleep (5); } - openvasd_response_free (response); + openvasd_response_cleanup (response); openvasd_connector_free(&connector); return rc; } diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 30f5a0de2..3ae7ea5b4 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2245,8 +2245,7 @@ static int move_buffer_data(struct FILESTREAM *filestream){ /** * @brief Update NVTs from Json response chunk by chunk * - * @param[in] curl_hnd Curl handler to perform the request - * @param[in] res Struct containing the response chunks + * @param[in] conn Openvasd connector * @param[in] scanner_feed_version Version of feed from scanner. * @param[in] rebuild Whether we're rebuilding the tables. * @@ -2308,11 +2307,12 @@ update_nvts_from_json_vts (openvasd_connector_t *connector, FILE *stream = NULL; struct FILESTREAM *filestream; nvti_t *nvti = NULL; - openvasd_curlm_t curl_hnd = NULL; - openvasd_stringstream res; + openvasd_curlm_t *curl_hnd = NULL; + openvasd_stringstream_t res; - init_openvasd_stringstream(&res); - resp = openvasd_get_vts_stream_init(connector, &curl_hnd, &res); + openvasd_stringstream_new (&res); + curl_hnd = openvasd_curlm_handler_new (); + resp = openvasd_get_vts_stream_init (connector, &curl_hnd, &res); if (resp->code < 0) { g_warning ("%s: failed to get VTs", __func__); @@ -2341,8 +2341,7 @@ update_nvts_from_json_vts (openvasd_connector_t *connector, // First run for initial data in the stream running = openvasd_get_vts_stream (curl_hnd); fwrite (res.ptr, 1, res.len, stream); - g_free (res.ptr); - init_openvasd_stringstream(&res); + openvasd_stringstream_reset (&res); int break_flag = 0; while (running) { @@ -2356,8 +2355,7 @@ update_nvts_from_json_vts (openvasd_connector_t *connector, { move_buffer_data (filestream); fwrite (res.ptr, 1, res.len, stream); - g_free (res.ptr); - init_openvasd_stringstream (&res); + openvasd_stringstream_reset (&res); } non_read_count = filestream->last_write - filestream->last_read; @@ -2398,13 +2396,13 @@ update_nvts_from_json_vts (openvasd_connector_t *connector, break; } - gvm_json_pull_event_cleanup(&event); - gvm_json_pull_parser_cleanup(&parser); - fclose(stream); + gvm_json_pull_event_cleanup (&event); + gvm_json_pull_parser_cleanup (&parser); + fclose (stream); - g_free (res.ptr); - openvasd_curl_handler_close (&curl_hnd); - openvasd_response_free (resp); + openvasd_stringstream_cleanup (&res); + openvasd_curlm_handler_close (&curl_hnd); + openvasd_response_cleanup (resp); batch_end (vt_refs_batch); @@ -2973,7 +2971,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, ret = 0; } - openvasd_response_free (resp); + openvasd_response_cleanup (resp); openvasd_connector_free (&connector); return ret; } From 95e192df182c3637d57563895e8d9ea09bec7eb2 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 22 Oct 2024 10:36:48 -0300 Subject: [PATCH 11/13] dont use double pointers --- src/manage.c | 66 ++++++++++++++++++++++--------------------- src/manage_sql.c | 26 ++++++++--------- src/manage_sql_nvts.c | 16 +++++------ 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/src/manage.c b/src/manage.c index bcf4e7135..6c4e53953 100644 --- a/src/manage.c +++ b/src/manage.c @@ -7458,7 +7458,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, if (!connector) return 1; - resp = openvasd_get_health_ready (&connector); + resp = openvasd_get_health_ready (connector); if (resp->code == -1) { g_warning ("%s: failed to connect to %s:%d", __func__, @@ -7474,7 +7474,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, } openvasd_response_cleanup (resp); - openvasd_connector_free (&connector); + openvasd_connector_free (connector); return ret; } @@ -8329,17 +8329,17 @@ stop_openvasd_task (task_t task) current_scanner_task = task; global_current_report = task_running_report (task); set_task_run_status (task, TASK_STATUS_STOP_REQUESTED); - response = openvasd_stop_scan (&connector); + response = openvasd_stop_scan (connector); if (response->code < 0) { ret = -1; g_free (scan_id); goto end_stop_openvasd; } - response = openvasd_delete_scan (&connector); + response = openvasd_delete_scan (connector); g_free (scan_id); end_stop_openvasd: - openvasd_connector_free(&connector); + openvasd_connector_free (connector); set_task_end_time_epoch (task, time (NULL)); set_task_run_status (task, TASK_STATUS_STOPPED); if (scan_report) @@ -8384,20 +8384,20 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, *error = g_strdup ("Could not connect to Openvasd Scanner"); return -1; } - status = openvasd_parsed_scan_status (&connection); + status = openvasd_parsed_scan_status (connection); if (status->status == OPENVASD_SCAN_STATUS_ERROR) { if (status->response_code == 404) { g_debug ("%s: Scan %s not found", __func__, scan_id); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); trim_partial_report (global_current_report); return 1; } g_warning ("%s: Error getting status of scan %s: %ld", __func__, scan_id, status->response_code); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return -1; } else if (status->status == OPENVASD_SCAN_STATUS_RUNNING @@ -8407,25 +8407,25 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, /* It would be possible to simply continue getting the results * from the scanner, but gvmd may have crashed while receiving * or storing the results, so some may be missing. */ - response = openvasd_stop_scan (&connection); + response = openvasd_stop_scan (connection); if (response->code != 204) { *error = g_strdup_printf ("Failed to stop old report: %ld", response->code); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); openvasd_response_cleanup(response); return -1; } - response = openvasd_delete_scan (&connection); + response = openvasd_delete_scan (connection); if (response->code != 204) { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); openvasd_response_cleanup(response); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return -1; } - openvasd_connector_free (&connection); + openvasd_connector_free (connection); trim_partial_report (global_current_report); return 1; } @@ -8434,16 +8434,16 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, /* OSP can't stop an already finished/interrupted scan, * but it must be delete to be resumed. */ g_debug ("%s: Scan %s finished", __func__, scan_id); - response = openvasd_delete_scan (&connection); + response = openvasd_delete_scan (connection); if (response->code != 204) { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); openvasd_response_cleanup(response); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return -1; } - openvasd_connector_free (&connection); + openvasd_connector_free (connection); trim_partial_report (global_current_report); return 1; } @@ -8452,23 +8452,23 @@ prepare_openvasd_scan_for_resume (task_t task, const char *scan_id, { g_debug ("%s: Scan %s stopped or interrupted", __func__, scan_id); - response = openvasd_delete_scan (&connection); + response = openvasd_delete_scan (connection); if (response->code != 204) { *error = g_strdup_printf ("Failed to delete old report: %ld", response->code); openvasd_response_cleanup(response); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return -1; } - openvasd_connector_free (&connection); + openvasd_connector_free (connection); trim_partial_report (global_current_report); return 1; } g_warning ("%s: Unexpected scanner status %d", __func__, status->status); *error = g_strdup_printf ("Unexpected scanner status %d", status->status); - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return -1; } @@ -8777,7 +8777,7 @@ launch_openvasd_openvas_task (task_t task, target_t target, const char *scan_id, scan_config = openvasd_build_scan_config_json(openvasd_target, scanner_options, vts); - response = openvasd_start_scan (&connection, scan_config); + response = openvasd_start_scan (connection, scan_config); openvasd_target_free(openvasd_target); // Credentials are freed with target g_slist_free_full (vts, (GDestroyNotify) openvasd_vt_single_free); @@ -8829,7 +8829,7 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) break; } - progress = openvasd_get_scan_progress (&connector); + progress = openvasd_get_scan_progress (connector); if (progress < 0 || progress > 100) { @@ -8852,14 +8852,14 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) "Erroneous scan progress value", "", "", QOD_DEFAULT, NULL, NULL); report_add_result (report, result); - response = openvasd_delete_scan(&connector); + response = openvasd_delete_scan(connector); rc = -1; break; } else { /* Get the full openvasd report. */ - progress = openvasd_get_scan_progress (&connector); + progress = openvasd_get_scan_progress (connector); if (progress < 0 || progress > 100) { @@ -8896,12 +8896,12 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) set_report_slave_progress (report, progress); - openvasd_parsed_results (&connector, result_start, + openvasd_parsed_results (connector, result_start, result_end, &results); result_start += g_slist_length (results); gvm_sleep(1); - openvasd_scan_status = openvasd_parsed_scan_status (&connector); + openvasd_scan_status = openvasd_parsed_scan_status (connector); start_time = openvasd_scan_status->start_time; end_time = openvasd_scan_status->end_time; current_status = openvasd_scan_status->status; @@ -8910,8 +8910,10 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) if (g_slist_length(results)) { - parse_openvasd_report (task, report, results, - start_time, end_time); + parse_openvasd_report (task, report, results, start_time, + end_time); + g_slist_free_full (results, + (GDestroyNotify) openvasd_result_free); } if (current_status == OPENVASD_SCAN_STATUS_STORED) { @@ -8931,7 +8933,7 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) "Task interrupted unexpectedly", "", "", QOD_DEFAULT, NULL, NULL); report_add_result (report, result); - response = openvasd_delete_scan (&connector); + response = openvasd_delete_scan (connector); rc = -3; break; } @@ -8953,14 +8955,14 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) "Scan stopped unexpectedly by the server", "", "", QOD_DEFAULT, NULL, NULL); report_add_result (report, result); - response = openvasd_delete_scan (&connector); + response = openvasd_delete_scan (connector); rc = -1; break; } else if (progress == 100 && current_status == OPENVASD_SCAN_STATUS_SUCCEEDED) { - response = openvasd_delete_scan (&connector); + response = openvasd_delete_scan (connector); rc = response->code; break; } @@ -8979,7 +8981,7 @@ handle_openvasd_scan (task_t task, report_t report, const char *scan_id) gvm_sleep (5); } openvasd_response_cleanup (response); - openvasd_connector_free(&connector); + openvasd_connector_free(connector); return rc; } diff --git a/src/manage_sql.c b/src/manage_sql.c index 6b31bad40..ea7d7d8ff 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -43605,19 +43605,19 @@ openvasd_get_details_from_iterator (iterator_t *iterator, char **desc, connection = openvasd_connector_new(); - openvasd_connector_builder (&connection, OPENVASD_SERVER, server); - openvasd_connector_builder (&connection, OPENVASD_CA_CERT, ca_pub); - openvasd_connector_builder (&connection, OPENVASD_KEY, key_priv); - openvasd_connector_builder (&connection, OPENVASD_CERT, key_pub); - openvasd_connector_builder (&connection, OPENVASD_PORT, (void *) &port); + openvasd_connector_builder (connection, OPENVASD_SERVER, server); + openvasd_connector_builder (connection, OPENVASD_CA_CERT, ca_pub); + openvasd_connector_builder (connection, OPENVASD_KEY, key_priv); + openvasd_connector_builder (connection, OPENVASD_CERT, key_pub); + openvasd_connector_builder (connection, OPENVASD_PORT, (void *) &port); if (!connection) return 1; *desc = g_strdup_printf("Openvasd Sensor on htt://%s:%d", server, port); - if (openvasd_parsed_scans_preferences (&connection, params) < 0) + if (openvasd_parsed_scans_preferences (connection, params) < 0) return 1; - openvasd_connector_free (&connection); + openvasd_connector_free (connection); return 0; } @@ -60273,14 +60273,14 @@ openvasd_scanner_connect (scanner_t scanner, const char *scan_id) connection = openvasd_connector_new(); - openvasd_connector_builder (&connection, OPENVASD_SERVER, server); - openvasd_connector_builder (&connection, OPENVASD_CA_CERT, ca_pub); - openvasd_connector_builder (&connection, OPENVASD_KEY, key_priv); - openvasd_connector_builder (&connection, OPENVASD_CERT, key_pub); - openvasd_connector_builder (&connection, OPENVASD_PORT, (void *) &port); + openvasd_connector_builder (connection, OPENVASD_SERVER, server); + openvasd_connector_builder (connection, OPENVASD_CA_CERT, ca_pub); + openvasd_connector_builder (connection, OPENVASD_KEY, key_priv); + openvasd_connector_builder (connection, OPENVASD_CERT, key_pub); + openvasd_connector_builder (connection, OPENVASD_PORT, (void *) &port); if (scan_id && scan_id[0] != '\0') - openvasd_connector_builder (&connection, OPENVASD_SCAN_ID, scan_id); + openvasd_connector_builder (connection, OPENVASD_SCAN_ID, scan_id); g_free (server); g_free (ca_pub); diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 3ae7ea5b4..e684c1dd8 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2252,7 +2252,7 @@ static int move_buffer_data(struct FILESTREAM *filestream){ * @return 0 success, 1 VT integrity check failed, -1 error */ static int -update_nvts_from_json_vts (openvasd_connector_t *connector, +update_nvts_from_json_vts (openvasd_connector_t connector, const gchar *scanner_feed_version, int rebuild) { @@ -2831,18 +2831,18 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, return -1; } - ret = update_nvts_from_json_vts (&connector, scanner_feed_version, + ret = update_nvts_from_json_vts (connector, scanner_feed_version, rebuild); if (ret) { - openvasd_connector_free (&connector); + openvasd_connector_free (connector); return ret; } /* Update scanner preferences */ // TODO: update scanner preferences - resp = openvasd_get_vts (&connector); + resp = openvasd_get_vts (connector); if (resp->code != 200) { g_warning ("%s: failed to get scanner preferences", __func__); @@ -2850,9 +2850,9 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, } GSList *scan_prefs = NULL; - openvasd_parsed_scans_preferences (&connector, &scan_prefs); + openvasd_parsed_scans_preferences (connector, &scan_prefs); g_debug ("There %d scan preferences", g_slist_length (scan_prefs)); - openvasd_connector_free (&connector); + openvasd_connector_free (connector); GString *prefs_sql; GSList *point; @@ -2956,7 +2956,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, if (!connector) return 1; - resp = openvasd_get_health_ready (&connector); + resp = openvasd_get_health_ready (connector); if (resp->code == -1) { g_warning ("%s: failed to connect to %s:%d", __func__, @@ -2972,7 +2972,7 @@ nvts_feed_info_internal_from_openvasd (const gchar *scanner_uuid, } openvasd_response_cleanup (resp); - openvasd_connector_free (&connector); + openvasd_connector_free (connector); return ret; } From f45fb9a6e3f3aac1a33bd924abbe89aff3446cfe Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Fri, 1 Nov 2024 09:30:49 -0300 Subject: [PATCH 12/13] more adjustments to changes in gvm-libs --- src/manage_sql_nvts.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index e684c1dd8..6446abad0 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2307,12 +2307,8 @@ update_nvts_from_json_vts (openvasd_connector_t connector, FILE *stream = NULL; struct FILESTREAM *filestream; nvti_t *nvti = NULL; - openvasd_curlm_t *curl_hnd = NULL; - openvasd_stringstream_t res; - openvasd_stringstream_new (&res); - curl_hnd = openvasd_curlm_handler_new (); - resp = openvasd_get_vts_stream_init (connector, &curl_hnd, &res); + resp = openvasd_get_vt_stream_init (connector); if (resp->code < 0) { g_warning ("%s: failed to get VTs", __func__); @@ -2339,23 +2335,25 @@ update_nvts_from_json_vts (openvasd_connector_t connector, gvm_json_pull_event_init (&event); // First run for initial data in the stream - running = openvasd_get_vts_stream (curl_hnd); - fwrite (res.ptr, 1, res.len, stream); - openvasd_stringstream_reset (&res); + running = openvasd_get_vt_stream (connector); + fwrite (openvasd_vt_stream_str (connector), 1, + openvasd_vt_stream_len (connector), stream); + + openvasd_reset_vt_stream (connector); int break_flag = 0; while (running) { size_t non_read_count = 0; // Ensure a big chunk of data. // Realloc is expensive therefore we realloc with bigger chuncks - while (running > 0 && res.len < GVM_JSON_PULL_READ_BUFFER_SIZE * 8) - running = openvasd_get_vts_stream (curl_hnd); + while (running > 0 && openvasd_vt_stream_len (connector) < GVM_JSON_PULL_READ_BUFFER_SIZE * 8) + running = openvasd_get_vt_stream (connector); - if (res.len > 0) + if (openvasd_vt_stream_len (connector) > 0) { move_buffer_data (filestream); - fwrite (res.ptr, 1, res.len, stream); - openvasd_stringstream_reset (&res); + fwrite (openvasd_vt_stream_str (connector), 1, openvasd_vt_stream_len (connector), stream); + openvasd_reset_vt_stream (connector); } non_read_count = filestream->last_write - filestream->last_read; @@ -2400,11 +2398,8 @@ update_nvts_from_json_vts (openvasd_connector_t connector, gvm_json_pull_parser_cleanup (&parser); fclose (stream); - openvasd_stringstream_cleanup (&res); - openvasd_curlm_handler_close (&curl_hnd); openvasd_response_cleanup (resp); - batch_end (vt_refs_batch); batch_end (vt_sevs_batch); From 484bf9dda27d637dd63637157cb41ebe1e3aa8a6 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 4 Nov 2024 13:34:54 -0300 Subject: [PATCH 13/13] check for error during rebuild --- src/manage_sql_nvts.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c index 6446abad0..17e74ee01 100644 --- a/src/manage_sql_nvts.c +++ b/src/manage_sql_nvts.c @@ -2826,8 +2826,8 @@ update_nvt_cache_openvasd (gchar* openvasd_uuid, gchar *db_feed_version, return -1; } - ret = update_nvts_from_json_vts (connector, scanner_feed_version, - rebuild); + ret = update_nvts_from_json_vts (connector, scanner_feed_version, rebuild); + if (ret) { openvasd_connector_free (connector); @@ -3159,19 +3159,27 @@ manage_sync_nvts (int (*fork_update_nvt_cache) (pid_t*)) int update_or_rebuild_nvts (int update) { -gchar *db_feed_version, *scanner_feed_version; + gchar *db_feed_version = NULL; + gchar *scanner_feed_version = NULL; #if OPENVASD - int ret = 0; - const char *update_socket = NULL; - nvts_feed_version_status_internal (update_socket, - &db_feed_version, - &scanner_feed_version); + int ret = 0; + const char *update_socket = NULL; + + ret = nvts_feed_version_status_internal (update_socket, + &db_feed_version, + &scanner_feed_version); + if (ret == -1) + { + g_warning ("Failed to get scanner feed version."); + return -3; + } g_debug ("%s: db_feed_version: %s", __func__, db_feed_version); if (update == 0) set_nvts_feed_version ("0"); - ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, db_feed_version, + ret = update_nvt_cache_openvasd (SCANNER_UUID_OPENVASD_DEFAULT, + db_feed_version, scanner_feed_version, 0); if (ret != 0) ret = -1;