OpenVAS Scanner  7.0.1~git
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)
 
int find_plugin_in_deps (GHashTable *checked, struct scheduler_plugin **array, int pos)
 
int check_dependency_cycles (plugins_scheduler_t sched)
 
plugins_scheduler_t plugins_scheduler_init (const char *plugins_list, int autoload, int only_network, 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)
 
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 43 of file pluginscheduler.c.

Function Documentation

◆ check_dependency_cycles()

int check_dependency_cycles ( plugins_scheduler_t  sched)

Definition at line 274 of file pluginscheduler.c.

275 {
276  int i, j;
277  GHashTable *checked;
278 
279  checked = g_hash_table_new_full (g_str_hash, g_direct_equal, NULL, NULL);
280  for (i = ACT_INIT; i <= ACT_END; i++)
281  {
282  GSList *element = sched->list[i];
283 
284  while (element)
285  {
286  struct scheduler_plugin *array[1024];
287  int pos;
288 
289  array[0] = element->data;
290  pos = find_plugin_in_deps (checked, array, 0);
291  if (pos >= 0)
292  {
293  g_warning ("Dependency cycle:");
294  for (j = 0; j <= pos; j++)
295  {
296  char *name = nvticache_get_filename (array[j]->oid);
297 
298  g_message (" %s (%s)", name, array[j]->oid);
299  g_free (name);
300  }
301 
302  g_hash_table_destroy (checked);
303  return 1;
304  }
305  element = element->next;
306  }
307  }
308  g_hash_table_destroy (checked);
309  return 0;
310 }

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 
)

Definition at line 247 of file pluginscheduler.c.

249 {
250  GSList *element = array[pos]->deps;
251  int i;
252 
253  for (i = 0; i < pos; i++)
254  if (array[i] == array[pos])
255  return pos;
256 
257  if (g_hash_table_lookup (checked, array[pos]))
258  return -1;
259  while (element)
260  {
261  int ret;
262 
263  array[pos + 1] = element->data;
264  ret = find_plugin_in_deps (checked, array, pos + 1);
265  if (ret != -1)
266  return ret;
267  element = element->next;
268  }
269  g_hash_table_insert (checked, array[pos], array[pos]);
270  return -1;
271 }

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 394 of file pluginscheduler.c.

395 {
396  int category;
397  GSList *element;
398  int still_running = 0;
399 
400  for (category = start; category <= end; category++)
401  {
402  struct scheduler_plugin *plugin;
403  element = h->list[category];
404  if (category == ACT_SCANNER || category == ACT_KILL_HOST
405  || category == ACT_FLOOD || category == ACT_DENIAL)
407 
408  plugin = plugins_next_unrun (element);
409  if (plugin == PLUG_RUNNING)
410  still_running = 1;
411  else if (plugin)
412  return plugin;
414  }
415  return still_running ? PLUG_RUNNING : NULL;
416 }

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 58 of file pluginscheduler.c.

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

References ACT_END, ACT_INIT, scheduler_plugin::deps, plugins_scheduler::list, name, scheduler_plugin::oid, 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 352 of file pluginscheduler.c.

353 {
354  int still_running = 0;
355 
356  while (plugins)
357  {
358  struct scheduler_plugin *plugin = plugins->data;
359  switch (plugin->running_state)
360  {
361  case PLUGIN_STATUS_UNRUN:
362  {
363  struct scheduler_plugin *nplugin;
364  GSList *deps_list = plugin->deps;
365 
366  nplugin = plugins_next_unrun (deps_list);
367 
368  if (nplugin == PLUG_RUNNING)
369  still_running = 1;
370  else if (nplugin)
371  {
373  return nplugin;
374  }
375  else
376  {
378  return plugin;
379  }
380  break;
381  }
383  still_running = 1;
384  break;
385  case PLUGIN_STATUS_DONE:
386  break;
387  }
388  plugins = plugins->next;
389  }
390  return still_running ? PLUG_RUNNING : NULL;
391 }

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 341 of file pluginscheduler.c.

342 {
343  int ret = 0, i;
344  assert (sched);
345 
346  for (i = ACT_INIT; i <= ACT_END; i++)
347  ret += g_slist_length (sched->list[i]);
348  return ret;
349 }

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 211 of file pluginscheduler.c.

213 {
214  char *oids, *oid, *saveptr;
215  GHashTable *oids_table, *names_table;
216  int error_counter = 0;
217 
218  oids_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
219  names_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
220 
221  /* Store list of plugins in hashtable. */
222  oids = g_strdup (oid_list);
223  oid = strtok_r (oids, ";", &saveptr);
224  while (oid)
225  {
226  error_counter +=
227  plugin_add (sched, oids_table, names_table, autoload, oid);
228  oid = strtok_r (NULL, ";", &saveptr);
229  }
230 
231  /* When autoload is disabled, each plugin's deps list is still empty. */
232  if (!autoload)
233  plugins_scheduler_fill_deps (sched, oids_table);
234 
235  if (error_counter > 0)
236  g_warning ("%s: %d errors were found during the plugin scheduling.",
237  __func__, error_counter);
238 
239  g_hash_table_destroy (oids_table);
240  g_hash_table_destroy (names_table);
241  g_free (oids);
242 
243  return error_counter;
244 }

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 164 of file pluginscheduler.c.

165 {
166  int category;
167 
168  for (category = ACT_INIT; category <= ACT_END; category++)
169  {
170  GSList *element = sched->list[category];
171 
172  while (element)
173  {
174  char *deps;
175  struct scheduler_plugin *plugin = element->data;
176 
177  assert (plugin->deps == NULL);
178  deps = nvticache_get_dependencies (plugin->oid);
179  if (deps)
180  {
181  int i;
182  char **array = g_strsplit (deps, ", ", 0);
183 
184  for (i = 0; array[i]; i++)
185  {
186  struct scheduler_plugin *dep_plugin;
187  char *dep_oid = nvticache_get_oid (array[i]);
188  dep_plugin = g_hash_table_lookup (oids_table, dep_oid);
189  if (dep_plugin)
190  plugin->deps = g_slist_prepend (plugin->deps, dep_plugin);
191  g_free (dep_oid);
192  }
193  g_strfreev (array);
194  g_free (deps);
195  }
196  element = element->next;
197  }
198  }
199 }

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 534 of file pluginscheduler.c.

535 {
536  int i;
537 
538  for (i = ACT_INIT; i <= ACT_END; i++)
539  g_slist_free_full (sched->list[i], scheduler_plugin_free);
540  g_free (sched);
541 }

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  only_network,
int *  error 
)

Definition at line 313 of file pluginscheduler.c.

315 {
317  int i;
318 
319  /* Fill our lists */
320  ret = g_malloc0 (sizeof (*ret));
321  *error = plugins_scheduler_enable (ret, plugins_list, autoload);
322 
323  if (only_network)
324  {
325  for (i = ACT_GATHER_INFO; i <= ACT_END; i++)
326  {
327  ret->list[i] = NULL;
328  }
329  }
330 
331  if (check_dependency_cycles (ret))
332  {
334  return NULL;
335  }
336  malloc_trim (0);
337  return ret;
338 }

References ACT_END, ACT_GATHER_INFO, check_dependency_cycles(), plugins_scheduler::list, 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 442 of file pluginscheduler.c.

443 {
444  struct scheduler_plugin *ret;
445  static int scheduler_phase = 0;
446 
447  if (h == NULL)
448  return NULL;
449 
450  if (scheduler_phase == 0)
451  {
452  ret = get_next_in_range (h, ACT_INIT, ACT_INIT);
453  if (ret)
454  return ret;
455  scheduler_phase = 1;
457  }
458  if (scheduler_phase <= 1)
459  {
461  if (ret)
462  return ret;
463  scheduler_phase = 2;
465  }
466  if (scheduler_phase <= 2)
467  {
469  if (ret)
470  return ret;
471  scheduler_phase = 3;
473  }
474  if (scheduler_phase <= 3)
475  {
477  if (ret)
478  return ret;
479  scheduler_phase = 4;
481  }
482  if (scheduler_phase <= 4)
483  {
484  ret = get_next_in_range (h, ACT_END, ACT_END);
485  if (ret)
486  return ret;
487  scheduler_phase = 5;
489  }
490  return NULL;
491 }

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 499 of file pluginscheduler.c.

500 {
501  int category;
502 
503  if (sched->stopped)
504  return;
505  for (category = ACT_INIT; category < ACT_END; category++)
506  {
507  GSList *element = sched->list[category];
508 
509  while (element)
510  {
511  struct scheduler_plugin *plugin = element->data;
512 
514  element = element->next;
515  }
516  }
517  sched->stopped = 1;
518 }

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 419 of file pluginscheduler.c.

420 {
421  int category;
422 
423  assert (sched);
424  for (category = start; category <= end; category++)
425  {
426  GSList *element = sched->list[category];
427  while (element)
428  {
429  struct scheduler_plugin *plugin = element->data;
430 
431  g_free (plugin->oid);
432  g_slist_free (plugin->deps);
433  plugin->oid = NULL;
434  plugin->deps = NULL;
435  element = element->next;
436  }
437  }
438  malloc_trim (0);
439 }

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)

Definition at line 521 of file pluginscheduler.c.

522 {
523  struct scheduler_plugin *plugin;
524  if (!data)
525  return;
526 
527  plugin = data;
528  g_free (plugin->oid);
529  g_slist_free (plugin->deps);
530  g_free (plugin);
531 }

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:47
plugins_scheduler_enable
static int plugins_scheduler_enable(plugins_scheduler_t sched, const char *oid_list, int autoload)
Definition: pluginscheduler.c:211
scheduler_phase_cleanup
static void scheduler_phase_cleanup(plugins_scheduler_t sched, int start, int end)
Definition: pluginscheduler.c:419
plugins_scheduler
Definition: pluginscheduler.c:49
scheduler_plugin
Definition: pluginscheduler.h:40
pluginlaunch_disable_parallel_checks
void pluginlaunch_disable_parallel_checks(void)
Definition: pluginlaunch.c:290
find_plugin_in_deps
int find_plugin_in_deps(GHashTable *checked, struct scheduler_plugin **array, int pos)
Definition: pluginscheduler.c:247
PLUGIN_STATUS_RUNNING
@ PLUGIN_STATUS_RUNNING
Definition: pluginscheduler.h:36
ACT_ATTACK
@ ACT_ATTACK
Definition: nvt_categories.h:42
plugins_scheduler_free
void plugins_scheduler_free(plugins_scheduler_t sched)
Definition: pluginscheduler.c:534
get_next_in_range
static struct scheduler_plugin * get_next_in_range(plugins_scheduler_t h, int start, int end)
Definition: pluginscheduler.c:394
PLUGIN_STATUS_DONE
@ PLUGIN_STATUS_DONE
Definition: pluginscheduler.h:37
ACT_END
@ ACT_END
Definition: nvt_categories.h:48
name
const char * name
Definition: nasl_init.c:377
check_dependency_cycles
int check_dependency_cycles(plugins_scheduler_t sched)
Definition: pluginscheduler.c:274
plugins_scheduler_fill_deps
static void plugins_scheduler_fill_deps(plugins_scheduler_t sched, GHashTable *oids_table)
Definition: pluginscheduler.c:164
ACT_SETTINGS
@ ACT_SETTINGS
Definition: nvt_categories.h:40
ACT_DENIAL
@ ACT_DENIAL
Definition: nvt_categories.h:45
oid
const char * oid
Definition: nasl_builtin_find_service.c:57
scheduler_plugin::running_state
enum plugin_status running_state
Definition: pluginscheduler.h:44
scheduler_plugin_free
void scheduler_plugin_free(void *data)
Definition: pluginscheduler.c:521
plugins_scheduler::list
GSList * list[ACT_END+1]
Definition: pluginscheduler.c:51
plugin_add
static int plugin_add(plugins_scheduler_t sched, GHashTable *oids_table, GHashTable *names_table, int autoload, char *oid)
Definition: pluginscheduler.c:58
plugins_scheduler::stopped
int stopped
Definition: pluginscheduler.c:52
PLUG_RUNNING
#define PLUG_RUNNING
Definition: pluginscheduler.h:49
scheduler_plugin::deps
GSList * deps
Definition: pluginscheduler.h:43
scheduler_plugin::oid
char * oid
Definition: pluginscheduler.h:42
plugins_next_unrun
static struct scheduler_plugin * plugins_next_unrun(GSList *plugins)
Definition: pluginscheduler.c:352
PLUGIN_STATUS_UNRUN
@ PLUGIN_STATUS_UNRUN
Definition: pluginscheduler.h:35
ACT_SCANNER
@ ACT_SCANNER
Definition: nvt_categories.h:39
ACT_GATHER_INFO
@ ACT_GATHER_INFO
Definition: nvt_categories.h:41
ACT_KILL_HOST
@ ACT_KILL_HOST
Definition: nvt_categories.h:46
ACT_INIT
@ ACT_INIT
Definition: nvt_categories.h:38
pluginlaunch_enable_parallel_checks
void pluginlaunch_enable_parallel_checks(void)
Definition: pluginlaunch.c:296