OpenVAS Scanner  22.7.9
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. More...
 

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()

static 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 }

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()

static 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.

Referenced by check_dependency_cycles().

Here is the caller graph for this function:

◆ get_next_in_range()

static 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 }

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()

static 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 }

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

Referenced by plugins_scheduler_enable().

Here is the caller graph for this function:

◆ plugins_next_unrun()

static 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  {
343  case PLUGIN_STATUS_UNRUN:
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;
367  case PLUGIN_STATUS_DONE:
368  break;
369  }
370  plugins = plugins->next;
371  }
372  return still_running ? PLUG_RUNNING : NULL;
373 }

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

Referenced by get_next_in_range().

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()

static 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 }

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()

static 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 }

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 }

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  {
436  ret = get_next_in_range (h, ACT_INIT, ACT_INIT);
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  {
468  ret = get_next_in_range (h, ACT_END, ACT_END);
469  if (ret)
470  return ret;
471  scheduler_phase = 5;
473  }
474  return NULL;
475 }

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()

static 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()

static 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:
ACT_FLOOD
@ ACT_FLOOD
Definition: nvt_categories.h:33
plugins_scheduler_enable
static int plugins_scheduler_enable(plugins_scheduler_t sched, const char *oid_list, int autoload)
Definition: pluginscheduler.c:200
scheduler_phase_cleanup
static void scheduler_phase_cleanup(plugins_scheduler_t sched, int start, int end)
Definition: pluginscheduler.c:401
plugins_scheduler
Definition: pluginscheduler.c:37
scheduler_plugin
Definition: pluginscheduler.h:28
pluginlaunch_disable_parallel_checks
void pluginlaunch_disable_parallel_checks(void)
Definition: pluginlaunch.c:340
PLUGIN_STATUS_RUNNING
@ PLUGIN_STATUS_RUNNING
Definition: pluginscheduler.h:23
scheduler_plugin_free
static void scheduler_plugin_free(void *data)
Definition: pluginscheduler.c:505
ACT_ATTACK
@ ACT_ATTACK
Definition: nvt_categories.h:28
plugins_scheduler_free
void plugins_scheduler_free(plugins_scheduler_t sched)
Definition: pluginscheduler.c:518
get_next_in_range
static struct scheduler_plugin * get_next_in_range(plugins_scheduler_t h, int start, int end)
Definition: pluginscheduler.c:376
PLUGIN_STATUS_DONE
@ PLUGIN_STATUS_DONE
Definition: pluginscheduler.h:24
ACT_END
@ ACT_END
Definition: nvt_categories.h:34
name
const char * name
Definition: nasl_init.c:411
plugins_scheduler_fill_deps
static void plugins_scheduler_fill_deps(plugins_scheduler_t sched, GHashTable *oids_table)
Definition: pluginscheduler.c:153
ACT_SETTINGS
@ ACT_SETTINGS
Definition: nvt_categories.h:26
ACT_DENIAL
@ ACT_DENIAL
Definition: nvt_categories.h:31
oid
const char * oid
Definition: nasl_builtin_find_service.c:51
scheduler_plugin::running_state
enum plugin_status running_state
Definition: pluginscheduler.h:31
check_dependency_cycles
static int check_dependency_cycles(plugins_scheduler_t sched)
Definition: pluginscheduler.c:263
plugins_scheduler::list
GSList * list[ACT_END+1]
Definition: pluginscheduler.c:38
plugin_add
static int plugin_add(plugins_scheduler_t sched, GHashTable *oids_table, GHashTable *names_table, int autoload, char *oid)
Definition: pluginscheduler.c:45
plugins_scheduler::stopped
int stopped
Definition: pluginscheduler.c:39
PLUG_RUNNING
#define PLUG_RUNNING
Definition: pluginscheduler.h:36
scheduler_plugin::deps
GSList * deps
Definition: pluginscheduler.h:30
scheduler_plugin::oid
char * oid
Definition: pluginscheduler.h:29
plugins_next_unrun
static struct scheduler_plugin * plugins_next_unrun(GSList *plugins)
Definition: pluginscheduler.c:334
PLUGIN_STATUS_UNRUN
@ PLUGIN_STATUS_UNRUN
Definition: pluginscheduler.h:22
ACT_SCANNER
@ ACT_SCANNER
Definition: nvt_categories.h:25
ACT_GATHER_INFO
@ ACT_GATHER_INFO
Definition: nvt_categories.h:27
ACT_KILL_HOST
@ ACT_KILL_HOST
Definition: nvt_categories.h:32
ACT_INIT
@ ACT_INIT
Definition: nvt_categories.h:24
pluginlaunch_enable_parallel_checks
void pluginlaunch_enable_parallel_checks(void)
Definition: pluginlaunch.c:346
find_plugin_in_deps
static int find_plugin_in_deps(GHashTable *checked, struct scheduler_plugin **array, int pos)
Definition: pluginscheduler.c:236