OpenVAS Scanner  5.1.3
plugs_req.c
Go to the documentation of this file.
1 /* OpenVAS
2 * $Id$
3 * Description: Performs various checks for requirements set in a given plugin.
4 *
5 * Authors: - Renaud Deraison <deraison@nessus.org> (Original pre-fork develoment)
6 * - Tim Brown <mailto:timb@openvas.org> (Initial fork)
7 * - Laban Mwangi <mailto:labanm@openvas.org> (Renaming work)
8 * - Tarik El-Yassem <mailto:tarik@openvas.org> (Headers section)
9 *
10 * Copyright:
11 * Portions Copyright (C) 2006 Software in the Public Interest, Inc.
12 * Based on work Copyright (C) 1998 - 2006 Tenable Network Security, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2,
16 * as published by the Free Software Foundation
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27 
28 #include <stdlib.h> /* for atoi() */
29 #include <string.h> /* for strcmp() */
30 #include <stdio.h> /* for snprintf() */
31 #include <regex.h> /* for regcomp() */
32 
33 #include <openvas/misc/prefs.h> /* for prefs_get() */
34 #include <openvas/base/nvticache.h>
35 
36 #include "pluginscheduler.h"
37 #include "plugs_req.h"
38 
39 /**********************************************************
40 
41  Private Functions
42 
43 ***********************************************************/
44 
45 extern int kb_get_port_state_proto (kb_t, int, char *);
46 
52 static int
53 get_closed_ports (kb_t kb, char *ports_list, char *proto)
54 {
55  int i;
56  char **ports;
57 
58  if (!ports_list)
59  return -1;
60  ports = g_strsplit (ports_list, ", ", 0);
61  for (i = 0; ports[i] != NULL; i ++)
62  {
63  int iport = atoi (ports[i]);
64  if (iport > 0 && kb_get_port_state_proto (kb, iport, proto) != 0)
65  {
66  g_strfreev (ports);
67  return iport;
68  }
69  else
70  {
71  if (kb_item_get_int (kb, ports[i]) > 0)
72  {
73  g_strfreev (ports);
74  return 1; /* should be the actual value indeed ! */
75  }
76  }
77  }
78  g_strfreev (ports);
79  return 0; /* found nothing */
80 }
81 
82 
83 /**********************************************************
84 
85  Public Functions
86 
87 ***********************************************************/
88 
89 
94 struct arglist *
96  struct scheduler_plugin *plugin2)
97 {
98  struct arglist *ret = NULL;
99  int i, j;
100  char *ports1, *ports2, **array1, **array2;
101 
102  if (!plugin1 || !plugin2)
103  return 0;
104 
105  ports1 = nvticache_get_required_ports (plugin1->oid);
106  ports2 = nvticache_get_required_ports (plugin2->oid);
107  if (!ports1 || !ports2)
108  {
109  g_free (ports1);
110  g_free (ports2);
111  return 0;
112  }
113  array1 = g_strsplit (ports1, ", ", 0);
114  array2 = g_strsplit (ports2, ", ", 0);
115  g_free (ports1);
116  g_free (ports2);
117  if (!array1 || !array2)
118  {
119  g_strfreev (array1);
120  g_strfreev (array2);
121  return 0;
122  }
123 
124  for (i = 0; array1[i] != NULL; i ++)
125  {
126  for (j = 0; array2[j] != NULL; j ++)
127  {
128  if (!strcmp (array2[j], array1[i]))
129  {
130  if (!ret)
131  ret = g_malloc0 (sizeof (struct arglist));
132  arg_add_value (ret, array2[j], ARG_INT, (void *) 1);
133  }
134  }
135  }
136  g_strfreev (array1);
137  g_strfreev (array2);
138  return ret;
139 }
140 
149 static int
150 kb_missing_keyname_of_namelist (kb_t kb, char *keys, char **keyname)
151 {
152  int i;
153  char **keynames;
154  if (!kb || !keys || !*keys)
155  return 0;
156 
157  keynames = g_strsplit (keys, ", ", 0);
158  if (!keynames)
159  return 0;
160  for (i = 0; keynames[i] != NULL; i ++)
161  {
162  struct kb_item *kbi = kb_item_get_single (kb, keynames[i], KB_TYPE_UNSPEC);
163 
164  if (kbi == NULL)
165  {
166  if (keyname)
167  *keyname = g_strdup (keynames[i]);
168  g_strfreev (keynames);
169  return 1;
170  }
171 
172  kb_item_free (kbi);
173  }
174 
175  g_strfreev (keynames);
176  return 0; /* All of the keys are present in the kb */
177 }
178 
187 static int
188 kb_present_keyname_of_namelist (kb_t kb, char *keys, char **keyname)
189 {
190  int i;
191  char **keynames;
192 
193  if (!kb || !keys || !*keys)
194  return 0;
195 
196  keynames = g_strsplit (keys, ", ", 0);
197  if (!keynames)
198  return 0;
199  for (i = 0; keynames[i] != NULL; i ++)
200  {
201  struct kb_item *kbi = kb_item_get_single (kb, keynames[i], KB_TYPE_UNSPEC);
202 
203  if (kbi != NULL)
204  {
205  if (keyname)
206  *keyname = g_strdup (keynames[i]);
207  kb_item_free (kbi);
208  g_strfreev (keynames);
209  return 1;
210  }
211  }
212 
213  g_strfreev (keynames);
214  return 0;
215 }
216 
224 static int
225 check_mandatory_keys (kb_t kb, char *keys)
226 {
227  int i;
228  char **keynames;
229 
230  if (!kb || !keys || !*keys)
231  return 0;
232  keynames = g_strsplit (keys, ", ", 0);
233  if (!keynames)
234  return 0;
235  for (i = 0; keynames[i] != NULL; i ++)
236  {
237  struct kb_item *kbi;
238  char *re_str = NULL, *pos;
239 
240  /* Split, if key requires RE matching. */
241  if ((pos = strstr (keynames[i], "=")))
242  {
243  re_str = pos + 1;
244  *pos = '\0';
245  }
246 
247  kbi = kb_item_get_single (kb, keynames[i], KB_TYPE_UNSPEC);
248  if (!kbi)
249  {
250  g_strfreev (keynames);
251  return 1;
252  }
253 
254  if (re_str)
255  {
256  regex_t re;
257 
258  /* Check if RE matches. */
259  if (kbi->type != KB_TYPE_STR || !kbi->v_str)
260  {
261  g_strfreev (keynames);
262  kb_item_free (kbi);
263  return 1;
264  }
265  if (regcomp (&re, re_str, REG_EXTENDED | REG_NOSUB | REG_ICASE))
266  {
267  g_warning ("Couldn't compile regex %s", re_str);
268  g_strfreev (keynames);
269  kb_item_free (kbi);
270  return 1;
271  }
272  if (regexec (&re, kbi->v_str, 0, NULL, 0) == REG_NOMATCH)
273  {
274  g_strfreev (keynames);
275  kb_item_free (kbi);
276  regfree (&re);
277  return 1;
278  }
279  regfree (&re);
280  }
281  kb_item_free (kbi);
282  }
283 
284  g_strfreev (keynames);
285  return 0;
286 }
287 
298 int
300  struct scheduler_plugin *plugin)
301 {
302  char *mandatory_keys;
303  int ret;
304 
305  mandatory_keys = nvticache_get_mandatory_keys (plugin->oid);
306  ret = check_mandatory_keys (kb, mandatory_keys);
307 
308  g_free (mandatory_keys);
309  if (ret)
310  return 0;
311  return 1;
312 }
313 
319 char *
320 requirements_plugin (kb_t kb, struct scheduler_plugin *plugin)
321 {
322  static char error[64];
323  char *errkey = NULL, *keys, *tcp, *udp;
324  const char *opti = prefs_get ("optimization_level");
325 
326  /*
327  * Check wether the good ports are open
328  */
329  error[sizeof (error) - 1] = '\0';
330  tcp = nvticache_get_required_ports (plugin->oid);
331  if (tcp && *tcp && (get_closed_ports (kb, tcp, "tcp")) == 0)
332  {
333  strncpy (error, "none of the required tcp ports are open",
334  sizeof (error) - 1);
335  g_free (tcp);
336  return error;
337  }
338  g_free (tcp);
339 
340  udp = nvticache_get_required_udp_ports (plugin->oid);
341  if (udp && *udp && (get_closed_ports (kb, udp, "udp")) == 0)
342  {
343  strncpy (error, "none of the required udp ports are open",
344  sizeof (error) - 1);
345  g_free (udp);
346  return error;
347  }
348  g_free (udp);
349 
350  if (opti != NULL && (strcmp (opti, "open_ports") == 0 || atoi (opti) == 1))
351  return NULL;
352 
353  /*
354  * Check wether a key we wanted is missing
355  */
356  keys = nvticache_get_required_keys (plugin->oid);
357  if (kb_missing_keyname_of_namelist (kb, keys, &errkey))
358  {
359  snprintf (error, sizeof (error), "because the key %s is missing", errkey);
360  g_free (errkey);
361  g_free (keys);
362  return error;
363  }
364  g_free (keys);
365 
366  if (opti != NULL && (strcmp (opti, "required_keys") == 0 || atoi (opti) == 2))
367  return NULL;
368 
369  /*
370  * Check wether a key we do not want is present
371  */
372  keys = nvticache_get_excluded_keys (plugin->oid);
373  if (kb_present_keyname_of_namelist (kb, keys, &errkey))
374  {
375  snprintf (error, sizeof (error), "because the key %s is present", errkey);
376  g_free (errkey);
377  g_free (keys);
378  return error;
379  }
380  g_free (keys);
381  return NULL;
382 }
struct arglist * requirements_common_ports(struct scheduler_plugin *plugin1, struct scheduler_plugin *plugin2)
Returns <port> if the lists of the required ports between.
Definition: plugs_req.c:95
int mandatory_requirements_met(kb_t kb, struct scheduler_plugin *plugin)
Check whether mandatory requirements for plugin are met.
Definition: plugs_req.c:299
int kb_get_port_state_proto(kb_t, int, char *)
char * requirements_plugin(kb_t kb, struct scheduler_plugin *plugin)
Determine if the plugin requirements are met.
Definition: plugs_req.c:320