OpenVAS Scanner 23.32.3
pluginscheduler.c File Reference

Tells openvas which plugin should be executed next. More...

#include "pluginscheduler.h"
#include "../misc/nvt_categories.h"
#include "../misc/plugutils.h"
#include "pluginlaunch.h"
#include "pluginload.h"
#include <glib.h>
#include <gvm/base/prefs.h>
#include <gvm/util/nvticache.h>
#include <malloc.h>
#include <string.h>
Include dependency graph for pluginscheduler.c:

Go to the source code of this file.

Data Structures

struct  plugins_scheduler

Macros

#define G_LOG_DOMAIN   "sd main"
 GLib log domain.

Functions

static int plugin_add (plugins_scheduler_t sched, GHashTable *oids_table, GHashTable *names_table, int autoload, char *oid)
static void plugins_scheduler_fill_deps (plugins_scheduler_t sched, GHashTable *oids_table)
static int plugins_scheduler_enable (plugins_scheduler_t sched, const char *oid_list, int autoload)
static int find_plugin_in_deps (GHashTable *checked, struct scheduler_plugin **array, int pos)
static int check_dependency_cycles (plugins_scheduler_t sched)
plugins_scheduler_t plugins_scheduler_init (const char *plugins_list, int autoload, int *error)
int plugins_scheduler_count_active (plugins_scheduler_t sched)
static struct scheduler_pluginplugins_next_unrun (GSList *plugins)
static struct scheduler_pluginget_next_in_range (plugins_scheduler_t h, int start, int end)
static void scheduler_phase_cleanup (plugins_scheduler_t sched, int start, int end)
struct scheduler_pluginplugins_scheduler_next (plugins_scheduler_t h)
void plugins_scheduler_stop (plugins_scheduler_t sched)
static void scheduler_plugin_free (void *data)
void plugins_scheduler_free (plugins_scheduler_t sched)

Detailed Description

Tells openvas which plugin should be executed next.

Definition in file pluginscheduler.c.

Macro Definition Documentation

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "sd main"

GLib log domain.

Definition at line 30 of file pluginscheduler.c.

Function Documentation

◆ check_dependency_cycles()

int check_dependency_cycles ( plugins_scheduler_t sched)
static

Definition at line 263 of file pluginscheduler.c.

264{
265 int i, j;
266 GHashTable *checked;
267
268 checked = g_hash_table_new_full (g_str_hash, g_direct_equal, NULL, NULL);
269 for (i = ACT_INIT; i <= ACT_END; i++)
270 {
271 GSList *element = sched->list[i];
272
273 while (element)
274 {
275 struct scheduler_plugin *array[1024];
276 int pos;
277
278 array[0] = element->data;
279 pos = find_plugin_in_deps (checked, array, 0);
280 if (pos >= 0)
281 {
282 g_warning ("Dependency cycle:");
283 for (j = 0; j <= pos; j++)
284 {
285 char *name = nvticache_get_filename (array[j]->oid);
286
287 g_message (" %s (%s)", name, array[j]->oid);
288 g_free (name);
289 }
290
291 g_hash_table_destroy (checked);
292 return 1;
293 }
294 element = element->next;
295 }
296 }
297 g_hash_table_destroy (checked);
298 return 0;
299}
const char * oid
const char * name
Definition nasl_init.c:439
@ ACT_END
@ ACT_INIT
static int find_plugin_in_deps(GHashTable *checked, struct scheduler_plugin **array, int pos)
GSList * list[ACT_END+1]

References ACT_END, ACT_INIT, find_plugin_in_deps(), plugins_scheduler::list, name, and oid.

Referenced by plugins_scheduler_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_plugin_in_deps()

int find_plugin_in_deps ( GHashTable * checked,
struct scheduler_plugin ** array,
int pos )
static

Definition at line 236 of file pluginscheduler.c.

238{
239 GSList *element = array[pos]->deps;
240 int i;
241
242 for (i = 0; i < pos; i++)
243 if (array[i] == array[pos])
244 return pos;
245
246 if (g_hash_table_lookup (checked, array[pos]))
247 return -1;
248 while (element)
249 {
250 int ret;
251
252 array[pos + 1] = element->data;
253 ret = find_plugin_in_deps (checked, array, pos + 1);
254 if (ret != -1)
255 return ret;
256 element = element->next;
257 }
258 g_hash_table_insert (checked, array[pos], array[pos]);
259 return -1;
260}

References scheduler_plugin::deps, and find_plugin_in_deps().

Referenced by check_dependency_cycles(), and find_plugin_in_deps().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_next_in_range()

struct scheduler_plugin * get_next_in_range ( plugins_scheduler_t h,
int start,
int end )
static

Definition at line 376 of file pluginscheduler.c.

377{
378 int category;
379 GSList *element;
380 int still_running = 0;
381
382 for (category = start; category <= end; category++)
383 {
384 struct scheduler_plugin *plugin;
385 element = h->list[category];
386 if (category == ACT_SCANNER || category == ACT_KILL_HOST
387 || category == ACT_FLOOD || category == ACT_DENIAL)
389
390 plugin = plugins_next_unrun (element);
391 if (plugin == PLUG_RUNNING)
392 still_running = 1;
393 else if (plugin)
394 return plugin;
396 }
397 return still_running ? PLUG_RUNNING : NULL;
398}
@ ACT_KILL_HOST
@ ACT_SCANNER
@ ACT_FLOOD
@ ACT_DENIAL
void pluginlaunch_enable_parallel_checks(void)
void pluginlaunch_disable_parallel_checks(void)
static struct scheduler_plugin * plugins_next_unrun(GSList *plugins)
#define PLUG_RUNNING

References ACT_DENIAL, ACT_FLOOD, ACT_KILL_HOST, ACT_SCANNER, plugins_scheduler::list, PLUG_RUNNING, pluginlaunch_disable_parallel_checks(), pluginlaunch_enable_parallel_checks(), and plugins_next_unrun().

Referenced by plugins_scheduler_next().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugin_add()

int plugin_add ( plugins_scheduler_t sched,
GHashTable * oids_table,
GHashTable * names_table,
int autoload,
char * oid )
static

Definition at line 45 of file pluginscheduler.c.

47{
48 struct scheduler_plugin *plugin;
49 int category;
50 nvti_t *nvti;
51 int ret = 0;
52 gchar *tag_value;
53
54 if (g_hash_table_lookup (oids_table, oid))
55 return 0;
56
57 /* Check if the plugin is deprecated */
58 nvti = nvticache_get_nvt (oid);
59 if (nvti == NULL)
60 {
61 g_warning ("The NVT with oid %s was not found in the nvticache.", oid);
62 return 1;
63 }
64
65 tag_value = nvti_get_tag (nvti, "deprecated");
66 if (tag_value && !strcmp (tag_value, "1"))
67 {
68 if (prefs_get_bool ("log_whole_attack"))
69 {
70 char *name = nvticache_get_filename (oid);
71 g_message ("Plugin %s is deprecated. "
72 "It will neither be loaded nor launched.",
73 name);
74 g_free (name);
75 }
76 nvti_free (nvti);
77 g_free (tag_value);
78 return 0;
79 }
80
81 category = nvti_category (nvti);
82 if (!(category >= ACT_INIT && category <= ACT_END))
83 {
84 g_warning ("The NVT with oid %s has no category assigned. This is "
85 "considered a fatal error, since the NVTI Cache "
86 "structure stored in Redis is out dated or corrupted.",
87 oid);
88 nvti_free (nvti);
89 return 1;
90 }
91 plugin = g_malloc0 (sizeof (struct scheduler_plugin));
93 plugin->oid = g_strdup (oid);
94 g_hash_table_insert (oids_table, plugin->oid, plugin);
95
96 sched->list[category] = g_slist_prepend (sched->list[category], plugin);
97
98 /* Add the plugin's dependencies too. */
99 if (autoload)
100 {
101 char *saveptr, *dep_name = NULL, *deps = nvti_dependencies (nvti);
102
103 if (deps)
104 dep_name = strtok_r (deps, ", ", &saveptr);
105 while (dep_name)
106 {
107 struct scheduler_plugin *dep_plugin;
108 char *dep_oid;
109
110 dep_oid = g_hash_table_lookup (names_table, dep_name);
111 if (!dep_oid)
112 {
113 dep_oid = nvticache_get_oid (dep_name);
114 g_hash_table_insert (names_table, g_strdup (dep_name), dep_oid);
115 }
116 if (dep_oid)
117 {
118 ret =
119 plugin_add (sched, oids_table, names_table, autoload, dep_oid);
120 if (ret)
121 return 1;
122 dep_plugin = g_hash_table_lookup (oids_table, dep_oid);
123 /* In case of autoload, no need to wait for plugin_add() to
124 * fill all enabled plugins to start filling dependencies
125 * lists. */
126 if (dep_plugin)
127 plugin->deps = g_slist_prepend (plugin->deps, dep_plugin);
128 else
129 g_warning ("There was a problem loading %s (%s), a "
130 "dependency of %s. This can happen e.g. when "
131 "depending on a deprecated NVT.",
132 dep_name, dep_oid, oid);
133 }
134 else
135 {
136 char *name = nvticache_get_name (oid);
137 g_warning (
138 "There was a problem trying to load %s, a dependency "
139 "of %s. This may be due to a parse error, or it failed "
140 "to find the dependency. Please check the path to the "
141 "file.",
142 dep_name, name);
143 g_free (name);
144 }
145 dep_name = strtok_r (NULL, ", ", &saveptr);
146 }
147 }
148 nvti_free (nvti);
149 return 0;
150}
static int plugin_add(plugins_scheduler_t sched, GHashTable *oids_table, GHashTable *names_table, int autoload, char *oid)
@ PLUGIN_STATUS_UNRUN
enum plugin_status running_state

References ACT_END, ACT_INIT, scheduler_plugin::deps, plugins_scheduler::list, name, oid, scheduler_plugin::oid, plugin_add(), PLUGIN_STATUS_UNRUN, and scheduler_plugin::running_state.

Referenced by plugin_add(), and plugins_scheduler_enable().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_next_unrun()

struct scheduler_plugin * plugins_next_unrun ( GSList * plugins)
static

Definition at line 334 of file pluginscheduler.c.

335{
336 int still_running = 0;
337
338 while (plugins)
339 {
340 struct scheduler_plugin *plugin = plugins->data;
341 switch (plugin->running_state)
342 {
344 {
345 struct scheduler_plugin *nplugin;
346 GSList *deps_list = plugin->deps;
347
348 nplugin = plugins_next_unrun (deps_list);
349
350 if (nplugin == PLUG_RUNNING)
351 still_running = 1;
352 else if (nplugin)
353 {
355 return nplugin;
356 }
357 else
358 {
360 return plugin;
361 }
362 break;
363 }
365 still_running = 1;
366 break;
368 break;
369 }
370 plugins = plugins->next;
371 }
372 return still_running ? PLUG_RUNNING : NULL;
373}
@ PLUGIN_STATUS_RUNNING
@ PLUGIN_STATUS_DONE

References scheduler_plugin::deps, PLUG_RUNNING, PLUGIN_STATUS_DONE, PLUGIN_STATUS_RUNNING, PLUGIN_STATUS_UNRUN, plugins_next_unrun(), and scheduler_plugin::running_state.

Referenced by get_next_in_range(), and plugins_next_unrun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_scheduler_count_active()

int plugins_scheduler_count_active ( plugins_scheduler_t sched)

Definition at line 323 of file pluginscheduler.c.

324{
325 int ret = 0, i;
326 assert (sched);
327
328 for (i = ACT_INIT; i <= ACT_END; i++)
329 ret += g_slist_length (sched->list[i]);
330 return ret;
331}

References ACT_END, ACT_INIT, and plugins_scheduler::list.

Referenced by attack_host().

Here is the caller graph for this function:

◆ plugins_scheduler_enable()

int plugins_scheduler_enable ( plugins_scheduler_t sched,
const char * oid_list,
int autoload )
static

Definition at line 200 of file pluginscheduler.c.

202{
203 char *oids, *oid, *saveptr;
204 GHashTable *oids_table, *names_table;
205 int error_counter = 0;
206
207 oids_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
208 names_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
209
210 /* Store list of plugins in hashtable. */
211 oids = g_strdup (oid_list);
212 oid = strtok_r (oids, ";", &saveptr);
213 while (oid)
214 {
215 error_counter +=
216 plugin_add (sched, oids_table, names_table, autoload, oid);
217 oid = strtok_r (NULL, ";", &saveptr);
218 }
219
220 /* When autoload is disabled, each plugin's deps list is still empty. */
221 if (!autoload)
222 plugins_scheduler_fill_deps (sched, oids_table);
223
224 if (error_counter > 0)
225 g_warning ("%s: %d errors were found during the plugin scheduling.",
226 __func__, error_counter);
227
228 g_hash_table_destroy (oids_table);
229 g_hash_table_destroy (names_table);
230 g_free (oids);
231
232 return error_counter;
233}
static void plugins_scheduler_fill_deps(plugins_scheduler_t sched, GHashTable *oids_table)

References oid, plugin_add(), and plugins_scheduler_fill_deps().

Referenced by plugins_scheduler_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_scheduler_fill_deps()

void plugins_scheduler_fill_deps ( plugins_scheduler_t sched,
GHashTable * oids_table )
static

Definition at line 153 of file pluginscheduler.c.

154{
155 int category;
156
157 for (category = ACT_INIT; category <= ACT_END; category++)
158 {
159 GSList *element = sched->list[category];
160
161 while (element)
162 {
163 char *deps;
164 struct scheduler_plugin *plugin = element->data;
165
166 assert (plugin->deps == NULL);
167 deps = nvticache_get_dependencies (plugin->oid);
168 if (deps)
169 {
170 int i;
171 char **array = g_strsplit (deps, ", ", 0);
172
173 for (i = 0; array[i]; i++)
174 {
175 struct scheduler_plugin *dep_plugin;
176 char *dep_oid = nvticache_get_oid (array[i]);
177 dep_plugin = g_hash_table_lookup (oids_table, dep_oid);
178 if (dep_plugin)
179 plugin->deps = g_slist_prepend (plugin->deps, dep_plugin);
180 g_free (dep_oid);
181 }
182 g_strfreev (array);
183 g_free (deps);
184 }
185 element = element->next;
186 }
187 }
188}

References ACT_END, ACT_INIT, scheduler_plugin::deps, plugins_scheduler::list, and scheduler_plugin::oid.

Referenced by plugins_scheduler_enable().

Here is the caller graph for this function:

◆ plugins_scheduler_free()

void plugins_scheduler_free ( plugins_scheduler_t sched)

Definition at line 518 of file pluginscheduler.c.

519{
520 int i;
521
522 for (i = ACT_INIT; i <= ACT_END; i++)
523 g_slist_free_full (sched->list[i], scheduler_plugin_free);
524 g_free (sched);
525}
static void scheduler_plugin_free(void *data)

References ACT_END, ACT_INIT, plugins_scheduler::list, and scheduler_plugin_free().

Referenced by attack_host(), attack_network(), and plugins_scheduler_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_scheduler_init()

plugins_scheduler_t plugins_scheduler_init ( const char * plugins_list,
int autoload,
int * error )

Definition at line 302 of file pluginscheduler.c.

303{
305
306 /* Fill our lists */
307 ret = g_malloc0 (sizeof (*ret));
308 *error = plugins_scheduler_enable (ret, plugins_list, autoload);
309
310 if (check_dependency_cycles (ret))
311 {
313 return NULL;
314 }
315
316#ifdef __GLIBC__
317 malloc_trim (0);
318#endif
319 return ret;
320}
static int plugins_scheduler_enable(plugins_scheduler_t sched, const char *oid_list, int autoload)
static int check_dependency_cycles(plugins_scheduler_t sched)
void plugins_scheduler_free(plugins_scheduler_t sched)
struct plugins_scheduler * plugins_scheduler_t

References check_dependency_cycles(), plugins_scheduler_enable(), and plugins_scheduler_free().

Referenced by attack_network().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_scheduler_next()

struct scheduler_plugin * plugins_scheduler_next ( plugins_scheduler_t h)

Definition at line 426 of file pluginscheduler.c.

427{
428 struct scheduler_plugin *ret;
429 static int scheduler_phase = 0;
430
431 if (h == NULL)
432 return NULL;
433
434 if (scheduler_phase == 0)
435 {
437 if (ret)
438 return ret;
439 scheduler_phase = 1;
441 }
442 if (scheduler_phase <= 1)
443 {
445 if (ret)
446 return ret;
447 scheduler_phase = 2;
449 }
450 if (scheduler_phase <= 2)
451 {
453 if (ret)
454 return ret;
455 scheduler_phase = 3;
457 }
458 if (scheduler_phase <= 3)
459 {
461 if (ret)
462 return ret;
463 scheduler_phase = 4;
465 }
466 if (scheduler_phase <= 4)
467 {
469 if (ret)
470 return ret;
471 scheduler_phase = 5;
473 }
474 return NULL;
475}
@ ACT_GATHER_INFO
@ ACT_ATTACK
@ ACT_SETTINGS
static void scheduler_phase_cleanup(plugins_scheduler_t sched, int start, int end)
static struct scheduler_plugin * get_next_in_range(plugins_scheduler_t h, int start, int end)

References ACT_ATTACK, ACT_END, ACT_FLOOD, ACT_GATHER_INFO, ACT_INIT, ACT_SCANNER, ACT_SETTINGS, get_next_in_range(), and scheduler_phase_cleanup().

Referenced by attack_host().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugins_scheduler_stop()

void plugins_scheduler_stop ( plugins_scheduler_t sched)

Definition at line 483 of file pluginscheduler.c.

484{
485 int category;
486
487 if (sched->stopped)
488 return;
489 for (category = ACT_INIT; category < ACT_END; category++)
490 {
491 GSList *element = sched->list[category];
492
493 while (element)
494 {
495 struct scheduler_plugin *plugin = element->data;
496
498 element = element->next;
499 }
500 }
501 sched->stopped = 1;
502}

References ACT_END, ACT_INIT, plugins_scheduler::list, PLUGIN_STATUS_DONE, scheduler_plugin::running_state, and plugins_scheduler::stopped.

Referenced by attack_host().

Here is the caller graph for this function:

◆ scheduler_phase_cleanup()

void scheduler_phase_cleanup ( plugins_scheduler_t sched,
int start,
int end )
static

Definition at line 401 of file pluginscheduler.c.

402{
403 int category;
404
405 assert (sched);
406 for (category = start; category <= end; category++)
407 {
408 GSList *element = sched->list[category];
409 while (element)
410 {
411 struct scheduler_plugin *plugin = element->data;
412
413 g_free (plugin->oid);
414 g_slist_free (plugin->deps);
415 plugin->oid = NULL;
416 plugin->deps = NULL;
417 element = element->next;
418 }
419 }
420#ifdef __GLIBC__
421 malloc_trim (0);
422#endif
423}

References scheduler_plugin::deps, plugins_scheduler::list, and scheduler_plugin::oid.

Referenced by plugins_scheduler_next().

Here is the caller graph for this function:

◆ scheduler_plugin_free()

void scheduler_plugin_free ( void * data)
static

Definition at line 505 of file pluginscheduler.c.

506{
507 struct scheduler_plugin *plugin;
508 if (!data)
509 return;
510
511 plugin = data;
512 g_free (plugin->oid);
513 g_slist_free (plugin->deps);
514 g_free (plugin);
515}

References scheduler_plugin::deps, and scheduler_plugin::oid.

Referenced by plugins_scheduler_free().

Here is the caller graph for this function: