OpenVAS Scanner 23.43.1
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/boreas/cli.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 53 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 69 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 63 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 59 of file attack.c.

Referenced by attack_network().

◆ MAX_FORK_RETRIES

#define MAX_FORK_RETRIES   10

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

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

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

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

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

918{
919 const char *exclude_hosts = prefs_get ("exclude_hosts");
920 int ret = 0;
921 /* Exclude hosts ? */
922 if (exclude_hosts)
923 {
924 /* Exclude hosts, resolving hostnames. */
925 ret = gvm_hosts_exclude (hosts, exclude_hosts);
926
927 if (ret > 0)
928 g_message ("exclude_hosts: Skipped %d host(s).", ret);
929 if (ret < 0)
930 g_message ("exclude_hosts: Error.");
931 }
932 return ret;
933}
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 985 of file attack.c.

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

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

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

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

559{
560 /* Used for the status */
561 int num_plugs, forks_retry = 0, all_plugs_launched = 0;
562 char ip_str[INET6_ADDRSTRLEN];
563 struct scheduler_plugin *plugin;
564 pid_t parent;
565
566 addr6_to_str (ip, ip_str);
567 host_kb = args->host_kb;
568 host_vhosts = args->host->vhosts;
569 globals->host_pid = getpid ();
570 host_set_time (get_main_kb (), ip_str, "HOST_START");
571 kb_lnk_reset (get_main_kb ());
572 setproctitle ("openvas: testing %s", ip_str);
573 kb_lnk_reset (args->host_kb);
574
575 /* launch the plugins */
576 pluginlaunch_init (ip_str);
577 num_plugs = plugins_scheduler_count_active (args->sched);
578 for (;;)
579 {
580 /* Check that our father is still alive */
581 parent = getppid ();
582 if (parent <= 1 || process_alive (parent) == 0)
583 {
585 return;
586 }
587
589 {
590 // We send the stop scan signal to the current parent process
591 // group, which is the main scan process and host processes.
592 // This avoid to attack new hosts and force the running host
593 // process to finish and spread the signal to the plugin processes
594 // To prevent duplicate results we don't let ACT_END run.
595 killpg (parent, SIGUSR1);
596 }
597
598 if (scan_is_stopped ())
600
601 plugin = plugins_scheduler_next (args->sched);
602 if (plugin != NULL && plugin != PLUG_RUNNING)
603 {
604 int e;
605 static int last_status = 0, cur_plug = 0;
606
607 again:
608 e = launch_plugin (globals, plugin, ip, host_vhosts, args);
609 if (e < 0)
610 {
611 /*
612 * Remote host died
613 */
614 if (e == ERR_HOST_DEAD)
615 {
616 char buffer[2048];
617
618 snprintf (
619 buffer, sizeof (buffer),
620 "LOG|||%s||| |||general/Host_Details||| |||<host><detail>"
621 "<name>Host dead</name><value>1</value><source>"
622 "<description/><type/><name/></source></detail></host>",
623 ip_str);
625 get_main_kb (), "internal/results", buffer);
626
628 goto host_died;
629 }
630 else if (e == ERR_NO_FREE_SLOT)
631 {
632 if (forks_retry < MAX_FORK_RETRIES)
633 {
634 forks_retry++;
635 g_warning ("Launch failed for %s. No free slot available "
636 "in the internal process table for starting a "
637 "plugin.",
638 plugin->oid);
639 fork_sleep (forks_retry);
640 goto again;
641 }
642 }
643 else if (e == ERR_CANT_FORK)
644 {
645 if (forks_retry < MAX_FORK_RETRIES)
646 {
647 forks_retry++;
648 g_warning (
649 "fork() failed for %s - sleeping %d seconds (%s)",
650 plugin->oid, forks_retry, strerror (errno));
651 fork_sleep (forks_retry);
652 goto again;
653 }
654 else
655 {
656 g_warning ("fork() failed too many times - aborting");
657 goto host_died;
658 }
659 }
660 }
661
662 if ((cur_plug * 100) / num_plugs >= last_status
663 && !scan_is_stopped ())
664 {
665 last_status = (cur_plug * 100) / num_plugs + 2;
666 if (comm_send_status (get_main_kb (), ip_str, cur_plug, num_plugs)
667 < 0)
668 goto host_died;
669 }
670 cur_plug++;
671 }
672 else if (plugin == NULL)
673 break;
674 else if (plugin != NULL && plugin == PLUG_RUNNING)
675 /* 50 milliseconds. */
676 usleep (50000);
678 }
679
680 if (!scan_is_stopped () && prefs_get_bool ("table_driven_lsc")
681 && !lsc_has_run ()
682 && (prefs_get_bool ("mqtt_enabled")
683 || prefs_get_bool ("openvasd_lsc_enabled")))
684 {
685 call_lsc (args, ip_str);
686 }
687
689 if (!scan_is_stopped ())
690 {
691 int ret;
692 ret = comm_send_status (get_main_kb (), ip_str, num_plugs, num_plugs);
693 if (ret == 0)
694 all_plugs_launched = 1;
695 }
696
697host_died:
698 if (all_plugs_launched == 0 && !scan_is_stopped ())
699 g_message ("Vulnerability scan %s for host %s: not all plugins "
700 "were launched",
701 globals->scan_id, ip_str);
704 host_set_time (get_main_kb (), ip_str, "HOST_END");
705 write_host_stats (args->host_kb, globals->scan_id, ip_str);
706}
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:206
static int scan_is_stopped(void)
Definition attack.c:267
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:172
static void call_lsc(struct attack_start_args *args, const char *ip_str)
Definition attack.c:318
static void fork_sleep(int n)
Definition attack.c:249
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:450
#define ERR_HOST_DEAD
Definition attack.c:53
#define MAX_FORK_RETRIES
Definition attack.c:55
static kb_t host_kb
Definition attack.c:291
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:80
gvm_host_t * host
Definition attack.c:81
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 1169 of file attack.c.

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

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

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

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

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

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

809{
810 gvm_hosts_t *hosts_allow, *hosts_deny;
811 gvm_hosts_t *sys_hosts_allow, *sys_hosts_deny;
812
813 /* Do we have the right to test this host ? */
814 hosts_allow = gvm_hosts_new (prefs_get ("hosts_allow"));
815 hosts_deny = gvm_hosts_new (prefs_get ("hosts_deny"));
816 if (!host_authorized (host, addr, hosts_allow, hosts_deny))
817 return -1;
818
819 sys_hosts_allow = gvm_hosts_new (prefs_get ("sys_hosts_allow"));
820 sys_hosts_deny = gvm_hosts_new (prefs_get ("sys_hosts_deny"));
821 if (!host_authorized (host, addr, sys_hosts_allow, sys_hosts_deny))
822 return -2;
823
824 gvm_hosts_free (hosts_allow);
825 gvm_hosts_free (hosts_deny);
826 gvm_hosts_free (sys_hosts_allow);
827 gvm_hosts_free (sys_hosts_deny);
828 return 0;
829}
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:783

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

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

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

207{
208 char status_buf[2048];
209
210 if (!ip_str || !main_kb)
211 return -1;
212
213 if (strlen (ip_str) > (sizeof (status_buf) - 50))
214 return -1;
215
216 snprintf (status_buf, sizeof (status_buf), "%s/%d/%d", ip_str, curr, max);
217 kb_item_push_str_with_main_kb_check (main_kb, "internal/status", status_buf);
218 kb_lnk_reset (main_kb);
219
220 return 0;
221}
#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 signalling 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 172 of file attack.c.

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

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

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

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

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

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

1084{
1085 return alive_detection_tid;
1086}
static pthread_t alive_detection_tid
Definition attack.c:1075

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

1110{
1111 global_scan_stop = 1;
1112}
int global_scan_stop
Definition attack.c:262

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

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

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

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

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

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

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

350{
351 ipc_data_t *idata;
352 int ipc_msg_flag = IPC_DT_NO_DATA;
353
354 if ((idata = ipc_data_from_json (result, strlen (result))) != NULL)
355 {
356 switch (ipc_get_data_type_from_data (idata))
357 {
358 case IPC_DT_ERROR:
359 ipc_msg_flag |= IPC_DT_ERROR;
360 g_warning ("%s: Unknown data type.", __func__);
361 break;
362 case IPC_DT_NO_DATA:
363 break;
364 case IPC_DT_HOSTNAME:
365 ipc_msg_flag |= IPC_DT_HOSTNAME;
366 if (ipc_get_hostname_from_data (idata) == NULL)
367 g_warning ("%s: ihost data is NULL ignoring new vhost", __func__);
368 else
371 break;
373 ipc_msg_flag |= IPC_DT_USER_AGENT;
374 if (ipc_get_user_agent_from_data (idata) == NULL)
375 g_warning ("%s: iuser_agent data is NULL, ignoring new user agent",
376 __func__);
377 else
378 {
379 gchar *old_ua = NULL;
381 g_debug ("%s: The User-Agent %s has been overwritten with %s",
382 __func__, old_ua, ipc_get_user_agent_from_data (idata));
383 g_free (old_ua);
384 }
385 break;
386 case IPC_DT_LSC:
387 ipc_msg_flag |= IPC_DT_LSC;
388 set_lsc_flag ();
389 if (!scan_is_stopped () && prefs_get_bool ("table_driven_lsc")
390 && (prefs_get_bool ("mqtt_enabled")
391 || prefs_get_bool ("openvasd_lsc_enabled")))
392 {
393 struct in6_addr hostip;
394 gchar ip_str[INET6_ADDRSTRLEN];
395
396 if (!ipc_get_lsc_data_ready_flag (idata))
397 {
398 g_warning ("%s: Unknown data type.", __func__);
399 ipc_msg_flag |= IPC_DT_ERROR;
400 break;
401 }
402
403 gvm_host_get_addr6 (args->host, &hostip);
404 addr6_to_str (&hostip, ip_str);
405
406 call_lsc (args, ip_str);
407 }
408 break;
409 }
410 ipc_data_destroy (&idata);
411 }
412 return ipc_msg_flag;
413}
static void append_vhost(const char *vhost, const char *source)
Definition attack.c:295
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 416 of file attack.c.

417{
418 char *results;
419 int ipc_msg_flag = IPC_DT_NO_DATA;
420
421 while ((results = ipc_retrieve (ctx, IPC_MAIN)) != NULL)
422 {
423 size_t len, pos = 0;
424 for (size_t 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 ipc_msg_flag |= process_ipc_data (args, message);
433 g_free (message);
434 }
435 }
436 g_free (results);
437 return ipc_msg_flag;
438}
static int process_ipc_data(struct attack_start_args *args, const gchar *result)
Definition attack.c:349
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 237 of file attack.c.

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

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

268{
269 if (global_scan_stop == 1)
271 return global_scan_stop;
272}
static void scan_stop_cleanup(void)
Definition attack.c:1115

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

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

1079{
1080 alive_detection_tid = tid;
1081}

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

120{
121 kb_t main_kb = NULL;
122
125 host_kb_index);
126 kb_lnk_reset (main_kb);
127}
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 136 of file attack.c.

137{
138 kb_t main_kb = NULL;
139 char buffer[96];
140 char *scan_id = NULL;
141
143
145 {
146 kb_lnk_reset (main_kb);
147 return;
148 }
149 scan_id = kb_item_get_str (main_kb, ("internal/scanid"));
150 snprintf (buffer, sizeof (buffer), "internal/%s", scan_id);
151 kb_item_set_str_with_main_kb_check (main_kb, buffer, status, 0);
152 kb_lnk_reset (main_kb);
153 g_free (scan_id);
154}
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 716 of file attack.c.

717{
718 GString *string;
719
720 if (!list)
721 return NULL;
722 string = g_string_new (((gvm_vhost_t *) list->data)->value);
723 if (g_slist_length (list) == 1)
724 return g_string_free (string, FALSE);
725 list = list->next;
726 while (list)
727 {
728 g_string_append (string, ", ");
729 g_string_append (string, ((gvm_vhost_t *) list->data)->value);
730 list = list->next;
731 }
732 return g_string_free (string, FALSE);
733}
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 1075 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 262 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 291 of file attack.c.

Referenced by attack_host(), and check_duplicated_vhost().

◆ host_vhosts

GSList* host_vhosts = NULL
static

Definition at line 292 of file attack.c.

Referenced by append_vhost(), and attack_host().