OpenVAS Scanner 22.7.9
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 <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 int run_table_driven_lsc (const char *scan_id, kb_t kb, const char *ip_str, const char *hostname)
 Publish the necessary data to start a Table driven LSC scan.
 
static void process_ipc_data (const gchar *result)
 
static void read_ipc (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 void 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 ()
 
void attack_network (struct scan_globals *globals)
 Attack a whole network.
 

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 51 of file attack.c.

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "sd main"

GLib log domain.

Definition at line 67 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 61 of file attack.c.

◆ 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 57 of file attack.c.

◆ MAX_FORK_RETRIES

#define MAX_FORK_RETRIES   10

Definition at line 53 of file attack.c.

Function Documentation

◆ ad_thread_joined()

static 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 1179 of file attack.c.

1180{
1181 static gboolean alive_detection_thread_already_joined = FALSE;
1182 if (joined)
1183 alive_detection_thread_already_joined = TRUE;
1184 return alive_detection_thread_already_joined;
1185}

Referenced by attack_network(), and scan_stop_cleanup().

Here is the caller graph for this function:

◆ append_vhost()

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

Definition at line 293 of file attack.c.

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

References host_vhosts.

Referenced by process_ipc_data().

Here is the caller graph for this function:

◆ apply_hosts_excluded()

static void apply_hosts_excluded ( gvm_hosts_t *  hosts)
static

Definition at line 997 of file attack.c.

998{
999 const char *exclude_hosts = prefs_get ("exclude_hosts");
1000
1001 /* Exclude hosts ? */
1002 if (exclude_hosts)
1003 {
1004 /* Exclude hosts, resolving hostnames. */
1005 int ret = gvm_hosts_exclude (hosts, exclude_hosts);
1006
1007 if (ret > 0)
1008 g_message ("exclude_hosts: Skipped %d host(s).", ret);
1009 if (ret < 0)
1010 g_message ("exclude_hosts: Error.");
1011 }
1012}
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()

static void apply_hosts_preferences_ordering ( gvm_hosts_t *  hosts)
static

Definition at line 1064 of file attack.c.

1065{
1066 const char *ordering = prefs_get ("hosts_ordering");
1067
1068 /* Hosts ordering strategy: sequential, random, reversed... */
1069 if (ordering)
1070 {
1071 if (!strcmp (ordering, "random"))
1072 {
1073 gvm_hosts_shuffle (hosts);
1074 g_debug ("hosts_ordering: Random.");
1075 }
1076 else if (!strcmp (ordering, "reverse"))
1077 {
1078 gvm_hosts_reverse (hosts);
1079 g_debug ("hosts_ordering: Reverse.");
1080 }
1081 }
1082 else
1083 g_debug ("hosts_ordering: Sequential.");
1084}

References hosts.

Referenced by attack_network().

Here is the caller graph for this function:

◆ apply_hosts_reverse_lookup_preferences()

static int apply_hosts_reverse_lookup_preferences ( gvm_hosts_t *  hosts)
static

Definition at line 1087 of file attack.c.

1088{
1089#ifdef FEATURE_REVERSE_LOOKUP_EXCLUDED
1090 const char *exclude_hosts = prefs_get ("exclude_hosts");
1091 int hosts_excluded = 0;
1092
1093 if (prefs_get_bool ("reverse_lookup_unify"))
1094 {
1095 gvm_hosts_t *excluded;
1096
1097 excluded = gvm_hosts_reverse_lookup_unify_excluded (hosts);
1098 g_debug ("reverse_lookup_unify: Skipped %zu host(s).", excluded->count);
1099
1100 // Get the amount of hosts which are excluded now for this option,
1101 // but they are already in the exclude list.
1102 // This is to avoid issues with the scan progress calculation, since
1103 // the amount of excluded host could be duplicated.
1104 hosts_excluded += gvm_hosts_exclude (excluded, exclude_hosts);
1105
1106 gvm_hosts_free (excluded);
1107 }
1108
1109 if (prefs_get_bool ("reverse_lookup_only"))
1110 {
1111 gvm_hosts_t *excluded;
1112
1113 excluded = gvm_hosts_reverse_lookup_only_excluded (hosts);
1114 g_debug ("reverse_lookup_unify: Skipped %zu host(s).", excluded->count);
1115 // Get the amount of hosts which are excluded now for this option,
1116 // but they are already in the exclude list.
1117 // This is to avoid issues with the scan progress calculation, since
1118 // the amount of excluded host could be duplicated.
1119 hosts_excluded += gvm_hosts_exclude (excluded, exclude_hosts);
1120 gvm_hosts_free (excluded);
1121 }
1122 return exclude_hosts ? hosts_excluded : 0;
1123#else
1124 /* Reverse-lookup unify ? */
1125 if (prefs_get_bool ("reverse_lookup_unify"))
1126 g_debug ("reverse_lookup_unify: Skipped %d host(s).",
1127 gvm_hosts_reverse_lookup_unify (hosts));
1128
1129 /* Hosts that reverse-lookup only ? */
1130 if (prefs_get_bool ("reverse_lookup_only"))
1131 g_debug ("reverse_lookup_only: Skipped %d host(s).",
1132 gvm_hosts_reverse_lookup_only (hosts));
1133
1134 return 0;
1135#endif
1136}

References hosts.

Referenced by attack_network().

Here is the caller graph for this function:

◆ attack_host()

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

Attack one host.

Definition at line 630 of file attack.c.

632{
633 /* Used for the status */
634 int num_plugs, forks_retry = 0, all_plugs_launched = 0;
635 char ip_str[INET6_ADDRSTRLEN];
636 struct scheduler_plugin *plugin;
637 pid_t parent;
638
639 addr6_to_str (ip, ip_str);
640 host_kb = args->host_kb;
641 host_vhosts = args->host->vhosts;
642 globals->host_pid = getpid ();
643 host_set_time (get_main_kb (), ip_str, "HOST_START");
644 kb_lnk_reset (get_main_kb ());
645 setproctitle ("openvas: testing %s", ip_str);
646 kb_lnk_reset (args->host_kb);
647
648 /* launch the plugins */
649 pluginlaunch_init (ip_str);
650 num_plugs = plugins_scheduler_count_active (args->sched);
651 for (;;)
652 {
653 /* Check that our father is still alive */
654 parent = getppid ();
655 if (parent <= 1 || process_alive (parent) == 0)
656 {
658 return;
659 }
660
662 {
663 // We send the stop scan signal to the current parent process
664 // group, which is the main scan process and host processes.
665 // This avoid to attack new hosts and force the running host
666 // process to finish and spread the signal to the plugin processes
667 // To prevent duplicate results we don't let ACT_END run.
668 killpg (parent, SIGUSR1);
669 }
670
671 if (scan_is_stopped ())
673
674 plugin = plugins_scheduler_next (args->sched);
675 if (plugin != NULL && plugin != PLUG_RUNNING)
676 {
677 int e;
678 static int last_status = 0, cur_plug = 0;
679
680 again:
681 e = launch_plugin (globals, plugin, ip, host_vhosts, args);
682 if (e < 0)
683 {
684 /*
685 * Remote host died
686 */
687 if (e == ERR_HOST_DEAD)
688 {
689 char buffer[2048];
690
691 snprintf (
692 buffer, sizeof (buffer),
693 "LOG|||%s||| |||general/Host_Details||| |||<host><detail>"
694 "<name>Host dead</name><value>1</value><source>"
695 "<description/><type/><name/></source></detail></host>",
696 ip_str);
698 get_main_kb (), "internal/results", buffer);
699
701 goto host_died;
702 }
703 else if (e == ERR_NO_FREE_SLOT)
704 {
705 if (forks_retry < MAX_FORK_RETRIES)
706 {
707 forks_retry++;
708 g_warning ("Launch failed for %s. No free slot available "
709 "in the internal process table for starting a "
710 "plugin.",
711 plugin->oid);
712 fork_sleep (forks_retry);
713 goto again;
714 }
715 }
716 else if (e == ERR_CANT_FORK)
717 {
718 if (forks_retry < MAX_FORK_RETRIES)
719 {
720 forks_retry++;
721 g_warning (
722 "fork() failed for %s - sleeping %d seconds (%s)",
723 plugin->oid, forks_retry, strerror (errno));
724 fork_sleep (forks_retry);
725 goto again;
726 }
727 else
728 {
729 g_warning ("fork() failed too many times - aborting");
730 goto host_died;
731 }
732 }
733 }
734
735 if ((cur_plug * 100) / num_plugs >= last_status
736 && !scan_is_stopped ())
737 {
738 last_status = (cur_plug * 100) / num_plugs + 2;
739 if (comm_send_status (get_main_kb (), ip_str, cur_plug, num_plugs)
740 < 0)
741 goto host_died;
742 }
743 cur_plug++;
744 }
745 else if (plugin == NULL)
746 break;
747 else if (plugin != NULL && plugin == PLUG_RUNNING)
748 /* 50 milliseconds. */
749 usleep (50000);
751 }
752
753 if (!scan_is_stopped () && prefs_get_bool ("table_driven_lsc")
754 && prefs_get_bool ("mqtt_enabled"))
755 {
756 if (run_table_driven_lsc (globals->scan_id, args->host_kb, ip_str, NULL))
757 {
758 char buffer[2048];
759 snprintf (
760 buffer, sizeof (buffer),
761 "ERRMSG|||%s||| ||| ||| ||| Unable to launch table driven lsc",
762 ip_str);
764 "internal/results", buffer);
765 g_warning ("%s: Unable to launch table driven LSC", __func__);
766 }
767 }
768
770 if (!scan_is_stopped ())
771 {
772 int ret;
773 ret = comm_send_status (get_main_kb (), ip_str, num_plugs, num_plugs);
774 if (ret == 0)
775 all_plugs_launched = 1;
776 }
777
778host_died:
779 if (all_plugs_launched == 0 && !scan_is_stopped ())
780 g_message ("Vulnerability scan %s for host %s: not all plugins "
781 "were launched",
782 globals->scan_id, ip_str);
785 host_set_time (get_main_kb (), ip_str, "HOST_END");
786}
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:204
static int run_table_driven_lsc(const char *scan_id, kb_t kb, const char *ip_str, const char *hostname)
Publish the necessary data to start a Table driven LSC scan.
Definition: attack.c:331
static int scan_is_stopped(void)
Definition: attack.c:265
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:170
static void fork_sleep(int n)
Definition: attack.c:247
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:525
#define ERR_HOST_DEAD
Definition: attack.c:51
#define MAX_FORK_RETRIES
Definition: attack.c:53
static kb_t host_kb
Definition: attack.c:289
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)
Definition: pluginlaunch.c:315
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.
Definition: pluginlaunch.c:528
void pluginlaunch_stop(void)
Definition: pluginlaunch.c:352
void pluginlaunch_wait(kb_t main_kb, kb_t kb)
Waits and 'pushes' processes until num_running_processes is 0.
Definition: pluginlaunch.c:495
#define ERR_CANT_FORK
Error for when it is not possible to fork a new plugin process.
Definition: pluginlaunch.h:22
#define ERR_NO_FREE_SLOT
Error for when the process table is full.
Definition: pluginlaunch.h:26
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:478
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:387
plugins_scheduler_t sched
Definition: attack.c:78
gvm_host_t * host
Definition: attack.c:79
char * scan_id
Definition: scanneraux.h:22
pid_t host_pid
Definition: scanneraux.h:23
int process_alive(pid_t pid)
Definition: utils.c:195

References 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(), 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(), run_table_driven_lsc(), scan_globals::scan_id, scan_is_stopped(), and attack_start_args::sched.

Referenced by attack_start().

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

◆ attack_network()

void attack_network ( struct scan_globals globals)

Attack a whole network.

Definition at line 1247 of file attack.c.

1248{
1249 int max_hosts = 0, max_checks;
1250 const char *hostlist;
1251 gvm_host_t *host;
1252 plugins_scheduler_t sched;
1253 int fork_retries = 0;
1254 GHashTable *files;
1255 struct timeval then, now;
1256 gvm_hosts_t *hosts;
1257 const gchar *port_range;
1258 int allow_simultaneous_ips;
1259 kb_t arg_host_kb, main_kb;
1260 GSList *unresolved;
1261 char buf[96];
1262
1264
1265 gboolean test_alive_hosts_only = prefs_get_bool ("test_alive_hosts_only");
1266 gvm_hosts_t *alive_hosts_list = NULL;
1267 kb_t alive_hosts_kb = NULL;
1268 if (test_alive_hosts_only)
1269 connect_main_kb (&alive_hosts_kb);
1270
1271 gettimeofday (&then, NULL);
1272
1273 if (check_kb_access ())
1274 return;
1275
1276 /* Init and check Target List */
1277 hostlist = prefs_get ("TARGET");
1278 if (hostlist == NULL)
1279 {
1280 return;
1281 }
1282
1283 /* Verify the port range is a valid one */
1284 port_range = prefs_get ("port_range");
1285 if (validate_port_range (port_range))
1286 {
1289 main_kb, "Invalid port list. Ports must be in the range [1-65535]",
1290 NULL, NULL, "ERRMSG");
1291 kb_lnk_reset (main_kb);
1292 g_warning ("Invalid port list. Ports must be in the range [1-65535]. "
1293 "Scan terminated.");
1294 set_scan_status ("finished");
1295
1296 return;
1297 }
1298
1299 /* Initialize the attack. */
1300 int plugins_init_error = 0;
1301 sched = plugins_scheduler_init (prefs_get ("plugin_set"),
1302 prefs_get_bool ("auto_enable_dependencies"),
1303 &plugins_init_error);
1304 if (!sched)
1305 {
1306 g_message ("Couldn't initialize the plugin scheduler");
1307 return;
1308 }
1309
1310 if (plugins_init_error > 0)
1311 {
1312 sprintf (buf,
1313 "%d errors were found during the plugin scheduling. "
1314 "Some plugins have not been launched.",
1315 plugins_init_error);
1316
1318 message_to_client (main_kb, buf, NULL, NULL, "ERRMSG");
1319 kb_lnk_reset (main_kb);
1320 }
1321
1322 max_hosts = get_max_hosts_number ();
1323 max_checks = get_max_checks_number ();
1324
1325 hosts = gvm_hosts_new (hostlist);
1326 if (hosts == NULL)
1327 {
1328 char *buffer;
1329 buffer = g_strdup_printf ("Invalid target list: %s.", hostlist);
1331 message_to_client (main_kb, buffer, NULL, NULL, "ERRMSG");
1332 g_free (buffer);
1333 /* Send the hosts count to the client as -1,
1334 * because the invalid target list.*/
1336 "HOSTS_COUNT");
1337 kb_lnk_reset (main_kb);
1338 g_warning ("Invalid target list. Scan terminated.");
1339 goto stop;
1340 }
1341
1342 unresolved = gvm_hosts_resolve (hosts);
1343 while (unresolved)
1344 {
1345 g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
1346 unresolved = unresolved->next;
1347 }
1348 g_slist_free_full (unresolved, g_free);
1349
1350 /* Apply Hosts preferences. */
1352
1353 int already_excluded = 0;
1354 already_excluded = apply_hosts_reverse_lookup_preferences (hosts);
1355
1356#ifdef FEATURE_HOSTS_ALLOWED_ONLY
1357 // Remove hosts which are denied and/or keep the ones in the allowed host
1358 // lists
1359 // for both, user and system wide settings.
1360 apply_hosts_allow_deny (hosts);
1361#endif
1362
1363 /* Send the hosts count to the client, after removing duplicated and
1364 * unresolved hosts.*/
1365 sprintf (buf, "%d", gvm_hosts_count (hosts) + already_excluded);
1367 message_to_client (main_kb, buf, NULL, NULL, "HOSTS_COUNT");
1368 kb_lnk_reset (main_kb);
1369
1370 // Remove the excluded hosts
1372
1373 host = gvm_hosts_next (hosts);
1374 if (host == NULL)
1375 goto stop;
1376 hosts_init (max_hosts);
1377
1378 g_message ("Vulnerability scan %s started: Target has %d hosts: "
1379 "%s, with max_hosts = %d and max_checks = %d",
1380 globals->scan_id, gvm_hosts_count (hosts), hostlist, max_hosts,
1381 max_checks);
1382
1383 if (test_alive_hosts_only)
1384 {
1385 /* Boolean signalling if alive detection finished. */
1386 gboolean ad_finished = FALSE;
1387 int err;
1388 pthread_t tid;
1389 struct in6_addr tmpaddr;
1390
1391 /* Reset the iterator. */
1392 hosts->current = 0;
1393 err = pthread_create (&tid, NULL, start_alive_detection, (void *) hosts);
1394 if (err == EAGAIN)
1395 g_warning (
1396 "%s: pthread_create() returned EAGAIN: Insufficient resources "
1397 "to create thread.",
1398 __func__);
1400 g_debug ("%s: started alive detection.", __func__);
1401
1402 for (host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1403 !host && !ad_finished && !scan_is_stopped ();
1404 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1405 {
1406 fork_sleep (1);
1407 }
1408
1409 if (gvm_host_get_addr6 (host, &tmpaddr) == 0)
1410 host = gvm_host_find_in_hosts (host, &tmpaddr, hosts);
1411 if (host)
1412 {
1413 g_debug (
1414 "%s: Get first host to test from Queue. This host is used for "
1415 "initialising the alive_hosts_list.",
1416 __func__);
1417 }
1418 alive_hosts_list = gvm_hosts_new (gvm_host_value_str (host));
1419 }
1420
1421 /*
1422 * Start the attack !
1423 */
1424 allow_simultaneous_ips = prefs_get_bool ("allow_simultaneous_ips");
1426 while (host && !scan_is_stopped ())
1427 {
1428 int pid, rc;
1429 struct attack_start_args args;
1430 char *host_str;
1431
1432 if (!test_alive_hosts_only
1433 && (!allow_simultaneous_ips && host_is_currently_scanned (host)))
1434 {
1435 sleep (1);
1436 // move the host at the end of the list and get the next host.
1437 gvm_hosts_move_current_host_to_end (hosts);
1438 host = gvm_hosts_next (hosts);
1439 continue;
1440 }
1441
1442 do
1443 {
1444 rc = kb_new (&arg_host_kb, prefs_get ("db_address"));
1445 if (rc < 0 && rc != -2)
1446 {
1447 report_kb_failure (rc);
1448 goto scan_stop;
1449 }
1450 else if (rc == -2)
1451 {
1452 sleep (KB_RETRY_DELAY);
1453 continue;
1454 }
1455 break;
1456 }
1457 while (1);
1458
1459 host_str = gvm_host_value_str (host);
1461 if (hosts_new (host_str, arg_host_kb, main_kb) < 0)
1462 {
1463 kb_delete (arg_host_kb);
1464 g_free (host_str);
1465 goto scan_stop;
1466 }
1467
1468 if (scan_is_stopped ())
1469 {
1470 kb_delete (arg_host_kb);
1471 g_free (host_str);
1472 continue;
1473 }
1474
1475 args.host = host;
1476 args.globals = globals;
1477 args.sched = sched;
1478 args.host_kb = arg_host_kb;
1479
1480 forkagain:
1482 /* Close child process' socket. */
1483 if (pid < 0)
1484 {
1485 fork_retries++;
1486 if (fork_retries > MAX_FORK_RETRIES)
1487 {
1488 /* Forking failed - we go to the wait queue. */
1489 g_warning ("fork() failed - %s. %s won't be tested",
1490 strerror (errno), host_str);
1491 g_free (host_str);
1492 goto stop;
1493 }
1494
1495 g_debug ("fork() failed - "
1496 "sleeping %d seconds and trying again...",
1497 fork_retries);
1498 fork_sleep (fork_retries);
1499 goto forkagain;
1500 }
1501 hosts_set_pid (host_str, pid);
1502
1503 if (test_alive_hosts_only)
1504 {
1505 struct in6_addr tmpaddr;
1506 gvm_host_t *alive_buf;
1507
1508 while (1)
1509 {
1510 /* Boolean signalling if alive detection finished. */
1511 gboolean ad_finished = FALSE;
1512 for (host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1513 !host && !ad_finished && !scan_is_stopped ();
1514 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1515 {
1516 fork_sleep (1);
1517 }
1518
1519 if (host && !allow_simultaneous_ips
1521 {
1522 struct in6_addr hostip;
1523 char ip_str[INET6_ADDRSTRLEN];
1524 int flag_set;
1525
1526 gvm_host_get_addr6 (host, &hostip);
1527 addr6_to_str (&hostip, ip_str);
1528
1529 // Re-add host at the end of the queue and reallocate the flag
1530 // if it was already set.
1531 flag_set = finish_signal_on_queue (alive_hosts_kb);
1532
1533 put_host_on_queue (alive_hosts_kb, ip_str);
1534 g_debug ("Reallocating the host %s at the end of the queue",
1535 ip_str);
1536
1537 gvm_host_free (host);
1538 host = NULL;
1539
1540 if (flag_set)
1541 {
1542 g_debug ("Reallocating finish signal in the host queue");
1543 realloc_finish_signal_on_queue (alive_hosts_kb);
1544 }
1545 }
1546 else
1547 break;
1548 }
1549
1550 if (host && gvm_host_get_addr6 (host, &tmpaddr) == 0)
1551 {
1552 alive_buf = host;
1553 host = gvm_host_find_in_hosts (host, &tmpaddr, hosts);
1554 gvm_host_free (alive_buf);
1555 alive_buf = NULL;
1556 }
1557
1558 if (host)
1559 gvm_hosts_add (alive_hosts_list, gvm_duplicate_host (host));
1560 else
1561 g_debug ("%s: got NULL host, stop/finish scan", __func__);
1562 }
1563 else
1564 {
1565 host = gvm_hosts_next (hosts);
1566 }
1567 g_free (host_str);
1568 }
1569
1570 /* Every host is being tested... We have to wait for the processes
1571 * to terminate. */
1572 while (hosts_read () == 0)
1573 if (scan_is_stopped () == 1)
1574 killpg (getpid (), SIGUSR1);
1575
1576 g_debug ("Test complete");
1577
1578scan_stop:
1579 /* Free the memory used by the files uploaded by the user, if any. */
1580 files = globals->files_translation;
1581 if (files)
1582 g_hash_table_destroy (files);
1583
1584stop:
1585
1586 if (test_alive_hosts_only)
1587 {
1588 int err;
1589 void *retval;
1590
1591 kb_lnk_reset (alive_hosts_kb);
1592 g_debug ("%s: free alive detection data ", __func__);
1593
1594 /* need to wait for alive detection to finish */
1595 g_debug ("%s: waiting for alive detection thread to be finished...",
1596 __func__);
1597 /* Join alive detection thread. */
1598 err = pthread_join (get_alive_detection_tid (), &retval);
1599 if (err == EDEADLK)
1600 g_debug ("%s: pthread_join() returned EDEADLK.", __func__);
1601 if (err == EINVAL)
1602 g_debug ("%s: pthread_join() returned EINVAL.", __func__);
1603 if (err == ESRCH)
1604 g_debug ("%s: pthread_join() returned ESRCH.", __func__);
1605 if (retval == PTHREAD_CANCELED)
1606 g_debug ("%s: pthread_join() returned PTHREAD_CANCELED.", __func__);
1607 /* Set flag signaling that alive deteciton thread was joined. */
1608 if (err == 0)
1609 ad_thread_joined (TRUE);
1610 g_debug ("%s: Finished waiting for alive detection thread.", __func__);
1611 }
1612
1613 plugins_scheduler_free (sched);
1614
1615 gettimeofday (&now, NULL);
1616 if (test_alive_hosts_only)
1617 g_message ("Vulnerability scan %s finished in %ld seconds: "
1618 "%d alive hosts of %d",
1619 globals->scan_id, now.tv_sec - then.tv_sec,
1620 gvm_hosts_count (alive_hosts_list), gvm_hosts_count (hosts));
1621 else
1622 g_message ("Vulnerability scan %s finished in %ld seconds: %d hosts",
1623 globals->scan_id, now.tv_sec - then.tv_sec,
1624 gvm_hosts_count (hosts));
1625
1626 gvm_hosts_free (hosts);
1627 if (alive_hosts_list)
1628 gvm_hosts_free (alive_hosts_list);
1629
1630 set_scan_status ("finished");
1631}
static void apply_hosts_excluded(gvm_hosts_t *hosts)
Definition: attack.c:997
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:917
static int apply_hosts_reverse_lookup_preferences(gvm_hosts_t *hosts)
Definition: attack.c:1087
static void handle_scan_stop_signal()
Definition: attack.c:1188
static void set_alive_detection_tid(pthread_t tid)
Definition: attack.c:1157
static void check_deprecated_prefs(void)
Check if any deprecated prefs are in pref table and print warning.
Definition: attack.c:819
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:95
static void report_kb_failure(int errcode)
Definition: attack.c:235
static int check_kb_access(void)
Definition: attack.c:1139
static void apply_hosts_preferences_ordering(gvm_hosts_t *hosts)
Definition: attack.c:1064
#define INVALID_TARGET_LIST
Definition: attack.c:61
static void message_to_client(kb_t kb, const char *msg, const char *ip_str, const char *port, const char *type)
Definition: attack.c:222
#define KB_RETRY_DELAY
Definition: attack.c:57
static gboolean ad_thread_joined(gboolean joined)
Set and get if alive detection thread was already joined by main thread.
Definition: attack.c:1179
static pthread_t get_alive_detection_tid()
Definition: attack.c:1162
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:134
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
Definition: nasl_cmd_exec.c:39
plugins_scheduler_t plugins_scheduler_init(const char *plugins_list, int autoload, int *error)
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:75
Host information, implemented as doubly linked list.
Definition: hosts.c:37
GHashTable * files_translation
Definition: scanneraux.h:20
int get_max_hosts_number(void)
Definition: utils.c:134
int get_max_checks_number(void)
Definition: utils.c:165

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(), scan_globals::files_translation, 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(), and timeval().

Referenced by openvas().

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

◆ attack_start()

static 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 917 of file attack.c.

918{
919 struct scan_globals *globals = args->globals;
920 char ip_str[INET6_ADDRSTRLEN], *hostnames;
921 struct in6_addr hostip;
922 struct timeval then;
923 kb_t kb = args->host_kb;
924 kb_t main_kb = get_main_kb ();
925 int ret;
926 args->ipc_context = ipcc;
927
928 nvticache_reset ();
929 kb_lnk_reset (kb);
930 kb_lnk_reset (main_kb);
931 gettimeofday (&then, NULL);
932
933 kb_item_set_str_with_main_kb_check (kb, "internal/scan_id", globals->scan_id,
934 0);
935 set_kb_readable (kb_get_kb_index (kb));
936
937 /* The reverse lookup is delayed to this step in order to not slow down the
938 * main scan process eg. case of target with big range of IP addresses. */
939 if (prefs_get_bool ("expand_vhosts"))
940 gvm_host_add_reverse_lookup (args->host);
941 if ((ret = gvm_vhosts_exclude (args->host, prefs_get ("exclude_hosts"))) > 0)
942 g_message ("exclude_hosts: Skipped %d vhost(s).", ret);
943 gvm_host_get_addr6 (args->host, &hostip);
944 addr6_to_str (&hostip, ip_str);
945
946#ifndef FEATURE_HOSTS_ALLOWED_ONLY
947 int ret_host_auth = check_host_authorization (args->host, &hostip);
948 if (ret_host_auth < 0)
949 {
950 if (ret_host_auth == -1)
951 message_to_client (kb, "Host access denied.", ip_str, NULL, "ERRMSG");
952 else
953 message_to_client (kb, "Host access denied (system-wide restriction.)",
954 ip_str, NULL, "ERRMSG");
955
956 kb_item_set_str_with_main_kb_check (kb, "internal/host_deny", "True", 0);
957 g_warning ("Host %s access denied.", ip_str);
958 return;
959 }
960#endif
961
962 if (prefs_get_bool ("test_empty_vhost"))
963 {
964 gvm_vhost_t *vhost =
965 gvm_vhost_new (g_strdup (ip_str), g_strdup ("IP-address"));
966 args->host->vhosts = g_slist_prepend (args->host->vhosts, vhost);
967 }
968 hostnames = vhosts_to_str (args->host->vhosts);
969 if (hostnames)
970 g_message ("Vulnerability scan %s started for host: %s (Vhosts: %s)",
971 globals->scan_id, ip_str, hostnames);
972 else
973 g_message ("Vulnerability scan %s started for host: %s", globals->scan_id,
974 ip_str);
975 g_free (hostnames);
976 attack_host (globals, &hostip, args);
977 kb_lnk_reset (main_kb);
978
979 if (!scan_is_stopped ())
980 {
981 struct timeval now;
982
983 gettimeofday (&now, NULL);
984 if (now.tv_usec < then.tv_usec)
985 {
986 then.tv_sec++;
987 now.tv_usec += 1000000;
988 }
989 g_message (
990 "Vulnerability scan %s finished for host %s in %ld.%.2ld seconds",
991 globals->scan_id, ip_str, (long) (now.tv_sec - then.tv_sec),
992 (long) ((now.tv_usec - then.tv_usec) / 10000));
993 }
994}
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:117
static int check_host_authorization(gvm_host_t *host, const struct in6_addr *addr)
Definition: attack.c:888
static void attack_host(struct scan_globals *globals, struct in6_addr *ip, struct attack_start_args *args)
Attack one host.
Definition: attack.c:630
static char * vhosts_to_str(GSList *list)
Definition: attack.c:796
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:503
static struct ipc_contexts * ipcc
Definition: processes.c:39
struct ipc_context * ipc_context
Definition: attack.c:77

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:

◆ check_deprecated_prefs()

static void check_deprecated_prefs ( void  )
static

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

Definition at line 819 of file attack.c.

820{
821 const gchar *source_iface = prefs_get ("source_iface");
822 const gchar *ifaces_allow = prefs_get ("ifaces_allow");
823 const gchar *ifaces_deny = prefs_get ("ifaces_deny");
824 const gchar *sys_ifaces_allow = prefs_get ("sys_ifaces_allow");
825 const gchar *sys_ifaces_deny = prefs_get ("sys_ifaces_deny");
826
827 if (source_iface || ifaces_allow || ifaces_deny || sys_ifaces_allow
828 || sys_ifaces_deny)
829 {
830 kb_t main_kb = NULL;
831 gchar *msg = NULL;
832
833 msg = g_strdup_printf (
834 "The following provided settings are deprecated since the 22.4 "
835 "release and will be ignored: %s%s%s%s%s",
836 source_iface ? "source_iface (task setting) " : "",
837 ifaces_allow ? "ifaces_allow (user setting) " : "",
838 ifaces_deny ? "ifaces_deny (user setting) " : "",
839 sys_ifaces_allow ? "sys_ifaces_allow (scanner only setting) " : "",
840 sys_ifaces_deny ? "sys_ifaces_deny (scanner only setting)" : "");
841 g_warning ("%s: %s", __func__, msg);
842
844 message_to_client (main_kb, msg, NULL, NULL, "ERRMSG");
845 kb_lnk_reset (main_kb);
846 g_free (msg);
847 }
848}

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()

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

Definition at line 888 of file attack.c.

889{
890 gvm_hosts_t *hosts_allow, *hosts_deny;
891 gvm_hosts_t *sys_hosts_allow, *sys_hosts_deny;
892
893 /* Do we have the right to test this host ? */
894 hosts_allow = gvm_hosts_new (prefs_get ("hosts_allow"));
895 hosts_deny = gvm_hosts_new (prefs_get ("hosts_deny"));
896 if (!host_authorized (host, addr, hosts_allow, hosts_deny))
897 return -1;
898
899 sys_hosts_allow = gvm_hosts_new (prefs_get ("sys_hosts_allow"));
900 sys_hosts_deny = gvm_hosts_new (prefs_get ("sys_hosts_deny"));
901 if (!host_authorized (host, addr, sys_hosts_allow, sys_hosts_deny))
902 return -2;
903
904 gvm_hosts_free (hosts_allow);
905 gvm_hosts_free (hosts_deny);
906 gvm_hosts_free (sys_hosts_allow);
907 gvm_hosts_free (sys_hosts_deny);
908 return 0;
909}
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:863

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()

static int check_kb_access ( void  )
static

Definition at line 1139 of file attack.c.

1140{
1141 int rc;
1142 kb_t kb;
1143
1144 rc = kb_new (&kb, prefs_get ("db_address"));
1145 if (rc)
1146 report_kb_failure (rc);
1147 else
1148 kb_delete (kb);
1149
1150 return rc;
1151}

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()

static 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 204 of file attack.c.

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

References kb_item_push_str_with_main_kb_check(), main_kb, and max.

Referenced by attack_host(), and Ensure().

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

◆ comm_send_status_host_dead()

static 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 170 of file attack.c.

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

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()

static 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 95 of file attack.c.

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

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()

static void fork_sleep ( int  n)
static

Definition at line 247 of file attack.c.

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

Referenced by attack_host(), and attack_network().

Here is the caller graph for this function:

◆ get_alive_detection_tid()

static pthread_t get_alive_detection_tid ( )
static

Definition at line 1162 of file attack.c.

1163{
1164 return alive_detection_tid;
1165}
static pthread_t alive_detection_tid
Definition: attack.c:1154

References alive_detection_tid.

Referenced by attack_network(), and scan_stop_cleanup().

Here is the caller graph for this function:

◆ handle_scan_stop_signal()

static void handle_scan_stop_signal ( )
static

Definition at line 1188 of file attack.c.

1189{
1190 global_scan_stop = 1;
1191}
int global_scan_stop
Definition: attack.c:260

References global_scan_stop.

Referenced by attack_network().

Here is the caller graph for this function:

◆ host_authorized()

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

Definition at line 863 of file attack.c.

865{
866 /* Check Hosts Access. */
867 if (host == NULL)
868 return 0;
869
870 if (hosts_deny && gvm_host_in_hosts (host, addr, hosts_deny))
871 return 0;
872 if (hosts_allow && !gvm_host_in_hosts (host, addr, hosts_allow))
873 return 0;
874
875 return 1;
876}

Referenced by check_host_authorization().

Here is the caller graph for this function:

◆ launch_plugin()

static 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 525 of file attack.c.

528{
529 int optimize = prefs_get_bool ("optimize_test");
530 int launch_error, pid, ret = 0;
531 char *oid, *name, *error = NULL, ip_str[INET6_ADDRSTRLEN];
532 nvti_t *nvti;
533
534 kb_lnk_reset (get_main_kb ());
535 addr6_to_str (ip, ip_str);
536 oid = plugin->oid;
537 nvti = nvticache_get_nvt (oid);
538
539 /* eg. When NVT was moved/removed by a feed update during the scan. */
540 if (!nvti)
541 {
542 g_message ("Plugin '%s' missing from nvticache.", oid);
544 goto finish_launch_plugin;
545 }
546 if (scan_is_stopped ())
547 {
549 goto finish_launch_plugin;
550 }
551
552 if (prefs_get_bool ("safe_checks")
553 && !nvti_category_is_safe (nvti_category (nvti)))
554 {
555 if (prefs_get_bool ("log_whole_attack"))
556 {
557 name = nvticache_get_filename (oid);
558 g_message ("Not launching %s (%s) against %s because safe checks are"
559 " enabled (this is not an error)",
560 name, oid, ip_str);
561 g_free (name);
562 }
564 goto finish_launch_plugin;
565 }
566
567 /* Do not launch NVT if mandatory key is missing (e.g. an important tool
568 * was not found). */
569 if (!mandatory_requirements_met (args->host_kb, nvti))
570 error = "because a mandatory key is missing";
571 if (error
572 || (optimize && (error = requirements_plugin (args->host_kb, nvti))))
573 {
575 if (prefs_get_bool ("log_whole_attack"))
576 {
577 name = nvticache_get_filename (oid);
578 g_message (
579 "Not launching %s (%s) against %s %s (this is not an error)", name,
580 oid, ip_str, error);
581 g_free (name);
582 }
583 goto finish_launch_plugin;
584 }
585
586 /* Stop the test if the host is 'dead' */
587 if (kb_item_get_int (args->host_kb, "Host/dead") > 0)
588 {
589 g_message ("The remote host %s is dead", ip_str);
592 ret = ERR_HOST_DEAD;
593 goto finish_launch_plugin;
594 }
595
596 /* Update vhosts list and start the plugin */
597 if (procs_get_ipc_contexts () != NULL)
598 {
599 for (int i = 0; i < procs_get_ipc_contexts ()->len; i++)
600 {
601 read_ipc (&procs_get_ipc_contexts ()->ctxs[i]);
602 }
603 }
604 launch_error = 0;
605 pid = plugin_launch (globals, plugin, ip, vhosts, args->host_kb,
606 get_main_kb (), nvti, &launch_error);
607 if (launch_error == ERR_NO_FREE_SLOT || launch_error == ERR_CANT_FORK)
608 {
610 ret = launch_error;
611 goto finish_launch_plugin;
612 }
613
614 if (prefs_get_bool ("log_whole_attack"))
615 {
616 name = nvticache_get_filename (oid);
617 g_message ("Launching %s (%s) against %s [%d]", name, oid, ip_str, pid);
618 g_free (name);
619 }
620
621finish_launch_plugin:
622 nvti_free (nvti);
623 return ret;
624}
static int nvti_category_is_safe(int category)
Checks that an NVT category is safe.
Definition: attack.c:280
static void read_ipc(struct ipc_context *ctx)
Definition: attack.c:491
const char * oid
const char * name
Definition: nasl_init.c:411
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.
Definition: pluginlaunch.c:458
@ 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()

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

Definition at line 222 of file attack.c.

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

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()

static 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 280 of file attack.c.

281{
282 /* XXX: Duplicated from openvas/nasl. */
283 if (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST
284 || category == ACT_FLOOD || category == ACT_DENIAL)
285 return 0;
286 return 1;
287}
@ 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().

Here is the caller graph for this function:

◆ process_ipc_data()

static void process_ipc_data ( const gchar *  result)
static

Definition at line 454 of file attack.c.

455{
456 ipc_data_t *idata;
457
458 if ((idata = ipc_data_from_json (result, strlen (result))) != NULL)
459 {
460 switch (ipc_get_data_type_from_data (idata))
461 {
462 case IPC_DT_ERROR:
463 g_warning ("%s: Unknown data type.", __func__);
464 break;
465 case IPC_DT_HOSTNAME:
466 if (ipc_get_hostname_from_data (idata) == NULL)
467 g_warning ("%s: ihost data is NULL ignoring new vhost", __func__);
468 else
471 break;
473 if (ipc_get_user_agent_from_data (idata) == NULL)
474 g_warning ("%s: iuser_agent data is NULL, ignoring new user agent",
475 __func__);
476 else
477 {
478 gchar *old_ua = NULL;
480 g_debug ("%s: The User-Agent %s has been overwritten with %s",
481 __func__, old_ua, ipc_get_user_agent_from_data (idata));
482 g_free (old_ua);
483 }
484 break;
485 }
486 ipc_data_destroy (&idata);
487 }
488}
static void append_vhost(const char *vhost, const char *source)
Definition: attack.c:293
gchar * ipc_get_hostname_from_data(ipc_data_t *data)
Get the hostname from IPC data.
Definition: ipc_openvas.c:73
enum ipc_data_type ipc_get_data_type_from_data(ipc_data_t *data)
Get the data type in data.
Definition: ipc_openvas.c:58
void ipc_data_destroy(ipc_data_t **data)
destroys ipc_data.
Definition: ipc_openvas.c:224
gchar * ipc_get_user_agent_from_data(ipc_data_t *data)
Get the User-Agent from IPC data.
Definition: ipc_openvas.c:105
struct ipc_data * ipc_data_from_json(const char *json, size_t len)
transforms json string to a ipc_data struct
Definition: ipc_openvas.c:319
gchar * ipc_get_hostname_source_from_data(ipc_data_t *data)
Get the vhost hostname source from IPC data.
Definition: ipc_openvas.c:89
@ IPC_DT_HOSTNAME
Definition: ipc_openvas.h:17
@ IPC_DT_USER_AGENT
Definition: ipc_openvas.h:18
@ IPC_DT_ERROR
Definition: ipc_openvas.h:16
gchar * user_agent_set(const gchar *ua)
Set user-agent.
Definition: user_agent.c:85

References append_vhost(), ipc_data_destroy(), ipc_data_from_json(), IPC_DT_ERROR, IPC_DT_HOSTNAME, IPC_DT_USER_AGENT, ipc_get_data_type_from_data(), ipc_get_hostname_from_data(), ipc_get_hostname_source_from_data(), ipc_get_user_agent_from_data(), 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()

static void read_ipc ( struct ipc_context ctx)
static

Definition at line 491 of file attack.c.

492{
493 char *results;
494
495 while ((results = ipc_retrieve (ctx, IPC_MAIN)) != NULL)
496 {
497 int len = 0;
498 int pos = 0;
499 for (int j = 0; results[j] != '\0'; j++)
500 if (results[j] == '}')
501 {
502 gchar *message = NULL;
503 len = j - pos + 1;
504 message = g_malloc0 (sizeof (gchar) * (len + 1));
505 memcpy (message, &results[pos], len);
506 pos = j + 1;
507 len = 0;
508 process_ipc_data (message);
509 g_free (message);
510 }
511 }
512 g_free (results);
513}
static void process_ipc_data(const gchar *result)
Definition: attack.c:454
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_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()

static void report_kb_failure ( int  errcode)
static

Definition at line 235 of file attack.c.

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

Referenced by attack_network(), and check_kb_access().

Here is the caller graph for this function:

◆ run_table_driven_lsc()

static int run_table_driven_lsc ( const char *  scan_id,
kb_t  kb,
const char *  ip_str,
const char *  hostname 
)
static

Publish the necessary data to start a Table driven LSC scan.

If the gather-package-list.nasl plugin was launched, and it generated a valid package list for a supported OS, the table driven LSC scan which is subscribed to the topic will perform a scan an publish the the results to be handle by the sensor/client.

Parameters
scan_idScan Id.
kb
ip_strIP string of host.
hostnameName of host.
Returns
0 on success, less than 0 on error.

Definition at line 331 of file attack.c.

333{
334 gchar *json_str;
335 gchar *package_list;
336 gchar *os_release;
337 gchar *topic;
338 gchar *payload;
339 gchar *status = NULL;
340 int topic_len;
341 int payload_len;
342 int err = 0;
343
344 // Subscribe to status topic
345 err = mqtt_subscribe ("scanner/status");
346 if (err)
347 {
348 g_warning ("%s: Error starting lsc. Unable to subscribe", __func__);
349 return -1;
350 }
351 /* Get the OS release. TODO: have a list with supported OS. */
352
353 os_release = kb_item_get_str (kb, "ssh/login/release_notus");
354 /* Get the package list. Currently only rpm support */
355 package_list = kb_item_get_str (kb, "ssh/login/package_list_notus");
356 if (!os_release || !package_list)
357 return 0;
358
360 os_release, package_list);
361 g_free (package_list);
362 g_free (os_release);
363
364 // Run table driven lsc
365 if (json_str == NULL)
366 return -1;
367
368 g_message ("Running Notus for %s", ip_str);
369 err = mqtt_publish ("scanner/package/cmd/notus", json_str);
370 if (err)
371 {
372 g_warning ("%s: Error publishing message for Notus.", __func__);
373 g_free (json_str);
374 return -1;
375 }
376
377 g_free (json_str);
378
379 // Wait for Notus scanner to start or interrupt
380 while (!status)
381 {
382 err = mqtt_retrieve_message (&topic, &topic_len, &payload, &payload_len,
383 60000);
384 if (err == -1 || err == 1)
385 {
386 g_warning ("%s: Unable to retrieve status message from notus. %s",
387 __func__, err == 1 ? "Timeout after 60 s." : "");
388 return -1;
389 }
390
391 // Get status if it belongs to corresponding scan and host
392 // Else wait for next status message
394 payload, payload_len);
395
396 g_free (topic);
397 g_free (payload);
398 }
399 // If started wait for it to finish or interrupt
400 if (!g_strcmp0 (status, "running"))
401 {
402 g_debug ("%s: table driven LSC with scan id %s successfully started "
403 "for host %s",
404 __func__, scan_id, ip_str);
405 g_free (status);
406 status = NULL;
407 while (!status)
408 {
409 err = mqtt_retrieve_message (&topic, &topic_len, &payload,
410 &payload_len, 60000);
411 if (err == -1)
412 {
413 g_warning ("%s: Unable to retrieve status message from notus.",
414 __func__);
415 return -1;
416 }
417 if (err == 1)
418 {
419 g_warning ("%s: Unablet to retrieve message. Timeout after 60s.",
420 __func__);
421 return -1;
422 }
423
425 scan_id, ip_str, payload, payload_len);
426 g_free (topic);
427 g_free (payload);
428 }
429 }
430 else
431 {
432 g_warning ("%s: Unable to start lsc. Got status: %s", __func__, status);
433 g_free (status);
434 return -1;
435 }
436
437 if (g_strcmp0 (status, "finished"))
438 {
439 g_warning (
440 "%s: table driven lsc with scan id %s did not finish successfully "
441 "for host %s. Last status was %s",
442 __func__, scan_id, ip_str, status);
443 err = -1;
444 }
445 else
446 g_debug ("%s: table driven lsc with scan id %s successfully finished "
447 "for host %s",
448 __func__, scan_id, ip_str);
449 g_free (status);
450 return err;
451}
u_char * payload
const char * hostname
Definition: pluginlaunch.c:68
const char * scan_id
Definition: scan_id.c:10
gchar * get_status_of_table_driven_lsc_from_json(const char *scan_id, const char *host_ip, const char *json, int len)
Get the status of table driven lsc from json object.
gchar * make_table_driven_lsc_info_json_str(const char *scan_id, const char *ip_str, const char *hostname, const char *os_release, const char *package_list)
Build a json object with data necessary to start a table drive LSC.

References get_status_of_table_driven_lsc_from_json(), hostname, make_table_driven_lsc_info_json_str(), payload, and scan_id.

Referenced by attack_host().

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

◆ scan_is_stopped()

static int scan_is_stopped ( void  )
static

Definition at line 265 of file attack.c.

266{
267 if (global_scan_stop == 1)
269 return global_scan_stop;
270}
static void scan_stop_cleanup(void)
Definition: attack.c:1194

References global_scan_stop, and scan_stop_cleanup().

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

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

◆ scan_stop_cleanup()

static void scan_stop_cleanup ( void  )
static

Definition at line 1194 of file attack.c.

1195{
1196 kb_t main_kb = NULL;
1197 char *pid;
1198 static int already_called = 0;
1199
1200 if (already_called == 1)
1201 return;
1202
1204 pid = kb_item_get_str (main_kb, ("internal/ovas_pid"));
1205 kb_lnk_reset (main_kb);
1206
1207 /* Stop all hosts and alive detection (if enabled) if we are in main.
1208 * Else stop all running plugin processes for the current host fork. */
1209 if (pid && (atoi (pid) == getpid ()))
1210 {
1211 already_called = 1;
1212 hosts_stop_all ();
1213
1214 /* Stop (cancel) alive detection if enabled and not already joined. */
1215 if (prefs_get_bool ("test_alive_hosts_only"))
1216 {
1217 /* Alive detection thread was already joined by main thread. */
1218 if (TRUE == ad_thread_joined (FALSE))
1219 {
1220 g_warning (
1221 "Alive detection thread was already joined by other "
1222 "thread. Cancel operation not permitted or not needed.");
1223 }
1224 else
1225 {
1226 int err;
1227 err = pthread_cancel (get_alive_detection_tid ());
1228 if (err == ESRCH)
1229 g_warning (
1230 "%s: pthread_cancel() returned ESRCH; No thread with the "
1231 "supplied ID could be found.",
1232 __func__);
1233 }
1234 }
1235 }
1236 else
1237 /* Current host process */
1239
1240 g_free (pid);
1241}
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()

static void set_alive_detection_tid ( pthread_t  tid)
static

Definition at line 1157 of file attack.c.

1158{
1159 alive_detection_tid = tid;
1160}

References alive_detection_tid.

Referenced by attack_network().

Here is the caller graph for this function:

◆ set_kb_readable()

static 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 117 of file attack.c.

118{
119 kb_t main_kb = NULL;
120
123 host_kb_index);
124 kb_lnk_reset (main_kb);
125}
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:602

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()

static 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 134 of file attack.c.

135{
136 kb_t main_kb = NULL;
137 char buffer[96];
138 char *scan_id = NULL;
139
141
143 {
144 kb_lnk_reset (main_kb);
145 return;
146 }
147 scan_id = kb_item_get_str (main_kb, ("internal/scanid"));
148 snprintf (buffer, sizeof (buffer), "internal/%s", scan_id);
149 kb_item_set_str_with_main_kb_check (main_kb, buffer, status, 0);
150 kb_lnk_reset (main_kb);
151 g_free (scan_id);
152}

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()

static char * vhosts_to_str ( GSList *  list)
static

Definition at line 796 of file attack.c.

797{
798 GString *string;
799
800 if (!list)
801 return NULL;
802 string = g_string_new (((gvm_vhost_t *) list->data)->value);
803 if (g_slist_length (list) == 1)
804 return g_string_free (string, FALSE);
805 list = list->next;
806 while (list)
807 {
808 g_string_append (string, ", ");
809 g_string_append (string, ((gvm_vhost_t *) list->data)->value);
810 list = list->next;
811 }
812 return g_string_free (string, FALSE);
813}
struct list * next

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 1154 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 260 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 289 of file attack.c.

Referenced by attack_host(), and check_duplicated_vhost().

◆ host_vhosts

GSList* host_vhosts = NULL
static

Definition at line 290 of file attack.c.

Referenced by append_vhost(), and attack_host().