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