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
70 
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 
92 GSList *log_config = NULL;
93 
94 static volatile int termination_signal = 0;
95 // static char *global_scan_id = NULL;
96 
97 typedef 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 
120 static 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 
127 static void
128 my_gnutls_log_func (int level, const char *text)
129 {
130  g_message ("(%d) %s", level, text);
131 }
132 
133 static 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)
149  global_max_checks = 10;
150  }
151 
152  if ((str = prefs_get ("max_sysload")) != NULL)
153  {
154  global_max_sysload = atoi (str);
155  if (global_max_sysload <= 0)
156  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)
163  global_min_memory = 0;
164  }
165 }
166 
167 static void
169 {
170  termination_signal = sig;
172 }
173 
177 static void
179 {
183  openvas_signal (SIGCHLD, sighand_chld);
184 }
185 
199 static 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 
272 static 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 
296 static 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 
311 static 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 
332 static 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 
351 static 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 
386 static 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 
409 static int
410 attack_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 
470 int
471 openvas (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 }
processes.h
processes.c header.
get_scan_id
const char * get_scan_id()
Definition: scan_id.c:22
destroy_scan_globals
void destroy_scan_globals(struct scan_globals *globals)
Definition: scanneraux.c:14
init_logging
static int init_logging()
Init logging.
Definition: openvas.c:273
script_infos::key
kb_t key
Definition: scanneraux.h:32
log_config
GSList * log_config
Logging parameters, as passed to setup_log_handlers.
Definition: openvas.c:92
global_max_checks
int global_max_checks
Definition: openvas.c:84
sighand.h
headerfile for sighand.c.
handle_termination_signal
static void handle_termination_signal(int sig)
Definition: openvas.c:168
set_default_openvas_prefs
static void set_default_openvas_prefs()
Set the prefs from the openvas_defaults array.
Definition: openvas.c:121
store_file
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
procs_terminate_childs
void procs_terminate_childs(void)
This function terminates all processes spawned with create_process. Calls terminate_child for each pr...
Definition: processes.c:113
openvas_option::value
char * value
Definition: openvas.c:100
overwrite_openvas_prefs_with_prefs_from_client
static int overwrite_openvas_prefs_with_prefs_from_client(struct scan_globals *globals)
Read the scan preferences from redis.
Definition: openvas.c:200
attack_network
void attack_network(struct scan_globals *globals)
Attack a whole network.
Definition: attack.c:1247
openvas_signal
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition: sighand.c:79
init_sentry
int init_sentry(void)
Init sentry.
Definition: debug_utils.c:23
global_min_memory
int global_min_memory
Definition: openvas.c:86
attack.h
attack.c header.
openvas_print_start_msg
static void openvas_print_start_msg()
Print start message.
Definition: openvas.c:333
openvas_SSL_init
int openvas_SSL_init()
Initializes SSL support.
Definition: network.c:341
utils.h
utils.c headerfile.
plugins_init
int plugins_init(void)
main function for loading all the plugins
Definition: pluginload.c:372
stop_single_task_scan
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
kb_item_set_str_with_main_kb_check
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
script_infos::globals
struct scan_globals * globals
Definition: scanneraux.h:30
set_scan_id
int set_scan_id(const char *new_scan_id)
Definition: scan_id.c:13
check_tls
static void check_tls()
Check TLS.
Definition: openvas.c:312
pid
static pid_t pid
Definition: nasl_cmd_exec.c:39
option
#define option
send_message_to_client_and_finish_scan
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
openvas
int openvas(int argc, char *argv[], char *env[])
openvas.
Definition: openvas.c:471
attack_network_init
static int attack_network_init(struct scan_globals *globals, const gchar *config_file)
Set up data needed for attack_network().
Definition: openvas.c:410
kb_item_set_int_with_main_kb_check
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
global_max_sysload
int global_max_sysload
Definition: openvas.c:87
init_signal_handlers
static void init_signal_handlers(void)
Initializes main scanner process' signal handlers.
Definition: openvas.c:178
scan_globals
Definition: scanneraux.h:19
sighand_chld
void sighand_chld(int sig)
Definition: sighand.c:95
openvas_defaults
static openvas_option openvas_defaults[]
Default values for scanner options. Must be NULL terminated.
Definition: openvas.c:109
openvas_option
Definition: openvas.c:98
termination_signal
static volatile int termination_signal
Definition: openvas.c:94
openvas.h
set_globals_from_preferences
static void set_globals_from_preferences(void)
Definition: openvas.c:134
pluginlaunch.h
pluginlaunch.c header.
set_main_kb
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
debug_utils.h
debug_utils.c headerfile.
is_scanner_only_pref
int is_scanner_only_pref(const char *pref)
Definition: utils.c:235
scan_id
const char * scan_id
Definition: scan_id.c:10
my_gnutls_log_func
static void my_gnutls_log_func(int level, const char *text)
Definition: openvas.c:128
vendor_version_set
void vendor_version_set(const gchar *version)
Set vendor version.
Definition: vendorversion.c:26
global_max_hosts
int global_max_hosts
Definition: openvas.c:83
scan_globals::scan_id
char * scan_id
Definition: scanneraux.h:22
openvas_option::option
char * option
Definition: openvas.c:99
gcrypt_init
static void gcrypt_init(void)
Definition: openvas.c:297
plugins_cache_init
int plugins_cache_init(void)
Main function for nvticache initialization without loading the plugins.
Definition: pluginload.c:348