OpenVAS Scanner 23.32.3
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
12
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
36#define G_LOG_DOMAIN "sd main"
37
54static GSList *
55collect_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
97static int
98calculate_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
112static int *loading_shm = NULL;
113static int loading_shmid = 0;
114
115/*
116 * @brief Initializes the shared memory data used to report plugins loading
117 * progress to other processes.
118 */
119void
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 */
152void
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 */
170int
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 */
181int
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 */
192static 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 */
204static 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 */
216static void
217cleanup_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
241static int
242plugins_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);
311
312 setproctitle ("openvas: Reloaded all the NVTs.");
313
314 return 0;
315}
316
317static 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}
341
347int
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
371int
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}
void nasl_clean_inc(void)
int add_nasl_inc_dir(const char *)
Adds the given string as directory for searching for includes.
static struct timeval timeval(unsigned long val)
const char * name
Definition nasl_init.c:439
int nasl_file_check(const char *folder, const char *filename)
Check a single .nasl/.inc file.
int nasl_plugin_add(const char *folder, char *filename)
Add one .nasl plugin to the plugin list.
static int loading_shmid
Definition pluginload.c:113
static int calculate_eta(struct timeval start_time, int loaded, int total)
Definition pluginload.c:98
static void cleanup_leftovers(int num_files)
Definition pluginload.c:217
int total_loading_plugins(void)
Definition pluginload.c:182
int plugins_init(void)
main function for loading all the plugins
Definition pluginload.c:372
static int * loading_shm
Definition pluginload.c:112
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
static void set_total_loading_plugins(int total)
Definition pluginload.c:205
static void include_dirs(void)
Definition pluginload.c:318
void init_loading_shm(void)
Definition pluginload.c:120
void destroy_loading_shm(void)
Definition pluginload.c:153
static int plugins_reload_from_dir(const char *folder)
Definition pluginload.c:242
static void set_current_loading_plugins(int current)
Definition pluginload.c:193
int current_loading_plugins(void)
Definition pluginload.c:171
int plugins_cache_init(void)
Main function for nvticache initialization without loading the plugins.
Definition pluginload.c:348
pluginload.c header.
processes.c header.
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition sighand.c:79
headerfile for sighand.c.
utils.c headerfile.