OpenVAS Scanner  5.1.3
ntp.c
Go to the documentation of this file.
1 /* OpenVAS
2 * $Id$
3 * Description: OpenVAS Transfer Protocol handling.
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 strlen() */
29 #include <stdlib.h> /* for atoi() */
30 
31 #include <glib.h>
32 
33 #include <openvas/misc/network.h> /* for recv_line */
34 #include <openvas/misc/internal_com.h> /* for INTERNAL_COMM_MSG_TYPE_DATA */
35 #include <openvas/misc/prefs.h> /* for prefs_set() */
36 
37 #include "ntp.h"
38 #include "otp.h"
39 #include "comm.h"
40 #include "log.h"
41 #include "utils.h"
42 #include "hosts.h"
43 
44 #ifndef MIN
45 #define MIN(x,y) ((x) < (y) ? (x):(y))
46 #endif
47 
48 
49 static int ntp_read_prefs (int);
50 static int ntp_long_attack (int);
51 static int ntp_recv_file (struct arglist *);
52 
56 int
57 ntp_parse_input (struct arglist *globals, char *input)
58 {
59  char *str;
60  int result = 1; /* default return value is 1 */
61  int soc = arg_get_value_int (globals, "global_socket");
62 
63  if (*input == '\0')
64  return -1;
65  str = strstr (input, " <|> ");
66  if (str == NULL)
67  return 1;
68 
69  str[0] = '\0';
70 
71  if (strcmp (input, "CLIENT") == 0)
72  {
73  input = str + 5;
74  str = strchr (input, ' ');
75  if (str != NULL)
76  str[0] = '\0';
77 
78  if (input[strlen (input) - 1] == '\n')
79  input[strlen (input) - 1] = '\0';
80 
81  switch (otp_get_client_request (input))
82  {
83  case CREQ_ATTACHED_FILE:
84  ntp_recv_file (globals);
85  break;
86 
87  case CREQ_LONG_ATTACK:
88  result = ntp_long_attack (soc);
89  break;
90 
91  case CREQ_PREFERENCES:
92  ntp_read_prefs (soc);
93  break;
94 
96  log_write ("Stopping the whole test (requested by client)");
97  hosts_stop_all ();
98  break;
99 
100  case CREQ_NVT_INFO:
101  {
102  comm_send_nvt_info (soc);
103  comm_send_preferences (soc);
104  break;
105  }
106 
107  case CREQ_UNKNOWN:
108  break;
109  }
110  }
111 
112  return (result);
113 }
114 
115 static int
116 ntp_long_attack (int soc)
117 {
118  char input[16384];
119  int size;
120  char *target;
121  int n;
122 
123  n = recv_line (soc, input, sizeof (input) - 1);
124  if (n <= 0)
125  return -1;
126 
127 #if DEBUGMORE
128  log_write ("long_attack :%s\n", input);
129 #endif
130  if (!strncmp (input, "<|> CLIENT", sizeof ("<|> CLIENT")))
131  return 1;
132  size = atoi (input);
133  target = g_malloc0 (size + 1);
134 
135  n = 0;
136  while (n < size)
137  {
138  int e;
139  e = nrecv (soc, target + n, size - n, 0);
140  if (e > 0)
141  n += e;
142  else
143  {
144  g_free (target);
145  return -1;
146  }
147  }
148 
149  prefs_set ("TARGET", target);
150 
151  g_free (target);
152 
153  return 0;
154 }
155 
162 static int
163 ntp_read_prefs (int soc)
164 {
165  char *input;
166  int input_sz = 1024 * 1024 * 2; /* this is sufficient for a plugin_set
167  for upto 69K OIDs */
168 
169  input = g_malloc0 (input_sz);
170  for (;;)
171  {
172  int n;
173  input[0] = '\0';
174  n = recv_line (soc, input, input_sz - 1);
175 
176  if (n < 0 || input[0] == '\0')
177  {
178  log_write ("Empty data string -- closing comm. channel");
179  exit (0);
180  }
181 
182  if (strstr (input, "<|> CLIENT") != NULL) /* finished = 1; */
183  break;
184  /* else */
185 
186  {
187  char *pref;
188  char *v;
189  pref = input;
190  v = strchr (input, '<');
191  if (v)
192  {
193  char *value;
194  v -= 1;
195  v[0] = 0;
196 
197  value = v + 5;
198  /*
199  * "system" prefs can't be changed
200  */
201  if (is_scanner_only_pref (pref))
202  continue;
203 
204  if (value[0] != '\0')
205  value[strlen (value) - 1] = '\0';
206 
207  prefs_set (pref, value);
208  }
209  }
210  }
211 
212  g_free (input);
213  return (0);
214 }
215 
228 static void
229 files_add_translation (struct arglist *globals, const char *remotename,
230  char *contents)
231 {
232  GHashTable *trans = arg_get_value (globals, "files_translation");
233  // Register the mapping table if none there yet
234  if (trans == NULL)
235  {
236  trans = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
237  arg_add_value (globals, "files_translation", ARG_PTR, trans);
238  }
239 
240  g_hash_table_insert (trans, g_strdup (remotename), contents);
241 }
242 
255 static void
256 files_add_size_translation (struct arglist *globals, const char *remotename,
257  const long filesize)
258 {
259  GHashTable *trans = arg_get_value (globals, "files_size_translation");
260  gchar *filesize_str = g_strdup_printf ("%ld", filesize);
261 
262  // Register the mapping table if none there yet
263  if (trans == NULL)
264  {
265  trans = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
266  arg_add_value (globals, "files_size_translation", ARG_PTR, trans);
267  }
268 
269  g_hash_table_insert (trans, g_strdup (remotename), g_strdup (filesize_str));
270 }
271 
277 int
278 ntp_recv_file (struct arglist *globals)
279 {
280  int soc = arg_get_value_int (globals, "global_socket");
281  char input[4096];
282  char *origname, *contents;
283  gchar *cont_ptr = NULL;
284  int n;
285  size_t bytes = 0, tot = 0;
286 
287  n = recv_line (soc, input, sizeof (input) - 1);
288  if (n <= 0)
289  return -1;
290 
291  if (strncmp (input, "name: ", strlen ("name: ")) == 0)
292  {
293  origname = g_strdup (input + sizeof ("name: ") - 1);
294  if (origname[strlen (origname) - 1] == '\n')
295  origname[strlen (origname) - 1] = '\0';
296  }
297  else
298  return -1;
299 
300  n = recv_line (soc, input, sizeof (input) - 1);
301  if (n <= 0)
302  {
303  g_free (origname);
304  return -1;
305  }
306  /* XXX content: message. Ignored for the moment */
307 
308  n = recv_line (soc, input, sizeof (input) - 1);
309  if (n <= 0)
310  {
311  g_free (origname);
312  return -1;
313  }
314 
315  if (strncmp (input, "bytes: ", sizeof ("bytes: ") - 1) == 0)
316  {
317  char *t = input + sizeof ("bytes: ") - 1;
318  bytes = atol (t);
319  }
320  else
321  {
322  g_free (origname);
323  return -1;
324  }
325 
326  /* We now know that we have to read <bytes> bytes from the remote socket. */
327 
328  contents = g_try_malloc0 (bytes);
329 
330  if (contents == NULL)
331  {
332  log_write ("ntp_recv_file: Failed to allocate memory for uploaded file.");
333  g_free (origname);
334  return -1;
335  }
336 
337  cont_ptr = contents;
338  while (tot < bytes)
339  {
340  bzero (input, sizeof (input));
341  n = nrecv (soc, input, MIN (sizeof (input) - 1, bytes - tot), 0);
342  if (n < 0)
343  {
344  log_write ("11_recv_file: nrecv(%d)", soc);
345  break;
346  }
347  else
348  {
349  memcpy ((cont_ptr + (tot * sizeof (char))), &input, n);
350  tot += n;
351  }
352  }
353  send_printf (soc, "SERVER <|> FILE_ACCEPTED <|> SERVER\n");
354  /* Add the fact that what the remote client calls <filename> is actually
355  * stored in <contents> here and has a size of <bytes> bytes. */
356  files_add_translation (globals, origname, contents);
357  files_add_size_translation (globals, origname, bytes);
358 
359  g_free (origname);
360  return 0;
361 }
362 
363 /*----------------------------------------------------------
364 
365  Communication protocol: timestamps
366 
367  ----------------------------------------------------------*/
368 
369 
370 static int
371 __ntp_timestamp_scan (int soc, char *msg)
372 {
373  char timestr[1024];
374  char *tmp;
375  time_t t;
376  int len;
377 
378  t = time (NULL);
379  tmp = ctime (&t);
380  timestr[sizeof (timestr) - 1] = '\0';
381  strncpy (timestr, tmp, sizeof (timestr) - 1);
382  len = strlen (timestr);
383  if (timestr[len - 1] == '\n')
384  timestr[len - 1] = '\0';
385 
386  send_printf (soc, "SERVER <|> TIME <|> %s <|> %s <|> SERVER\n", msg, timestr);
387  return 0;
388 }
389 
390 
391 static int
392 __ntp_timestamp_scan_host (int soc, char *msg, char *host)
393 {
394  char timestr[64];
395  char *tmp;
396  time_t t;
397  int len;
398  char buf[1024];
399 
400  t = time (NULL);
401  tmp = ctime (&t);
402  timestr[sizeof (timestr) - 1] = '\0';
403  strncpy (timestr, tmp, sizeof (timestr) - 1);
404  len = strlen (timestr);
405  if (timestr[len - 1] == '\n')
406  timestr[len - 1] = '\0';
407 
408  snprintf (buf, sizeof (buf),
409  "SERVER <|> TIME <|> %s <|> %s <|> %s <|> SERVER\n", msg, host,
410  timestr);
411 
412  internal_send (soc, buf, INTERNAL_COMM_MSG_TYPE_DATA);
413 
414  return 0;
415 }
416 
417 
418 int
420 {
421  return __ntp_timestamp_scan (soc, "SCAN_START");
422 }
423 
424 int
426 {
427  return __ntp_timestamp_scan (soc, "SCAN_END");
428 }
429 
430 int
432 {
433  return __ntp_timestamp_scan_host (soc, "HOST_START", host);
434 }
435 
436 int
438 {
439  return __ntp_timestamp_scan_host (soc, "HOST_END", host);
440 }
void hosts_stop_all(void)
Definition: hosts.c:230
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 ntp_timestamp_scan_ends(int soc)
Definition: ntp.c:425
#define MIN(x, y)
Definition: ntp.c:45
int ntp_timestamp_host_scan_starts(int soc, char *host)
Definition: ntp.c:431
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
int ntp_timestamp_host_scan_ends(int soc, char *host)
Definition: ntp.c:437
Host information, implemented as doubly linked list.
Definition: hosts.c:44
int is_scanner_only_pref(const char *pref)
Definition: utils.c:221
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 ntp_timestamp_scan_starts(int soc)
Definition: ntp.c:419
client_request_t otp_get_client_request(char *str)
Find the enum identifier for the client request which is given.
Definition: otp.c:42