OpenVAS Scanner 23.32.3
openvas.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 2006 Software in the Public Interest, Inc.
3 * SPDX-FileCopyrightText: 1998-2006 Tenable Network Security, Inc.
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
17
22
23#include "openvas.h"
24
25#include "../misc/kb_cache.h"
26#include "../misc/plugutils.h" /* nvticache_free */
27#include "../misc/scan_id.h" /* to manage global scan_id */
28#include "../misc/vendorversion.h" /* for vendor_version_set */
29#include "../nasl/nasl_krb5.h" /* for nasl_okrb5_clean */
30#include "attack.h" /* for attack_network */
31#include "debug_utils.h" /* for init_sentry */
32#include "pluginlaunch.h" /* for init_loading_shm */
33#include "processes.h" /* for create_process */
34#include "sighand.h" /* for openvas_signal */
35#include "utils.h" /* for store_file */
36
37#include <bsd/unistd.h> /* for proctitle_init */
38#include <errno.h> /* for errno() */
39#include <fcntl.h> /* for open() */
40#include <gcrypt.h> /* for gcry_control */
41#include <glib.h>
42#include <gnutls/gnutls.h> /* for gnutls_global_set_log_* */
43#include <grp.h>
44#include <gvm/base/logging.h> /* for setup_log_handler, load_log_configuration, free_log_configuration*/
45#include <gvm/base/nvti.h> /* for prefs_get() */
46#include <gvm/base/prefs.h> /* for prefs_get() */
47#include <gvm/base/version.h> /* for gvm_libs_version */
48#include <gvm/util/kb.h> /* for KB_PATH_DEFAULT */
49#include <gvm/util/mqtt.h> /* for mqtt_init */
50#include <gvm/util/nvticache.h> /* nvticache_free */
51#include <gvm/util/uuidutils.h> /* gvm_uuid_make */
52#include <netdb.h> /* for addrinfo */
53#include <pwd.h>
54#include <signal.h> /* for SIGTERM */
55#include <stdio.h> /* for fflush() */
56#include <stdlib.h> /* for atoi() */
57#include <sys/stat.h>
58#include <sys/un.h>
59#include <sys/wait.h> /* for waitpid */
60#include <unistd.h> /* for close() */
61
62#ifdef GIT_REV_AVAILABLE
63#include "gitrevision.h"
64#endif
65
66#if GNUTLS_VERSION_NUMBER < 0x030300
67#include "../misc/network.h" /* openvas_SSL_init */
68#endif
69
70#undef G_LOG_DOMAIN
74#define G_LOG_DOMAIN "sd main"
75
76#define PROCTITLE_WAITING "openvas: Waiting for incoming connections"
77#define PROCTITLE_LOADING "openvas: Loading Handler"
78#define PROCTITLE_RELOADING "openvas: Reloading"
79#define PROCTITLE_SERVING "openvas: Serving %s"
80
86
89
93GSList *log_config = NULL;
94
95static volatile int termination_signal = 0;
96// static char *global_scan_id = NULL;
97
98typedef struct
99{
100 char *option;
101 char *value;
103
111 {"plugins_folder", OPENVAS_NVT_DIR},
112 {"include_folders", OPENVAS_NVT_DIR},
113 {"plugins_timeout", G_STRINGIFY (NVT_TIMEOUT)},
114 {"scanner_plugins_timeout", G_STRINGIFY (SCANNER_NVT_TIMEOUT)},
115 {"db_address", KB_PATH_DEFAULT},
116 {NULL, NULL}};
117
121static void
123{
124 for (int i = 0; openvas_defaults[i].option != NULL; i++)
125 prefs_set (openvas_defaults[i].option, openvas_defaults[i].value);
126}
127
128static void
129my_gnutls_log_func (int level, const char *text)
130{
131 g_message ("(%d) %s", level, text);
132}
133
134static void
136{
137 const char *str;
138
139 if ((str = prefs_get ("max_hosts")) != NULL)
140 {
141 global_max_hosts = atoi (str);
142 if (global_max_hosts <= 0)
143 global_max_hosts = 15;
144 }
145
146 if ((str = prefs_get ("max_checks")) != NULL)
147 {
148 global_max_checks = atoi (str);
149 if (global_max_checks <= 0)
151 }
152
153 if ((str = prefs_get ("max_sysload")) != NULL)
154 {
155 global_max_sysload = atoi (str);
156 if (global_max_sysload <= 0)
158 }
159
160 if ((str = prefs_get ("min_free_mem")) != NULL)
161 {
162 global_min_memory = atoi (str);
163 if (global_min_memory <= 0)
165 }
166}
167
168static void
174
178static void
186
200static int
202{
203 char key[1024];
204 kb_t kb;
205 struct kb_item *res = NULL;
206
207 g_debug ("Start loading scan preferences.");
208 if (!globals->scan_id)
209 return -1;
210
211 snprintf (key, sizeof (key), "internal/%s/scanprefs", globals->scan_id);
212
213 kb = kb_find (prefs_get ("db_address"), key);
214 if (!kb)
215 return -1;
216 // 2022-10-19: currently internal/%s/scanprefs are set by ospd which is the
217 // main_kb in our context
218 set_main_kb (kb);
219
220 res = kb_item_get_all (kb, key);
221 if (!res)
222 return -1;
223
224 while (res)
225 {
226 gchar **pref = g_strsplit (res->v_str, "|||", 2);
227 if (pref[0])
228 {
229 gchar **pref_name = g_strsplit (pref[0], ":", 3);
230 if (pref_name[1] && pref_name[2] && !strncmp (pref_name[2], "file", 4)
231 && strcmp (pref[1], ""))
232 {
233 char *file_uuid = gvm_uuid_make ();
234 int ret;
235 prefs_set (pref[0], file_uuid);
236 ret = store_file (globals, pref[1], file_uuid);
237 if (ret)
238 g_debug ("Load preference: Failed to upload file "
239 "for nvt %s preference.",
240 pref_name[0]);
241
242 g_free (file_uuid);
243 }
244 else if (is_scanner_only_pref (pref[0]))
245 g_warning ("%s is a scanner only preference. It can not be written "
246 "by the client and will be ignored.",
247 pref_name[0]);
248 else
249 prefs_set (pref[0], pref[1] ? pref[1] : "");
250 g_strfreev (pref_name);
251 }
252
253 g_strfreev (pref);
254 res = res->next;
255 }
256 kb_del_items (kb, key);
257 snprintf (key, sizeof (key), "internal/%s", globals->scan_id);
258 kb_item_set_str_with_main_kb_check (kb, key, "ready", 0);
259 kb_item_set_int_with_main_kb_check (kb, "internal/ovas_pid", getpid ());
260 kb_lnk_reset (kb);
261
262 g_debug ("End loading scan preferences.");
263
264 kb_item_free (res);
265 return 0;
266}
267
273static int
275{
276 static gchar *log_config_file_name = NULL;
277 int err;
278
279 log_config_file_name =
280 g_build_filename (OPENVAS_SYSCONF_DIR, "openvas_log.conf", NULL);
281 if (g_file_test (log_config_file_name, G_FILE_TEST_EXISTS))
282 log_config = load_log_configuration (log_config_file_name);
283 err = setup_log_handlers (log_config);
284 if (err)
285 {
286 g_warning ("%s: Can not open or create log file or directory. "
287 "Please check permissions of log files listed in %s.",
288 __func__, log_config_file_name);
289 g_free (log_config_file_name);
290 return -1;
291 }
292 g_free (log_config_file_name);
293
294 return 0;
295}
296
297static void
299{
300 if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
301 return;
302 gcry_check_version (NULL);
303 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
304 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
305 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
306 gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
307}
308
312static void
314{
315#if GNUTLS_VERSION_NUMBER < 0x030300
316 if (openvas_SSL_init () < 0)
317 g_message ("Could not initialize openvas SSL!");
318#endif
319
320 if (prefs_get ("debug_tls") != NULL && atoi (prefs_get ("debug_tls")) > 0)
321 {
322 g_warning ("TLS debug is enabled and should only be used with care, "
323 "since it may reveal sensitive information in the scanner "
324 "logs and might make openvas fill your disk rather quickly.");
325 gnutls_global_set_log_function (my_gnutls_log_func);
326 gnutls_global_set_log_level (atoi (prefs_get ("debug_tls")));
327 }
328}
329
333static void
335{
336#ifdef OPENVAS_GIT_REVISION
337 g_message ("openvas %s (GIT revision %s) started", OPENVAS_VERSION,
338 OPENVAS_GIT_REVISION);
339#else
340 g_message ("openvas %s started", OPENVAS_VERSION);
341#endif
342}
343
352static int
354{
355 char key[1024];
356 kb_t kb;
357 int pid;
358
359 if (!get_scan_id ())
360 return 1;
361
362 snprintf (key, sizeof (key), "internal/%s", get_scan_id ());
363 kb = kb_find (prefs_get ("db_address"), key);
364 if (!kb)
365 return 1;
366
367 pid = kb_item_get_int (kb, "internal/ovas_pid");
368
369 /* Only send the signal if the pid is a positive value.
370 Since kb_item_get_int() will return -1 if the key does
371 not exist.
372 Warning: killing with -1 pid will send the signal system wide.
373 */
374 if (pid <= 0)
375 return 1;
376
377 /* Send the signal to the process group. */
378 killpg (pid, SIGUSR1);
379 return 0;
380}
381
387static void
389{
390 char key[1024];
391 kb_t kb;
392
393 // We get the main kb. It is still not set as global at this point.
394 snprintf (key, sizeof (key), "internal/%s/scanprefs", get_scan_id ());
395 kb = kb_find (prefs_get ("db_address"), key);
396 kb_item_push_str (kb, "internal/results", msg);
397 snprintf (key, sizeof (key), "internal/%s", get_scan_id ());
398 kb_item_set_str (kb, key, "finished", 0);
399 kb_lnk_reset (kb);
400}
401
410static int
411attack_network_init (struct scan_globals *globals, const gchar *config_file)
412{
413 const char *mqtt_server_uri;
414 const char *openvasd_server_uri;
415
417 prefs_config (config_file);
419
420 if (prefs_get ("vendor_version") != NULL)
421 vendor_version_set (prefs_get ("vendor_version"));
422 check_tls ();
424
425 if (plugins_cache_init ())
426 {
427 g_message ("Failed to initialize nvti cache.");
429 "ERRMSG||| ||| ||| ||| |||NVTI cache initialization failed");
430 nvticache_reset ();
431 return 1;
432 }
433 nvticache_reset ();
434
435 /* Init Notus communication */
436 openvasd_server_uri = prefs_get ("openvasd_server");
437 if (openvasd_server_uri)
438 {
439 g_message ("%s: LSC via openvasd", __func__);
440 prefs_set ("openvasd_lsc_enabled", "yes");
441 }
442 else
443 {
444 mqtt_server_uri = prefs_get ("mqtt_server_uri");
445 if (mqtt_server_uri)
446 {
447#ifdef AUTH_MQTT
448 const char *mqtt_user = prefs_get ("mqtt_user");
449 const char *mqtt_pass = prefs_get ("mqtt_pass");
450 if ((mqtt_init_auth (mqtt_server_uri, mqtt_user, mqtt_pass)) != 0)
451#else
452 if ((mqtt_init (mqtt_server_uri)) != 0)
453#endif
454 {
455 g_message ("%s: INIT MQTT: FAIL", __func__);
457 "ERRMSG||| ||| ||| ||| |||MQTT initialization failed");
458 }
459 else
460 {
461 g_message ("%s: INIT MQTT: SUCCESS", __func__);
462 prefs_set ("mqtt_enabled", "yes");
463 }
464 }
465 else
466 {
467 g_message ("%s: Neither openvasd_server nor mqtt_server_uri given, "
468 "LSC disabled",
469 __func__);
470 }
471 }
472
474
475 /* Make process a group leader, to make it easier to cleanup forked
476 * processes & their children. */
477 setpgid (0, 0);
478
480 {
481 g_warning ("No preferences found for the scan %s", globals->scan_id);
482 return 1;
483 }
484
485 return 0;
486}
487
493int
494openvas (int argc, char *argv[], char *env[])
495{
496 int err;
497
498 setproctitle_init (argc, argv, env);
499 gcrypt_init ();
500
501 static gboolean display_version = FALSE;
502 static gchar *config_file = NULL;
503 static gchar *scan_id = NULL;
504 static gchar *stop_scan_id = NULL;
505 static gboolean print_specs = FALSE;
506 static gboolean print_sysconfdir = FALSE;
507 static gboolean update_vt_info = FALSE;
508 GError *error = NULL;
509 GOptionContext *option_context;
510 static GOptionEntry entries[] = {
511 {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
512 "Display version information", NULL},
513 {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
514 "Configuration file", "<filename>"},
515 {"cfg-specs", 's', 0, G_OPTION_ARG_NONE, &print_specs,
516 "Print configuration settings", NULL},
517 {"sysconfdir", 'y', 0, G_OPTION_ARG_NONE, &print_sysconfdir,
518 "Print system configuration directory (set at compile time)", NULL},
519 {"update-vt-info", 'u', 0, G_OPTION_ARG_NONE, &update_vt_info,
520 "Updates VT info into redis store from VT files", NULL},
521 {"scan-start", '\0', 0, G_OPTION_ARG_STRING, &scan_id,
522 "ID of scan to start. ID and related data must be stored into redis "
523 "before.",
524 "<string>"},
525 {"scan-stop", '\0', 0, G_OPTION_ARG_STRING, &stop_scan_id,
526 "ID of scan to stop", "<string>"},
527
528 {NULL, 0, 0, 0, NULL, NULL, NULL}};
529
530 option_context =
531 g_option_context_new ("- Open Vulnerability Assessment Scanner");
532 g_option_context_add_main_entries (option_context, entries, NULL);
533 if (!g_option_context_parse (option_context, &argc, &argv, &error))
534 {
535 g_print ("%s\n\n", error->message);
536 return EXIT_SUCCESS;
537 }
538 g_option_context_free (option_context);
539
540 /* --sysconfdir */
541 if (print_sysconfdir)
542 {
543 g_print ("%s\n", SYSCONFDIR);
544 return EXIT_SUCCESS;
545 }
546
547 /* --version */
548 if (display_version)
549 {
550 printf ("OpenVAS %s\n", OPENVAS_VERSION);
551#ifdef OPENVAS_GIT_REVISION
552 printf ("GIT revision %s\n", OPENVAS_GIT_REVISION);
553#endif
554 printf ("gvm-libs %s\n", gvm_libs_version ());
555 printf ("Most new code since 2005: (C) 2024 Greenbone AG\n");
556 printf (
557 "Nessus origin: (C) 2004 Renaud Deraison <deraison@nessus.org>\n");
558 printf ("License GPLv2: GNU GPL version 2\n");
559 printf (
560 "This is free software: you are free to change and redistribute it.\n"
561 "There is NO WARRANTY, to the extent permitted by law.\n\n");
562 return EXIT_SUCCESS;
563 }
564
565 /* Switch to UTC so that OTP times are always in UTC. */
566 if (setenv ("TZ", "utc 0", 1) == -1)
567 {
568 g_print ("%s\n\n", strerror (errno));
569 return EXIT_SUCCESS;
570 }
571 tzset ();
572
573#ifdef LOG_REFERENCES_AVAILABLE
574 if (scan_id)
575 set_log_reference (scan_id);
576 if (stop_scan_id)
577 set_log_reference (stop_scan_id);
578#endif // LOG_REFERENCES_AVAILABLE
579 if (init_logging () != 0)
580 return EXIT_FAILURE;
581
582 if (!init_sentry ())
583 {
584 g_message ("Sentry is enabled. This can log sensitive information.");
585 }
586
587 /* Config file location */
588 if (!config_file)
589 config_file = OPENVAS_CONF;
590
591 if (update_vt_info)
592 {
594 prefs_config (config_file);
596 err = plugins_init ();
597 nvticache_reset ();
598 gvm_close_sentry ();
599 return err ? EXIT_FAILURE : EXIT_SUCCESS;
600 }
601
602 /* openvas --scan-stop */
603 if (stop_scan_id)
604 {
606 prefs_config (config_file);
607 if (plugins_cache_init ())
608 {
609 g_message ("Failed to initialize nvti cache. Not possible to "
610 "stop the scan");
611 nvticache_reset ();
612 gvm_close_sentry ();
613 return EXIT_FAILURE;
614 }
615 nvticache_reset ();
616
617 set_scan_id (g_strdup (stop_scan_id));
618 err = stop_single_task_scan ();
619 gvm_close_sentry ();
620#ifdef LOG_REFERENCES_AVAILABLE
621 free_log_reference ();
622#endif // LOG_REFERENCES_AVAILABLE
623 return err ? EXIT_FAILURE : EXIT_SUCCESS;
624 }
625
626 /* openvas --scan-start */
627 if (scan_id)
628 {
629 int attack_error = 0;
630 struct scan_globals *globals;
631 set_scan_id (g_strdup (scan_id));
632 globals = g_malloc0 (sizeof (struct scan_globals));
633 globals->scan_id = g_strdup (get_scan_id ());
634
635 if (attack_network_init (globals, config_file) != 0)
636 {
637 destroy_scan_globals (globals);
638 return EXIT_FAILURE;
639 }
640 attack_error = attack_network (globals);
641
642 gvm_close_sentry ();
643 destroy_scan_globals (globals);
645#ifdef LOG_REFERENCES_AVAILABLE
646 free_log_reference ();
647#endif // LOG_REFERENCES_AVAILABLE
648
649 if (attack_error)
650 {
651 g_warning ("Scan ending with FAILURE status");
652 return EXIT_FAILURE;
653 }
654 return EXIT_SUCCESS;
655 }
656
657 if (print_specs)
658 {
660 prefs_config (config_file);
661 prefs_dump ();
662 gvm_close_sentry ();
663 }
664
665 return EXIT_SUCCESS;
666}
int attack_network(struct scan_globals *globals)
Attack a whole network. return 0 on successes, -1 if there was a critical error.
Definition attack.c:1170
attack.c header.
int init_sentry(void)
Init sentry.
Definition debug_utils.c:23
debug_utils.c headerfile.
void set_main_kb(kb_t kb)
sets the shared database between ospd and openvas as a main_kb for further usage. @description this s...
Definition kb_cache.c:27
Header file to cache main_kb.
static pid_t pid
void nasl_okrb5_clean(void)
Definition nasl_krb5.c:314
#define option
int openvas_SSL_init()
Initializes SSL support.
Definition network.c:341
Header file for module network.
static volatile int termination_signal
Definition openvas.c:95
int openvas(int argc, char *argv[], char *env[])
openvas.
Definition openvas.c:494
static void my_gnutls_log_func(int level, const char *text)
Definition openvas.c:129
static int attack_network_init(struct scan_globals *globals, const gchar *config_file)
Set up data needed for attack_network().
Definition openvas.c:411
static void openvas_print_start_msg()
Print start message.
Definition openvas.c:334
int global_max_sysload
Definition openvas.c:88
static void set_globals_from_preferences(void)
Definition openvas.c:135
GSList * log_config
Logging parameters, as passed to setup_log_handlers.
Definition openvas.c:93
int global_min_memory
Definition openvas.c:87
static int overwrite_openvas_prefs_with_prefs_from_client(struct scan_globals *globals)
Read the scan preferences from redis.
Definition openvas.c:201
static void set_default_openvas_prefs()
Set the prefs from the openvas_defaults array.
Definition openvas.c:122
static void send_message_to_client_and_finish_scan(const char *msg)
Send a failure message and set the scan as finished.
Definition openvas.c:388
static openvas_option openvas_defaults[]
Default values for scanner options. Must be NULL terminated.
Definition openvas.c:110
int global_max_checks
Definition openvas.c:85
int global_max_hosts
Definition openvas.c:84
static void handle_termination_signal(int sig)
Definition openvas.c:169
static void init_signal_handlers(void)
Initializes main scanner process' signal handlers.
Definition openvas.c:179
static int init_logging()
Init logging.
Definition openvas.c:274
static void gcrypt_init(void)
Definition openvas.c:298
static int stop_single_task_scan(void)
Search in redis the process ID of a running scan and sends it the kill signal SIGUSR1,...
Definition openvas.c:353
static void check_tls()
Check TLS.
Definition openvas.c:313
pluginlaunch.c header.
int plugins_init(void)
main function for loading all the plugins
Definition pluginload.c:372
int plugins_cache_init(void)
Main function for nvticache initialization without loading the plugins.
Definition pluginload.c:348
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
int kb_item_set_int_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_set_int....
Definition plugutils.c:609
Header file for module plugutils.
void procs_terminate_childs(void)
This function terminates all processes spawned with create_process. Calls terminate_child for each pr...
Definition processes.c:113
processes.c header.
const char * scan_id
Definition scan_id.c:10
int set_scan_id(const char *new_scan_id)
Definition scan_id.c:13
const char * get_scan_id()
Definition scan_id.c:22
void destroy_scan_globals(struct scan_globals *globals)
Definition scanneraux.c:14
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition sighand.c:79
void sighand_chld(int sig)
Definition sighand.c:95
headerfile for sighand.c.
char * option
Definition openvas.c:100
char * value
Definition openvas.c:101
char * scan_id
Definition scanneraux.h:22
int is_scanner_only_pref(const char *pref)
Definition utils.c:238
int store_file(struct scan_globals *globals, const char *file, const char *file_hash)
Stores a file type preference in a hash table.
Definition utils.c:104
utils.c headerfile.
void vendor_version_set(const gchar *version)
Set vendor version.
Header file: vendor version functions prototypes.