OpenVAS Scanner  5.1.3
hosts.c
Go to the documentation of this file.
1 /* OpenVAS
2 * $Id$
3 * Description: Basically creates a new process for each tested host.
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 <errno.h> /* for errno() */
29 #include <sys/wait.h> /* for waitpid() */
30 #include <string.h> /* for strlen() */
31 #include <unistd.h> /* for close() */
32 
33 #include <openvas/misc/network.h> /* for internal_recv */
34 #include <openvas/misc/internal_com.h> /* for INTERNAL_COMM_MSG_TYPE_CTRL */
35 
36 #include "utils.h" /* for data_left() */
37 #include "log.h" /* for log_write() */
38 #include "hosts.h" /* for hosts_new() */
39 #include "ntp.h" /* for ntp_parse_input() */
40 
44 struct host
45 {
46  char *name;
47  int soc;
48  pid_t pid;
49  struct host *next;
50  struct host *prev;
51 };
56 static struct host *hosts = NULL;
57 static int g_soc = -1;
58 static int g_max_hosts = 15;
59 
60 
61 /*-------------------------------------------------------------------------*/
62 static int
63 forward (int in, int out)
64 {
65  char *buf = NULL;
66  int bufsz = 0;
67  int len;
68  int type;
69 
70  if (internal_recv (in, &buf, &bufsz, &type) < 0)
71  return -1;
72 
73  if (type & INTERNAL_COMM_MSG_TYPE_CTRL)
74  {
75  errno = type & ~INTERNAL_COMM_MSG_TYPE_CTRL;
76  return -1;
77  }
78  else if ((type & INTERNAL_COMM_MSG_TYPE_DATA) == 0)
79  {
80  log_write ("hosts.c:forward(): bad msg type (%d)\n", type);
81  return -1;
82  }
83 
84  len = strlen (buf);
85 
86  if (out > 0)
87  {
88  int n;
89  for (n = 0; n < len;)
90  {
91  int e;
92  e = nsend (out, buf + n, len - n, 0);
93  if (e < 0 && errno == EINTR)
94  continue;
95  else if (e < 0)
96  return -1;
97  else
98  n += e;
99  }
100  }
101 
102  g_free (buf);
103  return 0;
104 }
105 
106 
107 static void
108 forward_all (int in, int out)
109 {
110  while (forward (in, out) == 0);
111 }
112 
113 /*-------------------------------------------------------------------*/
114 
115 
116 static void
117 host_rm (struct host *h)
118 {
119  if (h->pid != 0)
120  waitpid (h->pid, NULL, WNOHANG);
121  forward_all (h->soc, g_soc);
122 
123  close (h->soc);
124  if (h->next != NULL)
125  h->next->prev = h->prev;
126 
127  if (h->prev != NULL)
128  h->prev->next = h->next;
129 
130  g_free (h->name);
131  g_free (h);
132 }
133 
134 /*-----------------------------------------------------------------*/
135 
139 static int
140 hosts_num (void)
141 {
142  struct host *h = hosts;
143  int num;
144 
145  for (num = 0; h != NULL; num++, h = h->next);
146 
147  return num;
148 }
149 
153 static struct host *
154 hosts_get (char *name)
155 {
156  struct host *h = hosts;
157  while (h != NULL)
158  {
159  if (strcmp (h->name, name) == 0)
160  return h;
161  h = h->next;
162  }
163  return NULL;
164 }
165 
166 
167 int
168 hosts_init (int soc, int max_hosts)
169 {
170  g_soc = soc;
171  g_max_hosts = max_hosts;
172  return 0;
173 }
174 
175 extern int global_scan_stop;
176 
177 int
178 hosts_new (struct arglist *globals, char *name, int soc)
179 {
180  struct host *h;
181 
182  while (hosts_num () >= g_max_hosts)
183  {
184  if (hosts_read (globals) < 0)
185  return -1;
186  }
187  if (global_scan_stop)
188  return 0;
189 
190  h = g_malloc0 (sizeof (struct host));
191  h->name = g_strdup (name);
192  h->pid = 0;
193  h->soc = soc;
194  if (hosts != NULL)
195  hosts->prev = h;
196  h->next = hosts;
197  h->prev = NULL;
198  hosts = h;
199  return 0;
200 }
201 
202 
203 int
204 hosts_set_pid (char *name, pid_t pid)
205 {
206  struct host *h = hosts_get (name);
207  if (h == NULL)
208  {
209  log_write ("host_set_pid() failed!\n");
210  return -1;
211  }
212 
213  h->pid = pid;
214  return 0;
215 }
216 
217 /*-----------------------------------------------------------------*/
218 static int
219 hosts_stop_host (struct host *h)
220 {
221  if (h == NULL)
222  return -1;
223 
224  log_write ("Stopping host %s scan", h->name);
225  kill (h->pid, SIGUSR1);
226  return 0;
227 }
228 
229 void
231 {
232  struct host *host = hosts;
233 
234  global_scan_stop = 1;
235  while (host)
236  {
237  hosts_stop_host (host);
238  host = host->next;
239  }
240 }
241 
242 /*-----------------------------------------------------------------*/
243 
244 static int
245 hosts_read_data (void)
246 {
247  fd_set rd;
248  struct timeval tv;
249  int max = -1;
250  struct host *h = hosts;
251  int e;
252  int ret = 0;
253 
254  waitpid (-1, NULL, WNOHANG);
255 
256  if (h == NULL)
257  return 0;
258 
259  FD_ZERO (&rd);
260  while (h != NULL)
261  {
262  if (kill (h->pid, 0) < 0) /* Process is dead */
263  {
264  if (!h->prev)
265  hosts = hosts->next;
266  host_rm (h);
267  h = hosts;
268  }
269  else
270  {
271  FD_SET (h->soc, &rd);
272  if (h->soc > max)
273  max = h->soc;
274  h = h->next;
275  }
276  }
277 
278  for (;;)
279  {
280  tv.tv_sec = 0;
281  tv.tv_usec = 10000;
282  e = select (max + 1, &rd, NULL, NULL, &tv);
283 
284  if (e < 0 && errno == EINTR)
285  continue;
286  else
287  break;
288  }
289 
290  if (e <= 0)
291  return -1;
292 
293  h = hosts;
294  while (h != NULL)
295  {
296  if (FD_ISSET (h->soc, &rd) != 0)
297  {
298  if ((data_left (h->soc) != 0)
299  && (forward (h->soc, g_soc) == 0))
300  ret++;
301  }
302  h = h->next;
303  }
304 
305  return ret;
306 }
307 
311 static int
312 hosts_read_client (struct arglist *globals)
313 {
314  struct timeval tv;
315  int e = 0;
316  fd_set rd;
317 
318  if (g_soc == -1)
319  return 0;
320 
321 
322  FD_ZERO (&rd);
323  FD_SET (g_soc, &rd);
324 
325  for (;;)
326  {
327  tv.tv_sec = 0;
328  tv.tv_usec = 1000;
329  e = select (g_soc + 1, &rd, NULL, NULL, &tv);
330  if (e < 0 && errno == EINTR)
331  continue;
332  else
333  break;
334  }
335 
336  if (e > 0 && FD_ISSET (g_soc, &rd) != 0)
337  {
338  int result;
339  char buf[4096];
340 
341  result = recv_line (g_soc, buf, sizeof (buf) - 1);
342  if (result <= 0)
343  return -1;
344  result = ntp_parse_input (globals, buf);
345  if (result == -1)
346  return -1;
347  }
348 
349  return 0;
350 }
351 
356 int
357 hosts_read (struct arglist *globals)
358 {
359  if (hosts_read_client (globals) < 0)
360  {
361  hosts_stop_all ();
362  log_write ("Client abruptly closed the communication");
363  return -1;
364  }
365 
366  if (hosts == NULL)
367  return -1;
368 
369  hosts_read_data ();
370 
371  return 0;
372 }
void hosts_stop_all(void)
Definition: hosts.c:230
void log_write(const char *str,...)
Write into the logfile / syslog.
Definition: log.c:140
int soc
Definition: hosts.c:47
int hosts_new(struct arglist *globals, char *name, int soc)
Definition: hosts.c:178
int hosts_init(int soc, int max_hosts)
Definition: hosts.c:168
Host information, implemented as doubly linked list.
Definition: hosts.c:44
struct host * prev
Definition: hosts.c:50
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 global_scan_stop
Definition: attack.c:181
int data_left(int soc)
Definition: utils.c:193
int hosts_set_pid(char *name, pid_t pid)
Definition: hosts.c:204
char * name
Definition: hosts.c:46
int hosts_read(struct arglist *globals)
Returns -1 if client asked to stop all tests or connection was lost or error. 0 otherwise.
Definition: hosts.c:357
pid_t pid
Definition: hosts.c:48
struct host * next
Definition: hosts.c:49