OpenVAS Scanner 23.40.3
attack.c File Reference

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

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

Go to the source code of this file.

Data Structures

struct  attack_start_args

Macros

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

Functions

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

Variables

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

Detailed Description

Launches the plugins, and manages multithreading.

Definition in file attack.c.

Macro Definition Documentation

◆ ERR_HOST_DEAD

#define ERR_HOST_DEAD   -1

Definition at line 52 of file attack.c.

Referenced by attack_host(), and launch_plugin().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "sd main"

GLib log domain.

Definition at line 68 of file attack.c.

◆ INVALID_TARGET_LIST

#define INVALID_TARGET_LIST   "-1"

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

Definition at line 62 of file attack.c.

Referenced by attack_network().

◆ KB_RETRY_DELAY

#define KB_RETRY_DELAY   3 /*In sec*/

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

Definition at line 58 of file attack.c.

Referenced by attack_network().

◆ MAX_FORK_RETRIES

#define MAX_FORK_RETRIES   10

Definition at line 54 of file attack.c.

Referenced by attack_host(), and attack_network().

Function Documentation

◆ ad_thread_joined()

gboolean ad_thread_joined ( gboolean joined)
static

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

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

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

Definition at line 1099 of file attack.c.

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

Referenced by attack_network(), and scan_stop_cleanup().

Here is the caller graph for this function:

◆ append_vhost()

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

Definition at line 294 of file attack.c.

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

References host_vhosts.

Referenced by process_ipc_data().

Here is the caller graph for this function:

◆ apply_hosts_excluded()

int apply_hosts_excluded ( gvm_hosts_t * hosts)
static

Definition at line 916 of file attack.c.

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

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

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

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

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

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

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

Referenced by attack_start().

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

◆ attack_network()

int attack_network ( struct scan_globals * globals)

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

Definition at line 1168 of file attack.c.

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

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

Referenced by openvas().

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

◆ attack_start()

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

Set up some data and jump into attack_host().

Definition at line 836 of file attack.c.

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

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

Referenced by attack_network().

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

◆ call_lsc()

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

Definition at line 317 of file attack.c.

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

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

Referenced by attack_host(), and process_ipc_data().

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

◆ check_deprecated_prefs()

void check_deprecated_prefs ( void )
static

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

Definition at line 738 of file attack.c.

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

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

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

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

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

References report_kb_failure().

Referenced by attack_network().

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

◆ comm_send_status()

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

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

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

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

Definition at line 205 of file attack.c.

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

References kb_item_push_str_with_main_kb_check(), main_kb, and max.

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

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

◆ comm_send_status_host_dead()

int comm_send_status_host_dead ( kb_t main_kb,
char * ip_str )
static

Send status to the client that the host is dead.

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

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

Definition at line 171 of file attack.c.

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

References kb_item_push_str_with_main_kb_check(), and main_kb.

Referenced by attack_host().

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

◆ connect_main_kb()

int connect_main_kb ( kb_t * main_kb)
static

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

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

Definition at line 96 of file attack.c.

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

References main_kb.

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

Here is the caller graph for this function:

◆ fork_sleep()

void fork_sleep ( int n)
static

Definition at line 248 of file attack.c.

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

Referenced by attack_host(), and attack_network().

Here is the caller graph for this function:

◆ get_alive_detection_tid()

pthread_t get_alive_detection_tid ( )
static

Definition at line 1082 of file attack.c.

1083{
1084 return alive_detection_tid;
1085}
static pthread_t alive_detection_tid
Definition attack.c:1074

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

1109{
1110 global_scan_stop = 1;
1111}
int global_scan_stop
Definition attack.c:261

References global_scan_stop.

Referenced by attack_network().

Here is the caller graph for this function:

◆ host_authorized()

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

Definition at line 782 of file attack.c.

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

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

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

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

References kb_item_push_str_with_main_kb_check(), and ipc_context::type.

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

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

◆ nvti_category_is_safe()

int nvti_category_is_safe ( int category)
static

Checks that an NVT category is safe.

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

Definition at line 281 of file attack.c.

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

References ACT_DENIAL, ACT_DESTRUCTIVE_ATTACK, ACT_FLOOD, and ACT_KILL_HOST.

Referenced by launch_plugin(), and main().

Here is the caller graph for this function:

◆ process_ipc_data()

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

Definition at line 348 of file attack.c.

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

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

Referenced by read_ipc().

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

◆ read_ipc()

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

Definition at line 415 of file attack.c.

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

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

Referenced by launch_plugin().

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

◆ report_kb_failure()

void report_kb_failure ( int errcode)
static

Definition at line 236 of file attack.c.

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

Referenced by attack_network(), and check_kb_access().

Here is the caller graph for this function:

◆ scan_is_stopped()

int scan_is_stopped ( void )
static

Definition at line 266 of file attack.c.

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

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

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

1078{
1079 alive_detection_tid = tid;
1080}

References alive_detection_tid.

Referenced by attack_network().

Here is the caller graph for this function:

◆ set_kb_readable()

void set_kb_readable ( int host_kb_index)
static

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

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

Definition at line 118 of file attack.c.

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

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

Referenced by attack_start().

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

◆ set_scan_status()

void set_scan_status ( char * status)
static

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

Parameters
[in]statusStatus to set.

Definition at line 135 of file attack.c.

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

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

Referenced by attack_network().

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

◆ vhosts_to_str()

char * vhosts_to_str ( GSList * list)
static

Definition at line 715 of file attack.c.

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

Referenced by get_alive_detection_tid(), and set_alive_detection_tid().

◆ global_scan_stop

int global_scan_stop = 0

Definition at line 261 of file attack.c.

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

◆ host_kb

kb_t host_kb = NULL
static

Definition at line 290 of file attack.c.

Referenced by attack_host(), and check_duplicated_vhost().

◆ host_vhosts

GSList* host_vhosts = NULL
static

Definition at line 291 of file attack.c.

Referenced by append_vhost(), and attack_host().