OpenVAS Scanner  22.7.9
pluginload.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 
13 #include "pluginload.h"
14 
15 #include "../nasl/nasl.h"
16 #include "processes.h"
17 #include "sighand.h"
18 #include "utils.h"
19 
20 #include <bsd/unistd.h>
21 #include <errno.h>
22 #include <glib.h>
23 #include <gvm/base/prefs.h> /* for prefs_get() */
24 #include <gvm/util/nvticache.h> /* for nvticache_new */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/shm.h> /* for shmget */
29 #include <sys/time.h>
30 #include <sys/wait.h>
31 
32 #undef G_LOG_DOMAIN
33 
36 #define G_LOG_DOMAIN "sd main"
37 
54 static GSList *
55 collect_nvts (const char *folder, const char *subdir, GSList *files)
56 {
57  GDir *dir;
58  const gchar *fname;
59 
60  if (folder == NULL)
61  return files;
62 
63  dir = g_dir_open (folder, 0, NULL);
64  if (dir == NULL)
65  return files;
66 
67  fname = g_dir_read_name (dir);
68  while (fname)
69  {
70  char *path;
71 
72  path = g_build_filename (folder, fname, NULL);
73  if (g_file_test (path, G_FILE_TEST_IS_DIR))
74  {
75  char *new_folder, *new_subdir;
76 
77  new_folder = g_build_filename (folder, fname, NULL);
78  new_subdir = g_build_filename (subdir, fname, NULL);
79 
80  files = collect_nvts (new_folder, new_subdir, files);
81 
82  if (new_folder)
83  g_free (new_folder);
84  if (new_subdir)
85  g_free (new_subdir);
86  }
87  else if (g_str_has_suffix (fname, ".nasl"))
88  files = g_slist_prepend (files, g_build_filename (subdir, fname, NULL));
89  g_free (path);
90  fname = g_dir_read_name (dir);
91  }
92 
93  g_dir_close (dir);
94  return files;
95 }
96 
97 static int
98 calculate_eta (struct timeval start_time, int loaded, int total)
99 {
100  struct timeval current_time;
101  int elapsed, remaining;
102 
103  if (start_time.tv_sec == 0)
104  return 0;
105 
106  gettimeofday (&current_time, NULL);
107  elapsed = current_time.tv_sec - start_time.tv_sec;
108  remaining = total - loaded;
109  return (remaining * elapsed) / loaded;
110 }
111 
112 static int *loading_shm = NULL;
113 static int loading_shmid = 0;
114 
115 /*
116  * @brief Initializes the shared memory data used to report plugins loading
117  * progress to other processes.
118  */
119 void
121 {
122  int shm_key;
123 
124  if (loading_shm)
125  return;
126 
127  shm_key = rand () + 1;
128  /*
129  * Create shared memory segment if it doesn't exist.
130  * This will be used to communicate current plugins loading progress to other
131  * processes.
132  * loading_shm[0]: Number of loaded plugins.
133  * loading_shm[1]: Total number of plugins.
134  */
135  loading_shmid = shmget (shm_key, sizeof (int) * 2, IPC_CREAT | 0600);
136  if (loading_shmid < 0)
137  perror ("shmget");
138  loading_shm = shmat (loading_shmid, NULL, 0);
139  if (loading_shm == (void *) -1)
140  {
141  perror ("shmat");
142  loading_shm = NULL;
143  }
144  else
145  bzero (loading_shm, sizeof (int) * 2);
146 }
147 
148 /*
149  * @brief Destroys the shared memory data used to report plugins loading
150  * progress to other processes.
151  */
152 void
154 {
155  if (loading_shm)
156  {
157  shmdt (loading_shm);
158  if (shmctl (loading_shmid, IPC_RMID, NULL))
159  perror ("shmctl");
160  loading_shm = NULL;
161  loading_shmid = 0;
162  }
163 }
164 
165 /*
166  * @brief Gives current number of loaded plugins.
167  *
168  * @return Number of loaded plugins, 0 if initialization wasn't successful.
169  */
170 int
172 {
173  return loading_shm ? loading_shm[0] : 0;
174 }
175 
176 /*
177  * @brief Gives the total number of plugins to be loaded.
178  *
179  * @return Total of loaded plugins, 0 if initialization wasn't successful.
180  */
181 int
183 {
184  return loading_shm ? loading_shm[1] : 0;
185 }
186 
187 /*
188  * @brief Sets number of loaded plugins.
189  *
190  * @param[in] current Number of loaded plugins.
191  */
192 static void
194 {
195  if (loading_shm)
196  loading_shm[0] = current;
197 }
198 
199 /*
200  * @brief Sets total number of plugins to be loaded.
201  *
202  * @param[in] total Total number of plugins
203  */
204 static void
206 {
207  if (loading_shm)
208  loading_shm[1] = total;
209 }
210 
211 /*
212  * @brief Clean leftover NVTs.
213  *
214  * @param[in] num_files Number of NVT files found in the folder.
215  */
216 static void
217 cleanup_leftovers (int num_files)
218 {
219  size_t count;
220  GSList *oids, *element;
221 
222  setproctitle ("openvas: Cleaning leftover NVTs.");
223 
224  count = nvticache_count ();
225  if ((int) count <= num_files)
226  return;
227 
228  oids = element = nvticache_get_oids ();
229  while (element)
230  {
231  char *path = nvticache_get_src (element->data);
232 
233  if (!g_file_test (path, G_FILE_TEST_EXISTS))
234  nvticache_delete (element->data);
235  g_free (path);
236  element = element->next;
237  }
238  g_slist_free_full (oids, g_free);
239 }
240 
241 static int
242 plugins_reload_from_dir (const char *folder)
243 {
244  GSList *files = NULL, *f;
245  int loaded_files = 0, num_files = 0;
246  struct timeval start_time;
247 
248  openvas_signal (SIGTERM, SIG_DFL);
249  if (folder == NULL)
250  {
251  g_debug ("%s:%d : folder == NULL", __FILE__, __LINE__);
252  g_debug ("Could not determine the value of <plugins_folder>. "
253  " Check %s\n",
254  (char *) prefs_get ("config_file"));
255  return 1;
256  }
257 
258  files = collect_nvts (folder, "", files);
259  num_files = g_slist_length (files);
260 
261  /*
262  * Add the plugins
263  */
264 
265  if (gettimeofday (&start_time, NULL))
266  {
267  bzero (&start_time, sizeof (start_time));
268  g_debug ("gettimeofday: %s", strerror (errno));
269  }
270  f = files;
271  set_total_loading_plugins (num_files);
272  while (f != NULL)
273  {
274  static int err_count = 0;
275  char *name = f->data;
276 
277  loaded_files++;
278  if (loaded_files % 50 == 0)
279  {
280  int percentile, eta;
281 
282  set_current_loading_plugins (loaded_files);
283  percentile = (loaded_files * 100) / num_files;
284  eta = calculate_eta (start_time, loaded_files, num_files);
285  setproctitle ("openvas: Reloaded %d of %d NVTs"
286  " (%d%% / ETA: %02d:%02d)",
287  loaded_files, num_files, percentile, eta / 60,
288  eta % 60);
289  }
290  if (prefs_get_bool ("log_plugins_name_at_load"))
291  g_message ("Loading %s", name);
292  if (g_str_has_suffix (name, ".nasl"))
293  {
294  if (nasl_plugin_add (folder, name))
295  err_count++;
296  }
297 
298  if (err_count == 20)
299  {
300  g_debug ("Stopped loading plugins: High number of errors.");
301  setproctitle ("openvas: Error loading NVTs.");
302  g_slist_free_full (files, g_free);
303  return 1;
304  }
305  f = g_slist_next (f);
306  }
307 
308  cleanup_leftovers (num_files);
309  g_slist_free_full (files, g_free);
310  nasl_clean_inc ();
311 
312  setproctitle ("openvas: Reloaded all the NVTs.");
313 
314  return 0;
315 }
316 
317 static void
319 {
320  const gchar *pref_include_folders;
321 
322  add_nasl_inc_dir (""); // for absolute and relative paths
323  pref_include_folders = prefs_get ("include_folders");
324  if (pref_include_folders != NULL)
325  {
326  gchar **include_folders = g_strsplit (pref_include_folders, ":", 0);
327  unsigned int i = 0;
328 
329  for (i = 0; i < g_strv_length (include_folders); i++)
330  {
331  int result = add_nasl_inc_dir (include_folders[i]);
332  if (result < 0)
333  g_debug ("Could not add %s to the list of include folders.\n"
334  "Make sure %s exists and is a directory.\n",
335  include_folders[i], include_folders[i]);
336  }
337 
338  g_strfreev (include_folders);
339  }
340 }
347 int
349 {
350  int ret;
351  const char *plugins_folder = prefs_get ("plugins_folder");
352 
353  if (nvticache_init (plugins_folder, prefs_get ("db_address")))
354  {
355  g_debug ("Failed to initialize nvti cache.");
356  return -1;
357  }
358  include_dirs ();
359  ret = nasl_file_check (plugins_folder, "plugin_feed_info.inc");
360  if (ret)
361  return -1;
362 
363  return 0;
364 }
365 
371 int
373 {
374  int ret = 0;
375  const char *plugins_folder = prefs_get ("plugins_folder");
376 
377  ret = plugins_cache_init ();
378  if (ret)
379  return ret;
380 
381  ret = plugins_reload_from_dir (plugins_folder);
382  nvticache_save ();
383  return ret;
384 }
processes.h
processes.c header.
total_loading_plugins
int total_loading_plugins(void)
Definition: pluginload.c:182
destroy_loading_shm
void destroy_loading_shm(void)
Definition: pluginload.c:153
init_loading_shm
void init_loading_shm(void)
Definition: pluginload.c:120
add_nasl_inc_dir
int add_nasl_inc_dir(const char *)
Adds the given string as directory for searching for includes.
Definition: nasl_grammar.tab.c:2539
plugins_reload_from_dir
static int plugins_reload_from_dir(const char *folder)
Definition: pluginload.c:242
sighand.h
headerfile for sighand.c.
nasl_plugin_add
int nasl_plugin_add(const char *folder, char *filename)
Add one .nasl plugin to the plugin list.
Definition: nasl_plugins.c:120
current_loading_plugins
int current_loading_plugins(void)
Definition: pluginload.c:171
include_dirs
static void include_dirs(void)
Definition: pluginload.c:318
loading_shmid
static int loading_shmid
Definition: pluginload.c:113
collect_nvts
static GSList * collect_nvts(const char *folder, const char *subdir, GSList *files)
Collects all NVT files in a directory and recurses into subdirs.
Definition: pluginload.c:55
name
const char * name
Definition: nasl_init.c:411
openvas_signal
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition: sighand.c:79
pluginload.h
pluginload.c header.
nasl_file_check
int nasl_file_check(const char *folder, const char *filename)
Check a single .nasl/.inc file.
Definition: nasl_plugins.c:83
loading_shm
static int * loading_shm
Definition: pluginload.c:112
utils.h
utils.c headerfile.
plugins_init
int plugins_init(void)
main function for loading all the plugins
Definition: pluginload.c:372
timeval
static struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:94
set_total_loading_plugins
static void set_total_loading_plugins(int total)
Definition: pluginload.c:205
cleanup_leftovers
static void cleanup_leftovers(int num_files)
Definition: pluginload.c:217
calculate_eta
static int calculate_eta(struct timeval start_time, int loaded, int total)
Definition: pluginload.c:98
set_current_loading_plugins
static void set_current_loading_plugins(int current)
Definition: pluginload.c:193
plugins_cache_init
int plugins_cache_init(void)
Main function for nvticache initialization without loading the plugins.
Definition: pluginload.c:348
nasl_clean_inc
void nasl_clean_inc(void)
Definition: nasl_grammar.tab.c:2806