diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d5e8c79c0..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)
@@ -91,7 +92,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 +314,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/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/gvmd.c b/src/gvmd.c
index 0fbe8051b..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.
*
@@ -2836,6 +2840,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 +2884,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..6c4e53953 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);
}
@@ -7419,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_cleanup (resp);
+ openvasd_connector_free (connector);
+ return ret;
+}
+
/**
* @brief Get VTs feed information from the scanner using VT update socket.
*
@@ -7434,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
}
/**
@@ -7498,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
}
/**
@@ -8201,3 +8286,870 @@ 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 = 0;
+ 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)
+ {
+ ret = -1;
+ goto end_stop_openvasd;
+ }
+ scanner = task_scanner (task);
+ connector = openvasd_scanner_connect (scanner, scan_id);
+ if (!connector)
+ {
+ ret = -1;
+ 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)
+ {
+ 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));
+ 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;
+
+ 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_cleanup(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_cleanup(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_cleanup(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_cleanup(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.
+ *
+ * @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_openvasd_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_cleanup (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);
+ g_slist_free_full (results,
+ (GDestroyNotify) openvasd_result_free);
+ }
+ 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_cleanup (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..ea7d7d8ff 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.
*
@@ -43570,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.
*
@@ -43605,6 +43656,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 +43718,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 +60248,357 @@ 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 && res->port == 0 && !strcmp (type, "host_detail") &&
+ 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);
+ }
+ desc = res->message;
+ 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..f867c75d3 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"
@@ -97,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.
*/
@@ -442,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 *);
@@ -542,4 +550,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;
diff --git a/src/manage_sql_nvts.c b/src/manage_sql_nvts.c
index 04e9cf3c8..17e74ee01 100644
--- a/src/manage_sql_nvts.c
+++ b/src/manage_sql_nvts.c
@@ -26,6 +26,13 @@
/**
* @brief Enable extra GNU functions.
*/
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#define _FILE_OFFSET_BITS 64
+#include
+
+#include
+#include "glibconfig.h"
+#include "manage.h"
#define _GNU_SOURCE
#include
@@ -35,6 +42,8 @@
#include
#include
+#include
+#include
#include
#include "manage_sql_nvts.h"
@@ -1452,6 +1461,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,
@@ -1594,6 +1604,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 = g_strdup (nvtpref_type (pref));
+ name = g_strdup (nvtpref_name (pref));
+ def = g_strdup (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 = g_strdup (name);
+ *preferences = g_list_prepend (*preferences, preference);
+ }
+
+ g_free (char_id);
+ g_free (name);
+ g_free (type);
+ g_free (def);
+ }
+
+ return 0;
+}
+
/**
* @brief Create NVTI structure from VT XML.
*
@@ -1618,6 +1713,7 @@ nvti_from_vt (element_t vt)
nvti_free (nvti);
return NULL;
}
+
nvti_set_oid (nvti, id);
g_free (id);
@@ -2053,6 +2149,295 @@ 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 chunk by chunk
+ *
+ * @param[in] conn Openvasd connector
+ * @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 (openvasd_connector_t connector,
+ 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);
+
+ 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;
+
+ resp = openvasd_get_vt_stream_init (connector);
+ if (resp->code < 0)
+ {
+ g_warning ("%s: failed to get VTs", __func__);
+ return -1;
+ }
+
+ cookie_io_functions_t cookiehooks = {
+ .read = readcookie,
+ .write = writecookie,
+ .seek = NULL,
+ .close = closecookie,
+ };
+
+ 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);
+
+ 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_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 && openvasd_vt_stream_len (connector) < GVM_JSON_PULL_READ_BUFFER_SIZE * 8)
+ running = openvasd_get_vt_stream (connector);
+
+ if (openvasd_vt_stream_len (connector) > 0)
+ {
+ move_buffer_data (filestream);
+ 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;
+ // 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);
+
+ openvasd_response_cleanup (resp);
+
+ 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 +2614,7 @@ nvt_severity_iterator_score (iterator_t *iterator)
*/
DEF_ACCESS (nvt_severity_iterator_value, 4);
+
/**
* @brief Update VTs via OSP.
*
@@ -2397,6 +2783,195 @@ 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;
+ }
+
+ ret = update_nvts_from_json_vts (connector, scanner_feed_version, rebuild);
+
+ if (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 ();
+
+ /* 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_cleanup (resp);
+ openvasd_connector_free (connector);
+ return ret;
+}
+
+
/**
* @brief Get the VTs feed version from an OSP scanner.
*
@@ -2453,7 +3028,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 +3041,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 +3115,14 @@ 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;
@@ -2571,8 +3159,35 @@ manage_sync_nvts (int (*fork_update_nvt_cache) (pid_t*))
int
update_or_rebuild_nvts (int update)
{
+ gchar *db_feed_version = NULL;
+ gchar *scanner_feed_version = NULL;
+#if OPENVASD
+ 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,
+ 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;
@@ -2621,7 +3236,7 @@ update_or_rebuild_nvts (int update)
{
return -1;
}
-
+#endif
return 0;
}