OpenVAS Scanner 23.32.3
attack.c File Reference

Launches the plugins, and manages multithreading. More...

#include "attack.h"
#include "../misc/ipc_openvas.h"
#include "../misc/kb_cache.h"
#include "../misc/network.h"
#include "../misc/nvt_categories.h"
#include "../misc/pcap_openvas.h"
#include "../misc/plugutils.h"
#include "../misc/table_driven_lsc.h"
#include "../misc/user_agent.h"
#include "../nasl/nasl_debug.h"
#include "hosts.h"
#include "pluginlaunch.h"
#include "pluginload.h"
#include "pluginscheduler.h"
#include "plugs_req.h"
#include "processes.h"
#include "sighand.h"
#include "utils.h"
#include <arpa/inet.h>
#include <bsd/unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <gvm/base/hosts.h>
#include <gvm/base/networking.h>
#include <gvm/base/prefs.h>
#include <gvm/boreas/alivedetection.h>
#include <gvm/boreas/boreas_io.h>
#include <gvm/util/mqtt.h>
#include <gvm/util/nvticache.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
Include dependency graph for attack.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  attack_start_args

Macros

#define ERR_HOST_DEAD   -1
#define MAX_FORK_RETRIES   10
#define KB_RETRY_DELAY   3 /*In sec*/
#define INVALID_TARGET_LIST   "-1"
#define G_LOG_DOMAIN   "sd main"
 GLib log domain.

Functions

static int connect_main_kb (kb_t *main_kb)
 Connect to the main kb. Must be released with kb_lnk_reset() after use.
static void set_kb_readable (int host_kb_index)
 Add the Host KB index to the list of readable KBs used by ospd-openvas.
static void set_scan_status (char *status)
 Set scan status. This helps ospd-openvas to identify if a scan crashed or finished cleanly.
static int comm_send_status_host_dead (kb_t main_kb, char *ip_str)
 Send status to the client that the host is dead.
static int comm_send_status (kb_t main_kb, char *ip_str, int curr, int max)
 Sends the progress status of of a host's scan.
static void message_to_client (kb_t kb, const char *msg, const char *ip_str, const char *port, const char *type)
static void report_kb_failure (int errcode)
static void fork_sleep (int n)
static void scan_stop_cleanup (void)
static int scan_is_stopped (void)
static int nvti_category_is_safe (int category)
 Checks that an NVT category is safe.
static void append_vhost (const char *vhost, const char *source)
static void call_lsc (struct attack_start_args *args, const char *ip_str)
static int process_ipc_data (struct attack_start_args *args, const gchar *result)
static int read_ipc (struct attack_start_args *args, struct ipc_context *ctx)
static int launch_plugin (struct scan_globals *globals, struct scheduler_plugin *plugin, struct in6_addr *ip, GSList *vhosts, struct attack_start_args *args)
 Launches a nvt. Respects safe check preference (i.e. does not try.
static void attack_host (struct scan_globals *globals, struct in6_addr *ip, struct attack_start_args *args)
 Attack one host.
static char * vhosts_to_str (GSList *list)
static void check_deprecated_prefs (void)
 Check if any deprecated prefs are in pref table and print warning.
static int host_authorized (const gvm_host_t *host, const struct in6_addr *addr, const gvm_hosts_t *hosts_allow, const gvm_hosts_t *hosts_deny)
static int check_host_authorization (gvm_host_t *host, const struct in6_addr *addr)
static void attack_start (struct ipc_context *ipcc, struct attack_start_args *args)
 Set up some data and jump into attack_host().
static int apply_hosts_excluded (gvm_hosts_t *hosts)
static void apply_hosts_preferences_ordering (gvm_hosts_t *hosts)
static int apply_hosts_reverse_lookup_preferences (gvm_hosts_t *hosts)
static int check_kb_access (void)
static void set_alive_detection_tid (pthread_t tid)
static pthread_t get_alive_detection_tid ()
static gboolean ad_thread_joined (gboolean joined)
 Set and get if alive detection thread was already joined by main thread.
static void handle_scan_stop_signal ()
int attack_network (struct scan_globals *globals)
 Attack a whole network. return 0 on successes, -1 if there was a critical error.

Variables

int global_scan_stop = 0
static kb_t host_kb = NULL
static GSList * host_vhosts = NULL
static pthread_t alive_detection_tid

Detailed Description

Launches the plugins, and manages multithreading.

Definition in file attack.c.

Macro Definition Documentation

◆ ERR_HOST_DEAD

#define ERR_HOST_DEAD   -1

Definition at line 52 of file attack.c.

Referenced by attack_host(), and launch_plugin().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "sd main"

GLib log domain.

Definition at line 68 of file attack.c.

◆ INVALID_TARGET_LIST

#define INVALID_TARGET_LIST   "-1"

Define value to be sent to the client for invalid target list.

Definition at line 62 of file attack.c.

Referenced by attack_network().

◆ KB_RETRY_DELAY

#define KB_RETRY_DELAY   3 /*In sec*/

Wait KB_RETRY_DELAY seconds until trying again to get a new kb.

Definition at line 58 of file attack.c.

Referenced by attack_network().

◆ MAX_FORK_RETRIES

#define MAX_FORK_RETRIES   10

Definition at line 54 of file attack.c.

Referenced by attack_host(), and attack_network().

Function Documentation

◆ ad_thread_joined()

gboolean ad_thread_joined ( gboolean joined)
static

Set and get if alive detection thread was already joined by main thread.

The status can only be set to TRUE once in the lifetime of the program and retrieved as often as needed. After it is set to TRUE it can not be unset.

Parameters
joinedTRUE to set status to joined and FALSE to retrieve status of join.
Returns
Returns true if thread was already joined.

Definition at line 1101 of file attack.c.

1102{
1103 static gboolean alive_detection_thread_already_joined = FALSE;
1104 if (joined)
1105 alive_detection_thread_already_joined = TRUE;
1106 return alive_detection_thread_already_joined;
1107}

Referenced by attack_network(), and scan_stop_cleanup().

Here is the caller graph for this function:

◆ append_vhost()

void append_vhost ( const char * vhost,
const char * source )
static

Definition at line 294 of file attack.c.

295{
296 GSList *vhosts = NULL;
297 vhosts = host_vhosts;
298 assert (source);
299 assert (vhost);
300 while (vhosts)
301 {
302 gvm_vhost_t *tmp = vhosts->data;
303
304 if (!strcmp (tmp->value, vhost))
305 {
306 g_info ("%s: vhost '%s' exists already", __func__, vhost);
307 return;
308 }
309 vhosts = vhosts->next;
310 }
311 host_vhosts = g_slist_append (
312 host_vhosts, gvm_vhost_new (g_strdup (vhost), g_strdup (source)));
313 g_info ("%s: add vhost '%s' from '%s'", __func__, vhost, source);
314}
static GSList * host_vhosts
Definition attack.c:291

References host_vhosts.

Referenced by process_ipc_data().

Here is the caller graph for this function:

◆ apply_hosts_excluded()

int apply_hosts_excluded ( gvm_hosts_t * hosts)
static

Definition at line 918 of file attack.c.

919{
920 const char *exclude_hosts = prefs_get ("exclude_hosts");
921 int ret = 0;
922 /* Exclude hosts ? */
923 if (exclude_hosts)
924 {
925 /* Exclude hosts, resolving hostnames. */
926 ret = gvm_hosts_exclude (hosts, exclude_hosts);
927
928 if (ret > 0)
929 g_message ("exclude_hosts: Skipped %d host(s).", ret);
930 if (ret < 0)
931 g_message ("exclude_hosts: Error.");
932 }
933 return ret;
934}
static struct host * hosts
Definition hosts.c:49

References hosts.

Referenced by attack_network().

Here is the caller graph for this function:

◆ apply_hosts_preferences_ordering()

void apply_hosts_preferences_ordering ( gvm_hosts_t * hosts)
static

Definition at line 986 of file attack.c.

987{
988 const char *ordering = prefs_get ("hosts_ordering");
989
990 /* Hosts ordering strategy: sequential, random, reversed... */
991 if (ordering)
992 {
993 if (!strcmp (ordering, "random"))
994 {
995 gvm_hosts_shuffle (hosts);
996 g_debug ("hosts_ordering: Random.");
997 }
998 else if (!strcmp (ordering, "reverse"))
999 {
1000 gvm_hosts_reverse (hosts);
1001 g_debug ("hosts_ordering: Reverse.");
1002 }
1003 }
1004 else
1005 g_debug ("hosts_ordering: Sequential.");
1006}

References hosts.

Referenced by attack_network().

Here is the caller graph for this function:

◆ apply_hosts_reverse_lookup_preferences()

int apply_hosts_reverse_lookup_preferences ( gvm_hosts_t * hosts)
static

Definition at line 1009 of file attack.c.

1010{
1011#ifdef FEATURE_REVERSE_LOOKUP_EXCLUDED
1012 const char *exclude_hosts = prefs_get ("exclude_hosts");
1013 int hosts_excluded = 0;
1014
1015 if (prefs_get_bool ("reverse_lookup_unify"))
1016 {
1017 gvm_hosts_t *excluded;
1018
1019 excluded = gvm_hosts_reverse_lookup_unify_excluded (hosts);
1020 g_debug ("reverse_lookup_unify: Skipped %zu host(s).", excluded->count);
1021
1022 // Get the amount of hosts which are excluded now for this option,
1023 // but they are already in the exclude list.
1024 // This is to avoid issues with the scan progress calculation, since
1025 // the amount of excluded host could be duplicated.
1026 hosts_excluded += gvm_hosts_exclude (excluded, exclude_hosts);
1027
1028 gvm_hosts_free (excluded);
1029 }
1030
1031 if (prefs_get_bool ("reverse_lookup_only"))
1032 {
1033 gvm_hosts_t *excluded;
1034
1035 excluded = gvm_hosts_reverse_lookup_only_excluded (hosts);
1036 g_debug ("reverse_lookup_unify: Skipped %zu host(s).", excluded->count);
1037 // Get the amount of hosts which are excluded now for this option,
1038 // but they are already in the exclude list.
1039 // This is to avoid issues with the scan progress calculation, since
1040 // the amount of excluded host could be duplicated.
1041 hosts_excluded += gvm_hosts_exclude (excluded, exclude_hosts);
1042 gvm_hosts_free (excluded);
1043 }
1044 return exclude_hosts ? hosts_excluded : 0;
1045#else
1046 /* Reverse-lookup unify ? */
1047 if (prefs_get_bool ("reverse_lookup_unify"))
1048 g_debug ("reverse_lookup_unify: Skipped %d host(s).",
1049 gvm_hosts_reverse_lookup_unify (hosts));
1050
1051 /* Hosts that reverse-lookup only ? */
1052 if (prefs_get_bool ("reverse_lookup_only"))
1053 g_debug ("reverse_lookup_only: Skipped %d host(s).",
1054 gvm_hosts_reverse_lookup_only (hosts));
1055
1056 return 0;
1057#endif
1058}

References hosts.

Referenced by attack_network().

Here is the caller graph for this function:

◆ attack_host()

void attack_host ( struct scan_globals * globals,
struct in6_addr * ip,
struct attack_start_args * args )
static

Attack one host.

Definition at line 558 of file attack.c.

560{
561 /* Used for the status */
562 int num_plugs, forks_retry = 0, all_plugs_launched = 0;
563 char ip_str[INET6_ADDRSTRLEN];
564 struct scheduler_plugin *plugin;
565 pid_t parent;
566
567 addr6_to_str (ip, ip_str);
568 host_kb = args->host_kb;
569 host_vhosts = args->host->vhosts;
570 globals->host_pid = getpid ();
571 host_set_time (get_main_kb (), ip_str, "HOST_START");
572 kb_lnk_reset (get_main_kb ());
573 setproctitle ("openvas: testing %s", ip_str);
574 kb_lnk_reset (args->host_kb);
575
576 /* launch the plugins */
577 pluginlaunch_init (ip_str);
578 num_plugs = plugins_scheduler_count_active (args->sched);
579 for (;;)
580 {
581 /* Check that our father is still alive */
582 parent = getppid ();
583 if (parent <= 1 || process_alive (parent) == 0)
584 {
586 return;
587 }
588
590 {
591 // We send the stop scan signal to the current parent process
592 // group, which is the main scan process and host processes.
593 // This avoid to attack new hosts and force the running host
594 // process to finish and spread the signal to the plugin processes
595 // To prevent duplicate results we don't let ACT_END run.
596 killpg (parent, SIGUSR1);
597 }
598
599 if (scan_is_stopped ())
601
602 plugin = plugins_scheduler_next (args->sched);
603 if (plugin != NULL && plugin != PLUG_RUNNING)
604 {
605 int e;
606 static int last_status = 0, cur_plug = 0;
607
608 again:
609 e = launch_plugin (globals, plugin, ip, host_vhosts, args);
610 if (e < 0)
611 {
612 /*
613 * Remote host died
614 */
615 if (e == ERR_HOST_DEAD)
616 {
617 char buffer[2048];
618
619 snprintf (
620 buffer, sizeof (buffer),
621 "LOG|||%s||| |||general/Host_Details||| |||<host><detail>"
622 "<name>Host dead</name><value>1</value><source>"
623 "<description/><type/><name/></source></detail></host>",
624 ip_str);
626 get_main_kb (), "internal/results", buffer);
627
629 goto host_died;
630 }
631 else if (e == ERR_NO_FREE_SLOT)
632 {
633 if (forks_retry < MAX_FORK_RETRIES)
634 {
635 forks_retry++;
636 g_warning ("Launch failed for %s. No free slot available "
637 "in the internal process table for starting a "
638 "plugin.",
639 plugin->oid);
640 fork_sleep (forks_retry);
641 goto again;
642 }
643 }
644 else if (e == ERR_CANT_FORK)
645 {
646 if (forks_retry < MAX_FORK_RETRIES)
647 {
648 forks_retry++;
649 g_warning (
650 "fork() failed for %s - sleeping %d seconds (%s)",
651 plugin->oid, forks_retry, strerror (errno));
652 fork_sleep (forks_retry);
653 goto again;
654 }
655 else
656 {
657 g_warning ("fork() failed too many times - aborting");
658 goto host_died;
659 }
660 }
661 }
662
663 if ((cur_plug * 100) / num_plugs >= last_status
664 && !scan_is_stopped ())
665 {
666 last_status = (cur_plug * 100) / num_plugs + 2;
667 if (comm_send_status (get_main_kb (), ip_str, cur_plug, num_plugs)
668 < 0)
669 goto host_died;
670 }
671 cur_plug++;
672 }
673 else if (plugin == NULL)
674 break;
675 else if (plugin != NULL && plugin == PLUG_RUNNING)
676 /* 50 milliseconds. */
677 usleep (50000);
679 }
680
681 if (!scan_is_stopped () && prefs_get_bool ("table_driven_lsc")
682 && !lsc_has_run ()
683 && (prefs_get_bool ("mqtt_enabled")
684 || prefs_get_bool ("openvasd_lsc_enabled")))
685 {
686 call_lsc (args, ip_str);
687 }
688
690 if (!scan_is_stopped ())
691 {
692 int ret;
693 ret = comm_send_status (get_main_kb (), ip_str, num_plugs, num_plugs);
694 if (ret == 0)
695 all_plugs_launched = 1;
696 }
697
698host_died:
699 if (all_plugs_launched == 0 && !scan_is_stopped ())
700 g_message ("Vulnerability scan %s for host %s: not all plugins "
701 "were launched",
702 globals->scan_id, ip_str);
705 host_set_time (get_main_kb (), ip_str, "HOST_END");
706 write_host_stats (args->host_kb, globals->scan_id, ip_str);
707}
static int comm_send_status(kb_t main_kb, char *ip_str, int curr, int max)
Sends the progress status of of a host's scan.
Definition attack.c:205
static int scan_is_stopped(void)
Definition attack.c:266
static int comm_send_status_host_dead(kb_t main_kb, char *ip_str)
Send status to the client that the host is dead.
Definition attack.c:171
static void call_lsc(struct attack_start_args *args, const char *ip_str)
Definition attack.c:317
static void fork_sleep(int n)
Definition attack.c:248
static int launch_plugin(struct scan_globals *globals, struct scheduler_plugin *plugin, struct in6_addr *ip, GSList *vhosts, struct attack_start_args *args)
Launches a nvt. Respects safe check preference (i.e. does not try.
Definition attack.c:451
#define ERR_HOST_DEAD
Definition attack.c:52
#define MAX_FORK_RETRIES
Definition attack.c:54
static kb_t host_kb
Definition attack.c:290
void host_set_time(kb_t kb, char *ip, char *type)
Add star_scan and end_scan results to the main kb.
Definition hosts.c:64
kb_t get_main_kb(void)
gets the main_kb. @description returns the previously set main_kb; when asserts are enabled it will a...
Definition kb_cache.c:41
void pluginlaunch_init(const char *host)
void pluginlaunch_wait_for_free_process(kb_t main_kb, kb_t kb)
Waits and 'pushes' processes until the number of running processes has changed.
void pluginlaunch_stop(void)
void pluginlaunch_wait(kb_t main_kb, kb_t kb)
Waits and 'pushes' processes until num_running_processes is 0.
#define ERR_CANT_FORK
Error for when it is not possible to fork a new plugin process.
#define ERR_NO_FREE_SLOT
Error for when the process table is full.
void plugins_scheduler_stop(plugins_scheduler_t sched)
void plugins_scheduler_free(plugins_scheduler_t sched)
int plugins_scheduler_count_active(plugins_scheduler_t sched)
struct scheduler_plugin * plugins_scheduler_next(plugins_scheduler_t h)
#define PLUG_RUNNING
int kb_item_push_str_with_main_kb_check(kb_t kb, const char *name, const char *value)
Check if the current kb corresponds to the original scanid, if it matches it kb_item_push_str....
Definition plugutils.c:533
int check_kb_inconsistency(kb_t main_kb)
Check if the current main kb corresponds to the original scan main kb. @description Compares the scan...
Definition plugutils.c:442
plugins_scheduler_t sched
Definition attack.c:79
gvm_host_t * host
Definition attack.c:80
char * scan_id
Definition scanneraux.h:22
pid_t host_pid
Definition scanneraux.h:23
int lsc_has_run(void)
Get lsc_flag value.
void write_host_stats(kb_t kb, const char *scan_id, const char *ip)
Reads the script stats from the kb and generate a string in json format to be stored in the disk.
Definition utils.c:308
int process_alive(pid_t pid)
Definition utils.c:198

References call_lsc(), check_kb_inconsistency(), comm_send_status(), comm_send_status_host_dead(), ERR_CANT_FORK, ERR_HOST_DEAD, ERR_NO_FREE_SLOT, fork_sleep(), get_main_kb(), attack_start_args::host, attack_start_args::host_kb, host_kb, scan_globals::host_pid, host_set_time(), host_vhosts, kb_item_push_str_with_main_kb_check(), launch_plugin(), lsc_has_run(), MAX_FORK_RETRIES, scheduler_plugin::oid, PLUG_RUNNING, pluginlaunch_init(), pluginlaunch_stop(), pluginlaunch_wait(), pluginlaunch_wait_for_free_process(), plugins_scheduler_count_active(), plugins_scheduler_free(), plugins_scheduler_next(), plugins_scheduler_stop(), process_alive(), scan_globals::scan_id, scan_is_stopped(), attack_start_args::sched, and write_host_stats().

Referenced by attack_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ attack_network()

int attack_network ( struct scan_globals * globals)

Attack a whole network. return 0 on successes, -1 if there was a critical error.

Definition at line 1170 of file attack.c.

1171{
1172 int max_hosts = 0, max_checks;
1173 const char *hostlist;
1174 gvm_host_t *host;
1175 plugins_scheduler_t sched;
1176 int fork_retries = 0;
1177 struct timeval then, now;
1178 gvm_hosts_t *hosts;
1179 const gchar *port_range;
1180 int allow_simultaneous_ips;
1181 kb_t arg_host_kb, main_kb;
1182 GSList *unresolved;
1183 char buf[96];
1184 int error = 0;
1185
1187
1188 gboolean test_alive_hosts_only = prefs_get_bool ("test_alive_hosts_only");
1189 gvm_hosts_t *alive_hosts_list = NULL;
1190 kb_t alive_hosts_kb = NULL;
1191 if (test_alive_hosts_only)
1192 connect_main_kb (&alive_hosts_kb);
1193
1194 gettimeofday (&then, NULL);
1195
1196 if (check_kb_access ())
1197 {
1198 error = -1;
1199 return error;
1200 }
1201 /* Init and check Target List */
1202 hostlist = prefs_get ("TARGET");
1203 if (hostlist == NULL)
1204 {
1205 error = -1;
1206 return error;
1207 }
1208
1209 /* Verify the port range is a valid one */
1210 port_range = prefs_get ("port_range");
1211 if (validate_port_range (port_range))
1212 {
1215 main_kb, "Invalid port list. Ports must be in the range [1-65535]",
1216 NULL, NULL, "ERRMSG");
1217 kb_lnk_reset (main_kb);
1218 g_warning ("Invalid port list. Ports must be in the range [1-65535]. "
1219 "Scan terminated.");
1220 set_scan_status ("finished");
1221
1222 error = -1;
1223 return error;
1224 }
1225
1226 /* Initialize the attack. */
1227 int plugins_init_error = 0;
1228 sched = plugins_scheduler_init (prefs_get ("plugin_set"),
1229 prefs_get_bool ("auto_enable_dependencies"),
1230 &plugins_init_error);
1231 if (!sched)
1232 {
1233 g_message ("Couldn't initialize the plugin scheduler");
1234
1235 error = -1;
1236 return error;
1237 }
1238
1239 if (plugins_init_error > 0)
1240 {
1241 sprintf (buf,
1242 "%d errors were found during the plugin scheduling. "
1243 "Some plugins have not been launched.",
1244 plugins_init_error);
1245
1247 message_to_client (main_kb, buf, NULL, NULL, "ERRMSG");
1248 kb_lnk_reset (main_kb);
1249 }
1250
1251 max_hosts = get_max_hosts_number ();
1252 max_checks = get_max_checks_number ();
1253
1254 hosts = gvm_hosts_new (hostlist);
1255 if (hosts == NULL)
1256 {
1257 char *buffer;
1258 buffer = g_strdup_printf ("Invalid target list: %s.", hostlist);
1260 message_to_client (main_kb, buffer, NULL, NULL, "ERRMSG");
1261 g_free (buffer);
1262 /* Send the hosts count to the client as -1,
1263 * because the invalid target list.*/
1265 "HOSTS_COUNT");
1266 kb_lnk_reset (main_kb);
1267 g_warning ("Invalid target list. Scan terminated.");
1268
1269 error = -1;
1270 goto stop;
1271 }
1272
1273 unresolved = gvm_hosts_resolve (hosts);
1274 while (unresolved)
1275 {
1276 g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
1277 unresolved = unresolved->next;
1278 }
1279 g_slist_free_full (unresolved, g_free);
1280
1281 /* Apply Hosts preferences. */
1283
1284 int already_excluded = 0;
1285 already_excluded = apply_hosts_reverse_lookup_preferences (hosts);
1286
1287#ifdef FEATURE_HOSTS_ALLOWED_ONLY
1288 // Remove hosts which are denied and/or keep the ones in the allowed host
1289 // lists
1290 // for both, user and system wide settings.
1291 apply_hosts_allow_deny (hosts);
1292#endif
1293
1294 // Remove the excluded hosts
1295 int exc = apply_hosts_excluded (hosts);
1296
1297 /* Send the excluded hosts count to the client, after removing duplicated and
1298 * unresolved hosts.*/
1299 sprintf (buf, "%d", exc + already_excluded);
1301 message_to_client (main_kb, buf, NULL, NULL, "HOSTS_EXCLUDED");
1302 kb_lnk_reset (main_kb);
1303
1304 /* Send the hosts count to the client, after removing duplicated and
1305 * unresolved hosts.*/
1306 sprintf (buf, "%d", gvm_hosts_count (hosts));
1308 message_to_client (main_kb, buf, NULL, NULL, "HOSTS_COUNT");
1309 kb_lnk_reset (main_kb);
1310
1311 host = gvm_hosts_next (hosts);
1312 if (host == NULL)
1313 goto stop;
1314
1315 hosts_init (max_hosts);
1316
1317 g_message ("Vulnerability scan %s started: Target has %d hosts: "
1318 "%s, with max_hosts = %d and max_checks = %d",
1319 globals->scan_id, gvm_hosts_count (hosts), hostlist, max_hosts,
1320 max_checks);
1321
1322 if (test_alive_hosts_only)
1323 {
1324 /* Boolean signalling if alive detection finished. */
1325 gboolean ad_finished = FALSE;
1326 int err;
1327 pthread_t tid;
1328 struct in6_addr tmpaddr;
1329
1330 /* Reset the iterator. */
1331 hosts->current = 0;
1332 err = pthread_create (&tid, NULL, start_alive_detection, (void *) hosts);
1333 if (err == EAGAIN)
1334 g_warning (
1335 "%s: pthread_create() returned EAGAIN: Insufficient resources "
1336 "to create thread.",
1337 __func__);
1339 g_debug ("%s: started alive detection.", __func__);
1340
1341 for (host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1342 !host && !ad_finished && !scan_is_stopped ();
1343 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1344 {
1345 fork_sleep (1);
1346 }
1347
1348 if (gvm_host_get_addr6 (host, &tmpaddr) == 0)
1349 host = gvm_host_find_in_hosts (host, &tmpaddr, hosts);
1350 if (host)
1351 {
1352 g_debug (
1353 "%s: Get first host to test from Queue. This host is used for "
1354 "initialising the alive_hosts_list.",
1355 __func__);
1356 }
1357 alive_hosts_list = gvm_hosts_new (gvm_host_value_str (host));
1358 }
1359
1360 if (prefs_get ("report_scripts"))
1361 {
1362 char *path = g_strdup_printf (
1363 "%s/%s-stats.json", prefs_get ("report_scripts"), globals->scan_id);
1364 write_script_stats ("{\"hosts\": {", path, 2);
1365 g_free (path);
1366 }
1367 /*
1368 * Start the attack !
1369 */
1370 allow_simultaneous_ips = prefs_get_bool ("allow_simultaneous_ips");
1372 while (host && !scan_is_stopped ())
1373 {
1374 int pid, rc;
1375 struct attack_start_args args;
1376 char *host_str;
1377
1378 if (!test_alive_hosts_only
1379 && (!allow_simultaneous_ips && host_is_currently_scanned (host)))
1380 {
1381 sleep (1);
1382 // move the host at the end of the list and get the next host.
1383 gvm_hosts_move_current_host_to_end (hosts);
1384 host = gvm_hosts_next (hosts);
1385 continue;
1386 }
1387
1388 do
1389 {
1390 rc = kb_new (&arg_host_kb, prefs_get ("db_address"));
1391 if (rc < 0 && rc != -2)
1392 {
1393 report_kb_failure (rc);
1394 goto stop;
1395 }
1396 else if (rc == -2)
1397 {
1398 sleep (KB_RETRY_DELAY);
1399 continue;
1400 }
1401 break;
1402 }
1403 while (1);
1404
1405 host_str = gvm_host_value_str (host);
1407 if (hosts_new (host_str, arg_host_kb, main_kb) < 0)
1408 {
1409 kb_delete (arg_host_kb);
1410 g_free (host_str);
1411 goto stop;
1412 }
1413
1414 if (scan_is_stopped ())
1415 {
1416 kb_delete (arg_host_kb);
1417 g_free (host_str);
1418 continue;
1419 }
1420
1421 args.host = host;
1422 args.globals = globals;
1423 args.sched = sched;
1424 args.host_kb = arg_host_kb;
1425
1426 forkagain:
1428 /* Close child process' socket. */
1429 if (pid < 0)
1430 {
1431 fork_retries++;
1432 if (fork_retries > MAX_FORK_RETRIES)
1433 {
1434 /* Forking failed - we go to the wait queue. */
1435 g_warning ("fork() failed - %s. %s won't be tested",
1436 strerror (errno), host_str);
1437 g_free (host_str);
1438 goto stop;
1439 }
1440
1441 g_debug ("fork() failed - "
1442 "sleeping %d seconds and trying again...",
1443 fork_retries);
1444 fork_sleep (fork_retries);
1445 goto forkagain;
1446 }
1447 hosts_set_pid (host_str, pid);
1448
1449 if (test_alive_hosts_only)
1450 {
1451 struct in6_addr tmpaddr;
1452 gvm_host_t *alive_buf;
1453
1454 while (1)
1455 {
1456 /* Boolean signalling if alive detection finished. */
1457 gboolean ad_finished = FALSE;
1458 for (host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1459 !host && !ad_finished && !scan_is_stopped ();
1460 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1461 {
1462 fork_sleep (1);
1463 }
1464
1465 if (host && !allow_simultaneous_ips
1467 {
1468 struct in6_addr hostip;
1469 char ip_str[INET6_ADDRSTRLEN];
1470 int flag_set;
1471
1472 gvm_host_get_addr6 (host, &hostip);
1473 addr6_to_str (&hostip, ip_str);
1474
1475 // Re-add host at the end of the queue and reallocate the flag
1476 // if it was already set.
1477 flag_set = finish_signal_on_queue (alive_hosts_kb);
1478
1479 put_host_on_queue (alive_hosts_kb, ip_str);
1480 g_debug ("Reallocating the host %s at the end of the queue",
1481 ip_str);
1482
1483 gvm_host_free (host);
1484 host = NULL;
1485
1486 if (flag_set)
1487 {
1488 g_debug ("Reallocating finish signal in the host queue");
1489 realloc_finish_signal_on_queue (alive_hosts_kb);
1490 }
1491 }
1492 else
1493 break;
1494 }
1495
1496 if (host && gvm_host_get_addr6 (host, &tmpaddr) == 0)
1497 {
1498 alive_buf = host;
1499 host = gvm_host_find_in_hosts (host, &tmpaddr, hosts);
1500 gvm_host_free (alive_buf);
1501 alive_buf = NULL;
1502 }
1503
1504 if (host)
1505 gvm_hosts_add (alive_hosts_list, gvm_duplicate_host (host));
1506 else
1507 g_debug ("%s: got NULL host, stop/finish scan", __func__);
1508 }
1509 else
1510 {
1511 host = gvm_hosts_next (hosts);
1512 }
1513 g_free (host_str);
1514 }
1515
1516 /* Every host is being tested... We have to wait for the processes
1517 * to terminate. */
1518 while (hosts_read () == 0)
1519 if (scan_is_stopped () == 1)
1520 killpg (getpid (), SIGUSR1);
1521
1522 g_debug ("Test complete");
1523
1524stop:
1525
1526 if (test_alive_hosts_only)
1527 {
1528 int err;
1529 void *retval;
1530
1531 kb_lnk_reset (alive_hosts_kb);
1532 g_debug ("%s: free alive detection data ", __func__);
1533
1534 /* need to wait for alive detection to finish */
1535 g_debug ("%s: waiting for alive detection thread to be finished...",
1536 __func__);
1537 /* Join alive detection thread. */
1538 err = pthread_join (get_alive_detection_tid (), &retval);
1539 if (err == EDEADLK)
1540 g_debug ("%s: pthread_join() returned EDEADLK.", __func__);
1541 if (err == EINVAL)
1542 g_debug ("%s: pthread_join() returned EINVAL.", __func__);
1543 if (err == ESRCH)
1544 g_debug ("%s: pthread_join() returned ESRCH.", __func__);
1545 if (retval == PTHREAD_CANCELED)
1546 g_debug ("%s: pthread_join() returned PTHREAD_CANCELED.", __func__);
1547 /* Set flag signaling that alive deteciton thread was joined. */
1548 if (err == 0)
1549 ad_thread_joined (TRUE);
1550 g_debug ("%s: Finished waiting for alive detection thread.", __func__);
1551 }
1552
1553 plugins_scheduler_free (sched);
1554
1555 gettimeofday (&now, NULL);
1556 if (test_alive_hosts_only)
1557 {
1558 g_message ("Vulnerability scan %s finished in %ld seconds: "
1559 "%d alive hosts of %d",
1560 globals->scan_id, now.tv_sec - then.tv_sec,
1561 gvm_hosts_count (alive_hosts_list), gvm_hosts_count (hosts));
1562 }
1563 else
1564 g_message ("Vulnerability scan %s finished in %ld seconds: %d hosts",
1565 globals->scan_id, now.tv_sec - then.tv_sec,
1566 gvm_hosts_count (hosts));
1567
1568 if (prefs_get ("report_scripts"))
1569 {
1570 char *buff =
1571 g_strdup_printf ("},\"scan_time\": {\"start\": %ld, \"stop\": %ld}}",
1572 then.tv_sec, now.tv_sec);
1573 char *path = g_strdup_printf (
1574 "%s/%s-stats.json", prefs_get ("report_scripts"), globals->scan_id);
1575
1576 write_script_stats (buff, path, 1);
1577
1578 g_free (buff);
1579 g_free (path);
1580 }
1581
1582 gvm_hosts_free (hosts);
1583 if (alive_hosts_list)
1584 gvm_hosts_free (alive_hosts_list);
1585
1586 set_scan_status ("finished");
1587
1588 return error;
1589}
static void attack_start(struct ipc_context *ipcc, struct attack_start_args *args)
Set up some data and jump into attack_host().
Definition attack.c:838
static int apply_hosts_reverse_lookup_preferences(gvm_hosts_t *hosts)
Definition attack.c:1009
static int apply_hosts_excluded(gvm_hosts_t *hosts)
Definition attack.c:918
static void handle_scan_stop_signal()
Definition attack.c:1110
static void set_alive_detection_tid(pthread_t tid)
Definition attack.c:1079
static void check_deprecated_prefs(void)
Check if any deprecated prefs are in pref table and print warning.
Definition attack.c:740
static int connect_main_kb(kb_t *main_kb)
Connect to the main kb. Must be released with kb_lnk_reset() after use.
Definition attack.c:96
static void report_kb_failure(int errcode)
Definition attack.c:236
static int check_kb_access(void)
Definition attack.c:1061
static void apply_hosts_preferences_ordering(gvm_hosts_t *hosts)
Definition attack.c:986
#define INVALID_TARGET_LIST
Definition attack.c:62
static void message_to_client(kb_t kb, const char *msg, const char *ip_str, const char *port, const char *type)
Definition attack.c:223
#define KB_RETRY_DELAY
Definition attack.c:58
static gboolean ad_thread_joined(gboolean joined)
Set and get if alive detection thread was already joined by main thread.
Definition attack.c:1101
static pthread_t get_alive_detection_tid()
Definition attack.c:1084
static void set_scan_status(char *status)
Set scan status. This helps ospd-openvas to identify if a scan crashed or finished cleanly.
Definition attack.c:135
int host_is_currently_scanned(gvm_host_t *host_to_check)
Returns 1 if the host is being scanned. 0 otherwise.
Definition hosts.c:271
int hosts_set_pid(char *name, pid_t pid)
Definition hosts.c:177
int hosts_read(void)
Returns -1 if client asked to stop all tests or connection was lost or error. 0 otherwise.
Definition hosts.c:253
int hosts_init(int max_hosts)
Definition hosts.c:144
int hosts_new(char *name, kb_t kb, kb_t main_kb)
Definition hosts.c:151
void(* ipc_process_func)(struct ipc_context *, void *)
Definition ipc.h:47
kb_t main_kb
Definition kb_cache.c:15
static struct timeval timeval(unsigned long val)
static pid_t pid
plugins_scheduler_t plugins_scheduler_init(const char *plugins_list, int autoload, int *error)
struct plugins_scheduler * plugins_scheduler_t
pid_t create_ipc_process(ipc_process_func func, void *args)
initializes a communication channels and calls a function with a new process
Definition processes.c:195
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition sighand.c:79
struct scan_globals * globals
Definition attack.c:76
Host information, implemented as doubly linked list.
Definition hosts.c:37
void write_script_stats(const char *buf, const char *path, int mode)
Writes scripts stats into a file.
Definition utils.c:271
int get_max_hosts_number(void)
Definition utils.c:137
int get_max_checks_number(void)
Definition utils.c:168

References ad_thread_joined(), apply_hosts_excluded(), apply_hosts_preferences_ordering(), apply_hosts_reverse_lookup_preferences(), attack_start(), check_deprecated_prefs(), check_kb_access(), connect_main_kb(), create_ipc_process(), fork_sleep(), get_alive_detection_tid(), get_max_checks_number(), get_max_hosts_number(), attack_start_args::globals, handle_scan_stop_signal(), attack_start_args::host, host_is_currently_scanned(), attack_start_args::host_kb, hosts, hosts_init(), hosts_new(), hosts_read(), hosts_set_pid(), INVALID_TARGET_LIST, KB_RETRY_DELAY, main_kb, MAX_FORK_RETRIES, message_to_client(), openvas_signal, pid, plugins_scheduler_free(), plugins_scheduler_init(), report_kb_failure(), scan_globals::scan_id, scan_is_stopped(), attack_start_args::sched, set_alive_detection_tid(), set_scan_status(), timeval(), and write_script_stats().

Referenced by openvas().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ attack_start()

void attack_start ( struct ipc_context * ipcc,
struct attack_start_args * args )
static

Set up some data and jump into attack_host().

Definition at line 838 of file attack.c.

839{
840 struct scan_globals *globals = args->globals;
841 char ip_str[INET6_ADDRSTRLEN], *hostnames;
842 struct in6_addr hostip;
843 struct timeval then;
844 kb_t kb = args->host_kb;
845 kb_t main_kb = get_main_kb ();
846 int ret;
847 args->ipc_context = ipcc;
848
849 nvticache_reset ();
850 kb_lnk_reset (kb);
851 kb_lnk_reset (main_kb);
852 gettimeofday (&then, NULL);
853
854 kb_item_set_str_with_main_kb_check (kb, "internal/scan_id", globals->scan_id,
855 0);
856 set_kb_readable (kb_get_kb_index (kb));
857
858 /* The reverse lookup is delayed to this step in order to not slow down the
859 * main scan process eg. case of target with big range of IP addresses. */
860 if (prefs_get_bool ("expand_vhosts"))
861 gvm_host_add_reverse_lookup (args->host);
862 if ((ret = gvm_vhosts_exclude (args->host, prefs_get ("exclude_hosts"))) > 0)
863 g_message ("exclude_hosts: Skipped %d vhost(s).", ret);
864 gvm_host_get_addr6 (args->host, &hostip);
865 addr6_to_str (&hostip, ip_str);
866
867#ifndef FEATURE_HOSTS_ALLOWED_ONLY
868 int ret_host_auth = check_host_authorization (args->host, &hostip);
869 if (ret_host_auth < 0)
870 {
871 if (ret_host_auth == -1)
872 message_to_client (kb, "Host access denied.", ip_str, NULL, "ERRMSG");
873 else
874 message_to_client (kb, "Host access denied (system-wide restriction.)",
875 ip_str, NULL, "ERRMSG");
876
877 kb_item_set_str_with_main_kb_check (kb, "internal/host_deny", "True", 0);
878 g_warning ("Host %s access denied.", ip_str);
879 return;
880 }
881#endif
882
883 if (prefs_get_bool ("test_empty_vhost"))
884 {
885 gvm_vhost_t *vhost =
886 gvm_vhost_new (g_strdup (ip_str), g_strdup ("IP-address"));
887 args->host->vhosts = g_slist_prepend (args->host->vhosts, vhost);
888 }
889 hostnames = vhosts_to_str (args->host->vhosts);
890 if (hostnames)
891 g_message ("Vulnerability scan %s started for host: %s (Vhosts: %s)",
892 globals->scan_id, ip_str, hostnames);
893 else
894 g_message ("Vulnerability scan %s started for host: %s", globals->scan_id,
895 ip_str);
896 g_free (hostnames);
897 attack_host (globals, &hostip, args);
898 kb_lnk_reset (main_kb);
899
900 if (!scan_is_stopped ())
901 {
902 struct timeval now;
903
904 gettimeofday (&now, NULL);
905 if (now.tv_usec < then.tv_usec)
906 {
907 then.tv_sec++;
908 now.tv_usec += 1000000;
909 }
910 g_message (
911 "Vulnerability scan %s finished for host %s in %ld.%.2ld seconds",
912 globals->scan_id, ip_str, (long) (now.tv_sec - then.tv_sec),
913 (long) ((now.tv_usec - then.tv_usec) / 10000));
914 }
915}
static void set_kb_readable(int host_kb_index)
Add the Host KB index to the list of readable KBs used by ospd-openvas.
Definition attack.c:118
static int check_host_authorization(gvm_host_t *host, const struct in6_addr *addr)
Definition attack.c:809
static void attack_host(struct scan_globals *globals, struct in6_addr *ip, struct attack_start_args *args)
Attack one host.
Definition attack.c:558
static char * vhosts_to_str(GSList *list)
Definition attack.c:717
int kb_item_set_str_with_main_kb_check(kb_t kb, const char *name, const char *value, size_t len)
Check if the current kb corresponds to the original scanid, if it matches it call kb_item_set_str....
Definition plugutils.c:558
static struct ipc_contexts * ipcc
Definition processes.c:39
struct ipc_context * ipc_context
Definition attack.c:78

References attack_host(), check_host_authorization(), get_main_kb(), attack_start_args::globals, attack_start_args::host, attack_start_args::host_kb, attack_start_args::ipc_context, ipcc, kb_item_set_str_with_main_kb_check(), main_kb, message_to_client(), scan_globals::scan_id, scan_is_stopped(), set_kb_readable(), timeval(), and vhosts_to_str().

Referenced by attack_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ call_lsc()

void call_lsc ( struct attack_start_args * args,
const char * ip_str )
static

Definition at line 317 of file attack.c.

318{
319 char *package_list = NULL;
320 char *os_release = NULL;
321 kb_t hostkb = NULL;
322
323 hostkb = args->host_kb;
324 /* Get the OS release. TODO: have a list with
325 * supported OS. */
326 os_release = kb_item_get_str (hostkb, "ssh/login/release_notus");
327 /* Get the package list. */
328 package_list = kb_item_get_str (hostkb, "ssh/login/package_list_notus");
329
330 if (run_table_driven_lsc (args->globals->scan_id, ip_str, NULL, package_list,
331 os_release)
332 < 0)
333 {
334 char buffer[2048];
335 snprintf (buffer, sizeof (buffer),
336 "ERRMSG|||%s||| ||| ||| ||| Unable to "
337 "launch table driven lsc",
338 ip_str);
339 kb_item_push_str_with_main_kb_check (get_main_kb (), "internal/results",
340 buffer);
341 g_warning ("%s: Unable to launch table driven LSC", __func__);
342 }
343 g_free (package_list);
344 g_free (os_release);
345}
int run_table_driven_lsc(const char *scan_id, const char *ip_str, const char *hostname, const char *package_list, const char *os_release)
Publish the necessary data to start a Table driven LSC scan.

References get_main_kb(), attack_start_args::globals, attack_start_args::host_kb, kb_item_push_str_with_main_kb_check(), run_table_driven_lsc(), and scan_globals::scan_id.

Referenced by attack_host(), and process_ipc_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_deprecated_prefs()

void check_deprecated_prefs ( void )
static

Check if any deprecated prefs are in pref table and print warning.

Definition at line 740 of file attack.c.

741{
742 const gchar *source_iface = prefs_get ("source_iface");
743 const gchar *ifaces_allow = prefs_get ("ifaces_allow");
744 const gchar *ifaces_deny = prefs_get ("ifaces_deny");
745 const gchar *sys_ifaces_allow = prefs_get ("sys_ifaces_allow");
746 const gchar *sys_ifaces_deny = prefs_get ("sys_ifaces_deny");
747
748 if (source_iface || ifaces_allow || ifaces_deny || sys_ifaces_allow
749 || sys_ifaces_deny)
750 {
751 kb_t main_kb = NULL;
752 gchar *msg = NULL;
753
754 msg = g_strdup_printf (
755 "The following provided settings are deprecated since the 22.4 "
756 "release and will be ignored: %s%s%s%s%s",
757 source_iface ? "source_iface (task setting) " : "",
758 ifaces_allow ? "ifaces_allow (user setting) " : "",
759 ifaces_deny ? "ifaces_deny (user setting) " : "",
760 sys_ifaces_allow ? "sys_ifaces_allow (scanner only setting) " : "",
761 sys_ifaces_deny ? "sys_ifaces_deny (scanner only setting)" : "");
762 g_warning ("%s: %s", __func__, msg);
763
765 message_to_client (main_kb, msg, NULL, NULL, "ERRMSG");
766 kb_lnk_reset (main_kb);
767 g_free (msg);
768 }
769}

References connect_main_kb(), main_kb, and message_to_client().

Referenced by attack_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_host_authorization()

int check_host_authorization ( gvm_host_t * host,
const struct in6_addr * addr )
static

Definition at line 809 of file attack.c.

810{
811 gvm_hosts_t *hosts_allow, *hosts_deny;
812 gvm_hosts_t *sys_hosts_allow, *sys_hosts_deny;
813
814 /* Do we have the right to test this host ? */
815 hosts_allow = gvm_hosts_new (prefs_get ("hosts_allow"));
816 hosts_deny = gvm_hosts_new (prefs_get ("hosts_deny"));
817 if (!host_authorized (host, addr, hosts_allow, hosts_deny))
818 return -1;
819
820 sys_hosts_allow = gvm_hosts_new (prefs_get ("sys_hosts_allow"));
821 sys_hosts_deny = gvm_hosts_new (prefs_get ("sys_hosts_deny"));
822 if (!host_authorized (host, addr, sys_hosts_allow, sys_hosts_deny))
823 return -2;
824
825 gvm_hosts_free (hosts_allow);
826 gvm_hosts_free (hosts_deny);
827 gvm_hosts_free (sys_hosts_allow);
828 gvm_hosts_free (sys_hosts_deny);
829 return 0;
830}
static int host_authorized(const gvm_host_t *host, const struct in6_addr *addr, const gvm_hosts_t *hosts_allow, const gvm_hosts_t *hosts_deny)
Definition attack.c:784

References host_authorized().

Referenced by attack_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_kb_access()

int check_kb_access ( void )
static

Definition at line 1061 of file attack.c.

1062{
1063 int rc;
1064 kb_t kb;
1065
1066 rc = kb_new (&kb, prefs_get ("db_address"));
1067 if (rc)
1068 report_kb_failure (rc);
1069 else
1070 kb_delete (kb);
1071
1072 return rc;
1073}

References report_kb_failure().

Referenced by attack_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ comm_send_status()

int comm_send_status ( kb_t main_kb,
char * ip_str,
int curr,
int max )
static

Sends the progress status of of a host's scan.

Status format "current_host/launched/total". Current host is the ip_str of the current host which is vulnerability tested. Launched is the number of plguins(VTs) which got already started. Total is the total number of plugins which will be started for the current host.

Parameters
main_kbKb to use.
ip_strstr representation of host ip
currCurrently launched plugins (VTs) for the host
maxMaximum number of plugins which will be launched for the host
Returns
0 on success, -1 on error.

Definition at line 205 of file attack.c.

206{
207 char status_buf[2048];
208
209 if (!ip_str || !main_kb)
210 return -1;
211
212 if (strlen (ip_str) > (sizeof (status_buf) - 50))
213 return -1;
214
215 snprintf (status_buf, sizeof (status_buf), "%s/%d/%d", ip_str, curr, max);
216 kb_item_push_str_with_main_kb_check (main_kb, "internal/status", status_buf);
217 kb_lnk_reset (main_kb);
218
219 return 0;
220}
#define max
Definition nasl_wmi.c:34

References kb_item_push_str_with_main_kb_check(), main_kb, and max.

Referenced by attack_host(), Ensure(), Ensure(), and Ensure().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ comm_send_status_host_dead()

int comm_send_status_host_dead ( kb_t main_kb,
char * ip_str )
static

Send status to the client that the host is dead.

Originally the progress status is of the format "current_host/launched/total". Current host is the ip_str of the current host which is vulnerability tested. Launched is the number of plguins(VTs) which got already started. Total is the total number of plugins which will be started for the current host. But here we use the format "current_host/0/-1" for implicit singalling that the host is dead.

Parameters
main_kbKb to use
ip_strstr representation of host ip
Returns
0 on success, -1 on failure.

Definition at line 171 of file attack.c.

172{
173 // implicit status code. Originally launched/total plugins
174 const gchar *host_dead_status_code = "0/-1";
175 const gchar *topic = "internal/status";
176 gchar *status;
177
178 // exact same restriction as comm_send_status() just to make it consistent
179 if (strlen (ip_str) > 1998)
180 return -1;
181 status = g_strjoin ("/", ip_str, host_dead_status_code, NULL);
183 g_free (status);
184
185 return 0;
186}

References kb_item_push_str_with_main_kb_check(), and main_kb.

Referenced by attack_host().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect_main_kb()

int connect_main_kb ( kb_t * main_kb)
static

Connect to the main kb. Must be released with kb_lnk_reset() after use.

Parameters
[out]main_kbThe connection to the kb.
Returns
0 on success, -1 on failure.

Definition at line 96 of file attack.c.

97{
98 int i = atoi (prefs_get ("ov_maindbid"));
99
100 *main_kb = kb_direct_conn (prefs_get ("db_address"), i);
101 if (main_kb)
102 {
103 return 0;
104 }
105
106 g_warning ("Not possible to get the main kb connection.");
107 return -1;
108}

References main_kb.

Referenced by attack_network(), check_deprecated_prefs(), scan_stop_cleanup(), set_kb_readable(), and set_scan_status().

Here is the caller graph for this function:

◆ fork_sleep()

void fork_sleep ( int n)
static

Definition at line 248 of file attack.c.

249{
250 time_t then, now;
251
252 now = then = time (NULL);
253 while (now - then < n)
254 {
255 waitpid (-1, NULL, WNOHANG);
256 usleep (10000);
257 now = time (NULL);
258 }
259}

Referenced by attack_host(), and attack_network().

Here is the caller graph for this function:

◆ get_alive_detection_tid()

pthread_t get_alive_detection_tid ( )
static

Definition at line 1084 of file attack.c.

1085{
1086 return alive_detection_tid;
1087}
static pthread_t alive_detection_tid
Definition attack.c:1076

References alive_detection_tid.

Referenced by attack_network(), and scan_stop_cleanup().

Here is the caller graph for this function:

◆ handle_scan_stop_signal()

void handle_scan_stop_signal ( )
static

Definition at line 1110 of file attack.c.

1111{
1112 global_scan_stop = 1;
1113}
int global_scan_stop
Definition attack.c:261

References global_scan_stop.

Referenced by attack_network().

Here is the caller graph for this function:

◆ host_authorized()

int host_authorized ( const gvm_host_t * host,
const struct in6_addr * addr,
const gvm_hosts_t * hosts_allow,
const gvm_hosts_t * hosts_deny )
static

Definition at line 784 of file attack.c.

786{
787 /* Check Hosts Access. */
788 if (host == NULL)
789 return 0;
790
791 if (hosts_deny && gvm_host_in_hosts (host, addr, hosts_deny))
792 return 0;
793 if (hosts_allow && !gvm_host_in_hosts (host, addr, hosts_allow))
794 return 0;
795
796 return 1;
797}

Referenced by check_host_authorization().

Here is the caller graph for this function:

◆ launch_plugin()

int launch_plugin ( struct scan_globals * globals,
struct scheduler_plugin * plugin,
struct in6_addr * ip,
GSList * vhosts,
struct attack_start_args * args )
static

Launches a nvt. Respects safe check preference (i.e. does not try.

destructive nvt if save_checks is yes).

Does not launch a plugin twice if !save_kb_replay.

Returns
ERR_HOST_DEAD if host died, ERR_CANT_FORK if forking failed, ERR_NO_FREE_SLOT if the process table is full, 0 otherwise.

Definition at line 451 of file attack.c.

454{
455 int optimize = prefs_get_bool ("optimize_test");
456 int launch_error, pid, ret = 0;
457 char *oid, *name, *error = NULL, ip_str[INET6_ADDRSTRLEN];
458 nvti_t *nvti;
459
460 kb_lnk_reset (get_main_kb ());
461 addr6_to_str (ip, ip_str);
462 oid = plugin->oid;
463 nvti = nvticache_get_nvt (oid);
464
465 /* eg. When NVT was moved/removed by a feed update during the scan. */
466 if (!nvti)
467 {
468 g_message ("Plugin '%s' missing from nvticache.", oid);
470 goto finish_launch_plugin;
471 }
472 if (scan_is_stopped ())
473 {
475 goto finish_launch_plugin;
476 }
477
478 if (prefs_get_bool ("safe_checks")
479 && !nvti_category_is_safe (nvti_category (nvti)))
480 {
481 if (prefs_get_bool ("log_whole_attack"))
482 {
483 name = nvticache_get_filename (oid);
484 g_message ("Not launching %s (%s) against %s because safe checks are"
485 " enabled (this is not an error)",
486 name, oid, ip_str);
487 g_free (name);
488 }
490 goto finish_launch_plugin;
491 }
492
493 /* Do not launch NVT if mandatory key is missing (e.g. an important tool
494 * was not found). */
495 if (!mandatory_requirements_met (args->host_kb, nvti))
496 error = "because a mandatory key is missing";
497 if (error
498 || (optimize && (error = requirements_plugin (args->host_kb, nvti))))
499 {
501 if (prefs_get_bool ("log_whole_attack"))
502 {
503 name = nvticache_get_filename (oid);
504 g_message (
505 "Not launching %s (%s) against %s %s (this is not an error)", name,
506 oid, ip_str, error);
507 g_free (name);
508 }
509 goto finish_launch_plugin;
510 }
511
512 /* Stop the test if the host is 'dead' */
513 if (kb_item_get_int (args->host_kb, "Host/dead") > 0)
514 {
515 g_message ("The remote host %s is dead", ip_str);
518 ret = ERR_HOST_DEAD;
519 goto finish_launch_plugin;
520 }
521
522 /* Update vhosts list and start the plugin */
523 if (procs_get_ipc_contexts () != NULL)
524 {
525 for (int i = 0; i < procs_get_ipc_contexts ()->len; i++)
526 {
527 read_ipc (args, &procs_get_ipc_contexts ()->ctxs[i]);
528 }
529 }
530
531 /* Start the plugin */
532 launch_error = 0;
533 pid = plugin_launch (globals, plugin, ip, vhosts, args->host_kb,
534 get_main_kb (), nvti, &launch_error);
535 if (launch_error == ERR_NO_FREE_SLOT || launch_error == ERR_CANT_FORK)
536 {
538 ret = launch_error;
539 goto finish_launch_plugin;
540 }
541
542 if (prefs_get_bool ("log_whole_attack"))
543 {
544 name = nvticache_get_filename (oid);
545 g_message ("Launching %s (%s) against %s [%d]", name, oid, ip_str, pid);
546 g_free (name);
547 }
548
549finish_launch_plugin:
550 nvti_free (nvti);
551 return ret;
552}
static int nvti_category_is_safe(int category)
Checks that an NVT category is safe.
Definition attack.c:281
static int read_ipc(struct attack_start_args *args, struct ipc_context *ctx)
Definition attack.c:415
const char * oid
const char * name
Definition nasl_init.c:439
int plugin_launch(struct scan_globals *globals, struct scheduler_plugin *plugin, struct in6_addr *ip, GSList *vhosts, kb_t kb, kb_t main_kb, nvti_t *nvti, int *error)
Start a plugin.
@ PLUGIN_STATUS_DONE
@ PLUGIN_STATUS_UNRUN
char * requirements_plugin(kb_t kb, nvti_t *nvti)
Determine if the plugin requirements are met.
Definition plugs_req.c:251
int mandatory_requirements_met(kb_t kb, nvti_t *nvti)
Check whether mandatory requirements for plugin are met.
Definition plugs_req.c:234
const struct ipc_contexts * procs_get_ipc_contexts(void)
returns ipc_contexts.
Definition processes.c:239
int len
Definition ipc.h:42
enum plugin_status running_state

References ERR_CANT_FORK, ERR_HOST_DEAD, ERR_NO_FREE_SLOT, get_main_kb(), attack_start_args::host_kb, ipc_contexts::len, mandatory_requirements_met(), name, nvti_category_is_safe(), oid, scheduler_plugin::oid, pid, plugin_launch(), PLUGIN_STATUS_DONE, PLUGIN_STATUS_UNRUN, pluginlaunch_stop(), procs_get_ipc_contexts(), read_ipc(), requirements_plugin(), scheduler_plugin::running_state, and scan_is_stopped().

Referenced by attack_host().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ message_to_client()

void message_to_client ( kb_t kb,
const char * msg,
const char * ip_str,
const char * port,
const char * type )
static

Definition at line 223 of file attack.c.

225{
226 char *buf;
227
228 buf = g_strdup_printf ("%s|||%s|||%s|||%s||| |||%s", type,
229 ip_str ? ip_str : "", ip_str ? ip_str : "",
230 port ? port : " ", msg ? msg : "No error.");
231 kb_item_push_str_with_main_kb_check (kb, "internal/results", buf);
232 g_free (buf);
233}

References kb_item_push_str_with_main_kb_check(), and ipc_context::type.

Referenced by attack_network(), attack_start(), and check_deprecated_prefs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nvti_category_is_safe()

int nvti_category_is_safe ( int category)
static

Checks that an NVT category is safe.

Parameters
categoryCategory to check.
Returns
0 if category is unsafe, 1 otherwise.

Definition at line 281 of file attack.c.

282{
283 /* XXX: Duplicated from openvas/nasl. */
284 if (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST
285 || category == ACT_FLOOD || category == ACT_DENIAL)
286 return 0;
287 return 1;
288}
@ ACT_KILL_HOST
@ ACT_DESTRUCTIVE_ATTACK
@ ACT_FLOOD
@ ACT_DENIAL

References ACT_DENIAL, ACT_DESTRUCTIVE_ATTACK, ACT_FLOOD, and ACT_KILL_HOST.

Referenced by launch_plugin(), and main().

Here is the caller graph for this function:

◆ process_ipc_data()

int process_ipc_data ( struct attack_start_args * args,
const gchar * result )
static

Definition at line 348 of file attack.c.

349{
350 ipc_data_t *idata;
351 int ipc_msg_flag = IPC_DT_NO_DATA;
352
353 if ((idata = ipc_data_from_json (result, strlen (result))) != NULL)
354 {
355 switch (ipc_get_data_type_from_data (idata))
356 {
357 case IPC_DT_ERROR:
358 ipc_msg_flag |= IPC_DT_ERROR;
359 g_warning ("%s: Unknown data type.", __func__);
360 break;
361 case IPC_DT_NO_DATA:
362 break;
363 case IPC_DT_HOSTNAME:
364 ipc_msg_flag |= IPC_DT_HOSTNAME;
365 if (ipc_get_hostname_from_data (idata) == NULL)
366 g_warning ("%s: ihost data is NULL ignoring new vhost", __func__);
367 else
370 break;
372 ipc_msg_flag |= IPC_DT_USER_AGENT;
373 if (ipc_get_user_agent_from_data (idata) == NULL)
374 g_warning ("%s: iuser_agent data is NULL, ignoring new user agent",
375 __func__);
376 else
377 {
378 gchar *old_ua = NULL;
380 g_debug ("%s: The User-Agent %s has been overwritten with %s",
381 __func__, old_ua, ipc_get_user_agent_from_data (idata));
382 g_free (old_ua);
383 }
384 break;
385 case IPC_DT_LSC:
386 ipc_msg_flag |= IPC_DT_LSC;
387 set_lsc_flag ();
388 if (!scan_is_stopped () && prefs_get_bool ("table_driven_lsc")
389 && (prefs_get_bool ("mqtt_enabled")
390 || prefs_get_bool ("openvasd_lsc_enabled")))
391 {
392 struct in6_addr hostip;
393 gchar ip_str[INET6_ADDRSTRLEN];
394
395 if (!ipc_get_lsc_data_ready_flag (idata))
396 {
397 g_warning ("%s: Unknown data type.", __func__);
398 ipc_msg_flag |= IPC_DT_ERROR;
399 break;
400 }
401
402 gvm_host_get_addr6 (args->host, &hostip);
403 addr6_to_str (&hostip, ip_str);
404
405 call_lsc (args, ip_str);
406 }
407 break;
408 }
409 ipc_data_destroy (&idata);
410 }
411 return ipc_msg_flag;
412}
static void append_vhost(const char *vhost, const char *source)
Definition attack.c:294
ipc_data_t * ipc_data_from_json(const char *json, size_t len)
transforms json string to a ipc_data struct
gchar * ipc_get_hostname_from_data(ipc_data_t *data)
Get the hostname from IPC data.
Definition ipc_openvas.c:82
enum ipc_data_type ipc_get_data_type_from_data(ipc_data_t *data)
Get the data type in data.
Definition ipc_openvas.c:67
void ipc_data_destroy(ipc_data_t **data)
destroys ipc_data.
gchar * ipc_get_user_agent_from_data(ipc_data_t *data)
Get the User-Agent from IPC data.
gboolean ipc_get_lsc_data_ready_flag(ipc_data_t *data)
Get the package list from LSC IPC data.
gchar * ipc_get_hostname_source_from_data(ipc_data_t *data)
Get the vhost hostname source from IPC data.
Definition ipc_openvas.c:98
struct ipc_data ipc_data_t
Definition ipc_openvas.h:23
@ IPC_DT_NO_DATA
Definition ipc_openvas.h:17
@ IPC_DT_HOSTNAME
Definition ipc_openvas.h:18
@ IPC_DT_USER_AGENT
Definition ipc_openvas.h:19
@ IPC_DT_ERROR
Definition ipc_openvas.h:16
@ IPC_DT_LSC
Definition ipc_openvas.h:20
void set_lsc_flag(void)
Set lsc_flag to 1.
gchar * user_agent_set(const gchar *ua)
Set user-agent.
Definition user_agent.c:89

References append_vhost(), call_lsc(), attack_start_args::host, ipc_data_destroy(), ipc_data_from_json(), IPC_DT_ERROR, IPC_DT_HOSTNAME, IPC_DT_LSC, IPC_DT_NO_DATA, IPC_DT_USER_AGENT, ipc_get_data_type_from_data(), ipc_get_hostname_from_data(), ipc_get_hostname_source_from_data(), ipc_get_lsc_data_ready_flag(), ipc_get_user_agent_from_data(), scan_is_stopped(), set_lsc_flag(), and user_agent_set().

Referenced by read_ipc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_ipc()

int read_ipc ( struct attack_start_args * args,
struct ipc_context * ctx )
static

Definition at line 415 of file attack.c.

416{
417 char *results;
418 int ipc_msg_flag = IPC_DT_NO_DATA;
419
420 while ((results = ipc_retrieve (ctx, IPC_MAIN)) != NULL)
421 {
422 int len = 0;
423 int pos = 0;
424 for (int j = 0; results[j] != '\0'; j++)
425 if (results[j] == '}')
426 {
427 gchar *message = NULL;
428 len = j - pos + 1;
429 message = g_malloc0 (sizeof (gchar) * (len + 1));
430 memcpy (message, &results[pos], len);
431 pos = j + 1;
432 len = 0;
433 ipc_msg_flag |= process_ipc_data (args, message);
434 g_free (message);
435 }
436 }
437 g_free (results);
438 return ipc_msg_flag;
439}
static int process_ipc_data(struct attack_start_args *args, const gchar *result)
Definition attack.c:348
char * ipc_retrieve(struct ipc_context *context, enum ipc_relation from)
retrieves data for the relation based on the context
Definition ipc.c:95
@ IPC_MAIN
Definition ipc.h:18
uint8_t len

References IPC_DT_NO_DATA, IPC_MAIN, ipc_retrieve(), len, and process_ipc_data().

Referenced by launch_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ report_kb_failure()

void report_kb_failure ( int errcode)
static

Definition at line 236 of file attack.c.

237{
238 gchar *msg;
239
240 errcode = abs (errcode);
241 msg = g_strdup_printf ("WARNING: Cannot connect to KB at '%s': %s'",
242 prefs_get ("db_address"), strerror (errcode));
243 g_warning ("%s", msg);
244 g_free (msg);
245}

Referenced by attack_network(), and check_kb_access().

Here is the caller graph for this function:

◆ scan_is_stopped()

int scan_is_stopped ( void )
static

Definition at line 266 of file attack.c.

267{
268 if (global_scan_stop == 1)
270 return global_scan_stop;
271}
static void scan_stop_cleanup(void)
Definition attack.c:1116

References global_scan_stop, and scan_stop_cleanup().

Referenced by attack_host(), attack_network(), attack_start(), launch_plugin(), and process_ipc_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_stop_cleanup()

void scan_stop_cleanup ( void )
static

Definition at line 1116 of file attack.c.

1117{
1118 kb_t main_kb = NULL;
1119 char *pid;
1120 static int already_called = 0;
1121
1122 if (already_called == 1)
1123 return;
1124
1126 pid = kb_item_get_str (main_kb, ("internal/ovas_pid"));
1127 kb_lnk_reset (main_kb);
1128
1129 /* Stop all hosts and alive detection (if enabled) if we are in main.
1130 * Else stop all running plugin processes for the current host fork. */
1131 if (pid && (atoi (pid) == getpid ()))
1132 {
1133 already_called = 1;
1134 hosts_stop_all ();
1135
1136 /* Stop (cancel) alive detection if enabled and not already joined. */
1137 if (prefs_get_bool ("test_alive_hosts_only"))
1138 {
1139 /* Alive detection thread was already joined by main thread. */
1140 if (TRUE == ad_thread_joined (FALSE))
1141 {
1142 g_warning (
1143 "Alive detection thread was already joined by other "
1144 "thread. Cancel operation not permitted or not needed.");
1145 }
1146 else
1147 {
1148 int err;
1149 err = pthread_cancel (get_alive_detection_tid ());
1150 if (err == ESRCH)
1151 g_warning (
1152 "%s: pthread_cancel() returned ESRCH; No thread with the "
1153 "supplied ID could be found.",
1154 __func__);
1155 }
1156 }
1157 }
1158 else
1159 /* Current host process */
1161
1162 g_free (pid);
1163}
void hosts_stop_all(void)
Definition hosts.c:203

References ad_thread_joined(), connect_main_kb(), get_alive_detection_tid(), hosts_stop_all(), main_kb, pid, and pluginlaunch_stop().

Referenced by scan_is_stopped().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_alive_detection_tid()

void set_alive_detection_tid ( pthread_t tid)
static

Definition at line 1079 of file attack.c.

1080{
1081 alive_detection_tid = tid;
1082}

References alive_detection_tid.

Referenced by attack_network().

Here is the caller graph for this function:

◆ set_kb_readable()

void set_kb_readable ( int host_kb_index)
static

Add the Host KB index to the list of readable KBs used by ospd-openvas.

Parameters
host_kb_indexThe Kb index used for the host, to be stored in a list key in the main_kb.

Definition at line 118 of file attack.c.

119{
120 kb_t main_kb = NULL;
121
124 host_kb_index);
125 kb_lnk_reset (main_kb);
126}
int kb_item_add_int_unique_with_main_kb_check(kb_t kb, const char *name, int value)
Check if the current kb corresponds to the original scanid, if it matches it call kb_item_add_int_uni...
Definition plugutils.c:657

References connect_main_kb(), kb_item_add_int_unique_with_main_kb_check(), and main_kb.

Referenced by attack_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_scan_status()

void set_scan_status ( char * status)
static

Set scan status. This helps ospd-openvas to identify if a scan crashed or finished cleanly.

Parameters
[in]statusStatus to set.

Definition at line 135 of file attack.c.

136{
137 kb_t main_kb = NULL;
138 char buffer[96];
139 char *scan_id = NULL;
140
142
144 {
145 kb_lnk_reset (main_kb);
146 return;
147 }
148 scan_id = kb_item_get_str (main_kb, ("internal/scanid"));
149 snprintf (buffer, sizeof (buffer), "internal/%s", scan_id);
150 kb_item_set_str_with_main_kb_check (main_kb, buffer, status, 0);
151 kb_lnk_reset (main_kb);
152 g_free (scan_id);
153}
const char * scan_id
Definition scan_id.c:10

References check_kb_inconsistency(), connect_main_kb(), kb_item_set_str_with_main_kb_check(), main_kb, and scan_id.

Referenced by attack_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ vhosts_to_str()

char * vhosts_to_str ( GSList * list)
static

Definition at line 717 of file attack.c.

718{
719 GString *string;
720
721 if (!list)
722 return NULL;
723 string = g_string_new (((gvm_vhost_t *) list->data)->value);
724 if (g_slist_length (list) == 1)
725 return g_string_free (string, FALSE);
726 list = list->next;
727 while (list)
728 {
729 g_string_append (string, ", ");
730 g_string_append (string, ((gvm_vhost_t *) list->data)->value);
731 list = list->next;
732 }
733 return g_string_free (string, FALSE);
734}
struct list * next
Define a string struct for storing the response.

References list::next.

Referenced by attack_start().

Here is the caller graph for this function:

Variable Documentation

◆ alive_detection_tid

pthread_t alive_detection_tid
static

Definition at line 1076 of file attack.c.

Referenced by get_alive_detection_tid(), and set_alive_detection_tid().

◆ global_scan_stop

int global_scan_stop = 0

Definition at line 261 of file attack.c.

Referenced by handle_scan_stop_signal(), hosts_new(), hosts_stop_all(), and scan_is_stopped().

◆ host_kb

kb_t host_kb = NULL
static

Definition at line 290 of file attack.c.

Referenced by attack_host(), and check_duplicated_vhost().

◆ host_vhosts

GSList* host_vhosts = NULL
static

Definition at line 291 of file attack.c.

Referenced by append_vhost(), and attack_host().