OpenVAS Scanner  5.1.3
comm.c
Go to the documentation of this file.
1  /* OpenVAS
2  * $Id$
3  * Description: Communication manager; it manages the NTP Protocol version 1.0 and 1.1.
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 <string.h> /* for strchr() */
29 #include <stdlib.h> /* for atoi() */
30 
31 #include <stdarg.h>
32 
33 #include <glib.h>
34 
35 #include <openvas/nasl/nasl.h>
36 #include <openvas/misc/nvt_categories.h>/* for ACT_FIRST */
37 #include <openvas/misc/plugutils.h>
38 #include <openvas/misc/network.h> /* for recv_line */
39 #include <openvas/misc/prefs.h> /* for preferences_get() */
40 
41 #include <openvas/base/nvticache.h> /* for nvticache_t */
42 
43 #include "comm.h"
44 #include "ntp.h"
45 #include "log.h"
46 #include "pluginscheduler.h"
47 #include "pluginload.h" /* for current_loading_plugins */
48 #include "sighand.h"
49 #include "utils.h"
50 
56 int
57 comm_init (int soc)
58 {
59  char buf[1024];
60  int n;
61 
62  /* We must read the version of the OTP the client
63  wants us to use */
64  n = recv_line (soc, buf, sizeof (buf) - 1);
65  if (n <= 0)
66  {
67  log_write ("Failed reading client-requested OTP version.");
68  return -1;
69  }
70 
71  buf[sizeof (buf) - 1] = '\0';
72  if (strncmp (buf, "< OTP/2.0 >", 11))
73  {
74  log_write ("Unknown client-requested OTP version: %s.", buf);
75  return -1;
76  }
77  nsend (soc, "< OTP/2.0 >\n", 12, 0);
78  return 0;
79 }
80 
88 int
89 comm_loading (int soc)
90 {
91  int n, len;
92  char buf[256];
93  n = recv_line (soc, buf, sizeof (buf) - 1);
94  if (n <= 0)
95  {
96  log_write ("Failed reading client input.");
97  return -1;
98  }
99  /* Always respond with SCANNER_LOADING. */
100  g_snprintf (buf, sizeof (buf), "SCANNER_LOADING <|> %d <|> %d\n",
102  len = strlen (buf);
103  n = nsend (soc, buf, len, 0);
104  if (n != len)
105  return -1;
106  while (n > 0)
107  n = recv_line (soc, buf, sizeof (buf) - 1);
108 
109  return 0;
110 }
111 
116 static int
117 is_client_present (int soc)
118 {
119  fd_set rd;
120  struct timeval tv;
121  int e;
122 
123  FD_ZERO (&rd);
124  FD_SET (soc, &rd);
125 again:
126  tv.tv_sec = 2;
127  tv.tv_usec = 0;
128  errno = 0;
129  e = select (soc + 1, &rd, NULL, NULL, &tv);
130  if (e < 0)
131  {
132  if (errno == EINTR)
133  goto again;
134  return 0;
135  }
136 
137  if (e > 0 && !data_left (soc))
138  return 0;
139  return 1;
140 }
141 
145 void
146 comm_terminate (int soc)
147 {
148  send_printf (soc, "SERVER <|> BYE <|> BYE <|> SERVER\n");
149  while (is_client_present (soc))
150  {
151  char buffer[4096];
152  int n;
153 
154  n = recv_line (soc, buffer, sizeof (buffer) - 1);
155  if (n < 0 || *buffer == '\0')
156  return;
157  }
158 }
159 
163 void
164 send_plug_info (int soc, const char *oid)
165 {
166  int category;
167  char *name = NULL, *copyright = NULL, *version = NULL, *family = NULL;
168  char *cve_id = NULL, *bid = NULL, *xref = NULL, *tag = NULL;
169 
170  category = nvticache_get_category (oid);
171  if (category >= ACT_UNKNOWN || category < ACT_FIRST)
172  category = ACT_UNKNOWN;
173  version = nvticache_get_version (oid);
174  name = nvticache_get_name (oid);
175  if (!name || strchr (name, '\n'))
176  {
177  log_write ("Erroneous name for plugin %s", oid);
178  goto send_cleanup;
179  }
180  copyright = nvticache_get_copyright (oid);
181  if (!copyright || strchr (copyright, '\n'))
182  {
183  log_write ("Erroneous copyright for plugin %s", oid);
184  goto send_cleanup;
185  }
186  family = nvticache_get_family (oid);
187  if (!family)
188  {
189  log_write ("Missing family for plugin %s", oid);
190  goto send_cleanup;
191  }
192 
193  cve_id = nvticache_get_cves (oid);
194  bid = nvticache_get_bids (oid);
195  xref = nvticache_get_xrefs (oid);
196  tag = nvticache_get_tags (oid);
197  if (tag)
198  {
199  char *index = tag;
200  while (*index)
201  {
202  if (*index == '\n')
203  *index = ';';
204  index++;
205  }
206  }
207 
209  (soc, "%s <|> %s <|> %d <|> %s <|> %s <|> %s <|> %s <|> %s <|> "
210  "%s <|> %s\n", oid, name, category, copyright, family, version,
211  (cve_id && *cve_id) ? cve_id : "NOCVE", (bid && *bid) ? bid : "NOBID",
212  (xref && *xref) ? xref: "NOXREF", (tag && *tag) ? tag : "NOTAG");
213 
214 send_cleanup:
215  g_free (name);
216  g_free (copyright);
217  g_free (family);
218  g_free (version);
219  g_free (cve_id);
220  g_free (bid);
221  g_free (xref);
222  g_free (tag);
223 }
224 
231 void
233 {
234  GSList *list, *element;
235 
236  list = element = nvticache_get_oids ();
237  send_printf (soc, "SERVER <|> PLUGIN_LIST <|>\n");
238  while (element)
239  {
240  send_plug_info (soc, element->data);
241  element = element->next;
242  }
243  send_printf (soc, "<|> SERVER\n");
244  g_slist_free_full (list, g_free);
245 }
246 
247 void
249 {
250  GSList *list, *element;
251 
252  list = element = nvticache_get_oids ();
253  while (element)
254  {
255  GSList *tmp, *nprefs;
256  char *name = nvticache_get_name (element->data);
257 
258  tmp = nprefs = nvticache_get_prefs (element->data);
259  while (tmp)
260  {
261  const nvtpref_t *nvtpref = tmp->data;
262  send_printf (soc, "%s[%s]:%s <|> %s\n", name, nvtpref_type (nvtpref),
263  g_strchomp (nvtpref_name (nvtpref)),
264  nvtpref_default (nvtpref));
265  tmp = tmp->next;
266  }
267  g_free (name);
268  g_slist_free_full (nprefs, (void (*) (void *)) nvtpref_free);
269  element = element->next;
270  }
271  g_slist_free_full (list, g_free);
272 }
273 
278 void
280 {
281  struct arglist *prefs = preferences_get ();
282 
283  /* We have to be backward compatible with the NTP/1.0 */
284  send_printf (soc, "SERVER <|> PREFERENCES <|>\n");
285 
286  while (prefs && prefs->next)
287  {
288  if (prefs->type == ARG_STRING && !is_scanner_only_pref (prefs->name))
289  send_printf (soc, "%s <|> %s\n", prefs->name,
290  (const char *) prefs->value);
291  prefs = prefs->next;
292  }
294  send_printf (soc, "<|> SERVER\n");
295 }
296 
297 
302 int
303 comm_wait_order (struct arglist *globals)
304 {
305  int soc = arg_get_value_int (globals, "global_socket");
306 
307  for (;;)
308  {
309  static char str[2048];
310  int n;
311 
312  memset (str, '\0', sizeof (str));
313  n = recv_line (soc, str, sizeof (str) - 1);
314  if (n < 0)
315  {
316  log_write ("Client closed the communication");
317  return -1;
318  }
319  if (str[0] == '\0')
320  if (!is_client_present (soc))
321  {
322  log_write ("Client not present");
323  return -1;
324  }
325 
326  n = ntp_parse_input (globals, str);
327  if (n == 0)
328  return 0;
329  else if (n == -1)
330  {
331  log_write ("Client input parsing error: %s", str);
332  return -1;
333  }
334  }
335 }
336 
337 /*-------------------------------------------------------------------------------*/
338 
339 
347 static int
348 nvt_feed_version (char *feed_version, int feed_size)
349 {
350  FILE *foutput;
351  gchar *command, *info_file;
352  info_file = g_build_filename (OPENVAS_NVT_DIR, "plugin_feed_info.inc", NULL);
353  command = g_strdup_printf ("grep PLUGIN_SET %s | sed -e 's/[^0-9]//g'",
354  info_file);
355 
356  foutput = popen (command, "r");
357  if (fgets (feed_version, feed_size, foutput) == NULL)
358  {
359  pclose (foutput);
360  g_free (info_file);
361  g_free (command);
362  return 1;
363  }
364 
365  feed_version[strlen (feed_version) - 1] = '\0';
366  pclose (foutput);
367  g_free (info_file);
368  g_free (command);
369  return 0;
370 }
371 
379 static int
380 is_valid_feed_version (const char *feed_version)
381 {
382  if (feed_version == NULL)
383  return 0;
384 
385  while (*feed_version)
386  if (!g_ascii_isdigit (*feed_version++))
387  return 0;
388  return 1;
389 }
390 
394 void
396 {
397  char buf[2048];
398  gchar *feed_version;
399  int feed_size = 32;
400 
401  feed_version = g_malloc0 (feed_size);
402  nvt_feed_version (feed_version, feed_size);
403 
404  send_printf (soc, "SERVER <|> NVT_INFO <|> %s <|> SERVER\n",
405  is_valid_feed_version (feed_version)
406  ? feed_version : "NOVERSION");
407 
408  g_free (feed_version);
409 
410  for (;;)
411  {
412  bzero (buf, sizeof (buf));
413  recv_line (soc, buf, sizeof (buf) - 1);
414  if (strstr (buf, "COMPLETE_LIST"))
415  comm_send_pluginlist (soc);
416  else
417  break;
418  }
419 }
void log_write(const char *str,...)
Write into the logfile / syslog.
Definition: log.c:140
void send_printf(int soc, char *data,...)
Writes data to a socket.
Definition: utils.c:276
int comm_loading(int soc)
Informs the client that the scanner is still loading.
Definition: comm.c:89
int total_loading_plugins(void)
Definition: pluginload.c:194
void comm_send_nvt_info(int soc)
Send the OTP NVT_INFO message and then handle any COMPLETE_LIST.
Definition: comm.c:395
void comm_send_preferences(int soc)
Sends the preferences of the scanner.
Definition: comm.c:279
void comm_send_pluginlist(int soc)
Sends the list of plugins that the scanner could load to the client,.
Definition: comm.c:232
void send_plugins_preferences(int soc)
Definition: comm.c:248
void send_plug_info(int soc, const char *oid)
Sends a plugin info.
Definition: comm.c:164
int current_loading_plugins(void)
Definition: pluginload.c:183
int is_scanner_only_pref(const char *pref)
Definition: utils.c:221
int comm_init(int soc)
Initializes the communication between the scanner (us) and the client.
Definition: comm.c:57
int ntp_parse_input(struct arglist *globals, char *input)
Parses the input sent by the client before the NEW_ATTACK message.
Definition: ntp.c:57
int data_left(int soc)
Definition: utils.c:193
int comm_wait_order(struct arglist *globals)
This function waits for the attack order of the client. Meanwhile, it processes all the messages the ...
Definition: comm.c:303
void comm_terminate(int soc)
This function must be called at the end of a session.
Definition: comm.c:146