1 /* Copyright (C) 2004 Michel Arboi <mikhail@nessus.org>
2  *
3  * SPDX-License-Identifier: GPL-2.0-only
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include "../misc/network.h"
20 #include "../misc/plugutils.h"
21 #include "nasl_lex_ctxt.h"
22 
23 #include <errno.h> /* for errno() */
24 #include <fcntl.h> /* for fcntl() */
25 #include <glib.h>
26 #include <gvm/base/logging.h>
27 #include <gvm/base/prefs.h> /* for prefs_get */
28 #include <netdb.h>          /* for getprotobyname() */
29 #include <stdio.h>          /* for fprintf() */
30 #include <stdlib.h>         /* for atoi() */
31 #include <string.h>         /* for strcmp() */
32 #include <sys/resource.h>   /* for getrlimit() */
33 #include <sys/socket.h>     /* for socket() */
34 #include <sys/time.h>       /* for gettimeofday() */
35 #include <sys/types.h>      /* for socket() */
36 #include <unistd.h>         /* for close() */
37 
38 #ifdef LINUX
39 #include <netinet/ip.h>
40 #include <netinet/tcp.h>
41 #endif
42 #include <limits.h>
43 #include <math.h> /* for sqrt(), floor() */
44 
45 #if !defined FD_SETSIZE || FD_SETSIZE > 1024
46 #define GRAB_MAX_SOCK 1024
47 #else
48 #define GRAB_MAX_SOCK FD_SETSIZE
49 #endif
50 
51 #if !defined FD_SETSIZE || FD_SETSIZE > 32
52 #define GRAB_MIN_SOCK 32
53 #else
54 #define GRAB_MIN_SOCK FD_SETSIZE
55 #warn "FD_SETSIZE is lower than 32"
56 #endif
57 
58 #if !defined FD_SETSIZE || FD_SETSIZE > 128
59 #define GRAB_MAX_SOCK_SAFE 128
60 #else
61 #define GRAB_MAX_SOCK_SAFE FD_SETSIZE
62 #warn "FD_SETSIZE is lower than 128"
63 #endif
64 
65 #define MAX_PASS_NB 16
66 
67 #ifndef MAXINT
68 #define MAXINT 0x7fffffffL
69 #endif
70 
71 #undef G_LOG_DOMAIN
72 /**
73  * @brief GLib logging domain.
74  */
75 #define G_LOG_DOMAIN "lib  nasl"
76 
77 typedef struct
78 {
79   int fd;
80   struct timeval tictac; /* open time */
81   unsigned short port;
82   unsigned char state;
83 } grab_socket_t;
84 
85 #define DIFFTV(t1, t2) \
86   (t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)
87 #define DIFFTVu(t1, t2) \
88   ((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))
89 
90 #define GRAB_SOCKET_UNUSED 0
91 #define GRAB_SOCKET_OPENING 1
92 #define GRAB_SOCKET_OPEN 2
93 
94 #define GRAB_PORT_UNKNOWN 0
95 #define GRAB_PORT_CLOSED 1
96 #define GRAB_PORT_OPEN 2
97 #define GRAB_PORT_SILENT 3
98 #define GRAB_PORT_REJECTED 4
99 #define GRAB_PORT_NOT_TESTED 254
100 #define GRAB_PORT_TESTING 255
101 
102 #define COMPUTE_RTT
103 /*
104  * RTT is always estimated (at least, the maximum is remembered)
105  * If you want to enable the "statistics", define COMPUTE_RTT and link
106  * the plugin with libm (we need sqrt)
107  */
108 /* Linux re-sends a SYN packet after 3 s
109  * anyway, I don't think that we can have a RTT bigger than 2 s
110  */
111 #define MAX_SANE_RTT 2000000 /* micro-seconds */
112 
113 static int
my_socket_close(int s)114 my_socket_close (int s)
115 {
116 #ifndef SO_LINGER
117   shutdown (s, 2);
118 #endif
119   return close (s);
120 }
121 
122 static int
std_port(int port)123 std_port (int port)
124 {
125   (void) port;
126   return 0; /** @todo: We are not able anymore to judge whether a port is a
127              * standard port. Previously a port was believed to be a standard
128              * port when it occurred in the currently configured list of ports.
129              * This needs to be resolved.
130              */
131 }
132 
133 static int
double_check_std_ports(unsigned char * ports_states)134 double_check_std_ports (unsigned char *ports_states)
135 {
136   int port, tbd_nb = 0;
137 
138   for (port = 1; port <= 65535; port++)
139     if (std_port (port) && ports_states[port] == GRAB_PORT_SILENT)
140       {
141         ports_states[port] = GRAB_PORT_UNKNOWN;
142         tbd_nb++;
143       }
144     else if (ports_states[port] == GRAB_PORT_UNKNOWN)
145       {
146         g_message ("openvas_tcp_scanner: bug in double_check_std_ports!"
147                    " Unknown port %d status",
148                    port);
149         tbd_nb++;
150       }
151   return tbd_nb;
152 }
153 
154 static int
banner_grab(const struct in6_addr * pia,const char * portrange,const int read_timeout,int min_cnx,int max_cnx,struct script_infos * desc)155 banner_grab (const struct in6_addr *pia, const char *portrange,
156              const int read_timeout, int min_cnx, int max_cnx,
157              struct script_infos *desc)
158 {
159   char buf[2048], kb[64];
160   int s, tcpproto, pass;
161   struct protoent *proto;
162   fd_set rfs, wfs, efs;
163   struct timeval timeout, ti;
164   struct sockaddr_in sa;
165   struct sockaddr_in6 sa6;
166   int len;
167   int retval;
168   int port = 23;
169   int imax, i, j, scanned_ports, x, opt;
170   unsigned int optsz;
171   int minport;
172   unsigned char ports_states[65536];
173   grab_socket_t sockets[GRAB_MAX_SOCK];
174   int open_sock_nb, open_sock_max, open_sock_max2;
175   int unfiltered_ports_nb, filtered_ports_nb;
176   int dropped_nb, timeout_nb, dropped_flag = 0;
177   int old_filtered = -1, old_opened = -1;
178   int open_ports_nb, closed_ports_nb;
179   int untested_ports_nb, total_ports_nb;
180   int cnx_max[3], rtt_max[3], rtt_min[3], ping_rtt = 0;
181 #if defined COMPUTE_RTT
182   double rtt_sum[3], rtt_sum2[3];
183   int rtt_nb[3];
184   static const char *rtt_type[] = {"unfiltered", "open", "closed"};
185 #endif
186   time_t start_time = time (NULL), start_time_1pass, end_time;
187   long diff_time, diff_time1;
188   int rst_rate_limit_flag = 0, doublecheck_flag = 0;
189 #if defined COMPUTE_RTT
190   double mean, sd = -1.0, emax = -1.0;
191 #endif
192 
193   proto = getprotobyname ("tcp");
194   if (proto == NULL)
195     {
196       perror ("tcp");
197       return -1;
198     }
199   tcpproto = proto->p_proto;
200 
201   for (i = 0; i < (int) (sizeof (ports_states) / sizeof (*ports_states)); i++)
202     ports_states[i] = GRAB_PORT_NOT_TESTED;
203   scanned_ports = 0;
204   for (i = 0; i < 3; i++)
205     {
206 #if defined COMPUTE_RTT
207       rtt_sum[i] = rtt_sum2[i] = 0.0;
208       rtt_nb[i] = 0;
209 #endif
210       rtt_max[i] = cnx_max[i] = 0;
211       rtt_min[i] = MAXINT;
212     }
213 
214   {
215     char *k;
216     int type = 0;
217     k = plug_get_key (desc, "/tmp/ping/RTT", &type, NULL, 0);
218     if (type == ARG_STRING && k != NULL)
219       ping_rtt = atoi (k);
220     else if (type == ARG_INT)
221       ping_rtt = GPOINTER_TO_SIZE (k);
222     else if (type >= 0)
223       g_message ("openvas_tcp_scanner: unknown key type %d", type);
224     g_free (k);
225     if (ping_rtt < 0 || ping_rtt > MAX_SANE_RTT)
226       ping_rtt = 0;
227   }
228 
229   {
230     char *p, *q;
231     int po1, po2 = 0;
232     p = (char *) portrange;
233     untested_ports_nb = 0;
234 
235     if (p)
236       while (*p != '\0')
237         {
238           while (*p == ',')
239             p++;
240 
241           /* Scanner accepts only T:1-3,6,U:103-333,770 due to getpts. */
242 
243           if (*p == 'T' && p[1] && p[1] == ':')
244             /* Skip over the leading "T:". */
245             p += 2;
246           else if (*p == 'U' && p[1] && p[1] == ':')
247             /* "U:" for UDP.  Skip the rest. */
248             break;
249 
250           if (*p == '-')
251             {
252               po1 = 1;
253               q = p + 1;
254               po2 = strtol (q, &p, 10);
255               if (q == p)
256                 {
257                   g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
258                   return -1;
259                 }
260             }
261           else
262             {
263               po1 = strtol (p, &q, 10);
264               if (q == p)
265                 {
266                   g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
267                   return -1;
268                 }
269               if (*q == ',')
270                 {
271                   p = q + 1;
272                   po2 = po1;
273                 }
274               else if (*q == '\0')
275                 {
276                   p = q;
277                   po2 = po1;
278                 }
279               else if (*q == '-')
280                 {
281                   if (q[1] == '\0')
282                     {
283                       po2 = 65535;
284                       p = q + 1;
285                     }
286                   else
287                     {
288                       po2 = strtol (q + 1, &p, 10);
289                       if (q + 1 == p)
290                         {
291                           g_message ("openvas_tcp_scanner: Cannot parse '%s'",
292                                      p);
293                           return -1;
294                         }
295                     }
296                 }
297             }
298           for (i = po1; i <= po2; i++)
299             {
300               ports_states[i] = GRAB_PORT_UNKNOWN;
301               untested_ports_nb++;
302             }
303         }
304     else
305       {
306         g_message ("openvas_tcp_scanner: port list empty");
307         return -1;
308       }
309   }
310 
311   for (i = 0; i < max_cnx; i++)
312     {
313       sockets[i].state = GRAB_SOCKET_UNUSED;
314       sockets[i].fd = -1;
315     }
316 
317   open_sock_nb = 0;
318   open_sock_max = min_cnx;
319   open_sock_max2 = max_cnx;
320 
321   open_ports_nb = closed_ports_nb = filtered_ports_nb = unfiltered_ports_nb = 0;
322 
323   for (pass = 1; pass <= MAX_PASS_NB; pass++)
324     {
325       int open_ports_nb1 = 0, closed_ports_nb1 = 0;
326       int wait_sock_nb = 0;
327 
328       minport = 1;
329       start_time_1pass = time (NULL);
330       FD_ZERO (&rfs);
331       FD_ZERO (&wfs);
332       imax = -1;
333 
334       while (scanned_ports < 65535)
335         {
336           total_ports_nb =
337             unfiltered_ports_nb + filtered_ports_nb + untested_ports_nb;
338           while (open_sock_nb < open_sock_max)
339             {
340               for (port = minport;
341                    port <= 65535 && ports_states[port] != GRAB_PORT_UNKNOWN;
342                    port++)
343                 ;
344               if (port > 65535)
345                 break;
346               minport = port;
347 
348               ports_states[port] = GRAB_PORT_TESTING;
349               if (IN6_IS_ADDR_V4MAPPED (pia))
350                 {
351                   s = socket (PF_INET, SOCK_STREAM, tcpproto);
352                 }
353               else
354                 {
355                   s = socket (PF_INET6, SOCK_STREAM, tcpproto);
356                 }
357               if (s < 0)
358                 {
359                   if (errno == ENFILE) /* File table overflow */
360                     {
361                       open_sock_max = open_sock_max2 = open_sock_nb / 2 - 1;
362                       /* NB: if open_sock_max2 < 0, the scanner aborts */
363                       /* DEBUG: otherwise, we print a less frigthtening message
364                        */
365                       continue;
366                     }
367                   else if (errno == EMFILE) /* Too many open files */
368                     {
369                       x = open_sock_nb / 16; /* 6.25% */
370                       open_sock_max = open_sock_max2 =
371                         open_sock_nb - (x > 0 ? x : 1);
372                       /* NB: if open_sock_max2 < 0, the scanner aborts */
373                       /* DEBUG: otherwise, we print a less frigthtening message
374                        */
375                       continue;
376                     }
377                   else
378                     {
379                       perror ("socket");
380                       return -1;
381                     }
382                 }
383 #if defined FD_SETSIZE
384               if (s >= FD_SETSIZE)
385                 {
386                   open_sock_max--;
387                   open_sock_max2--;
388                   if (close (s) < 0)
389                     perror ("close");
390                   continue;
391                 }
392 #endif
393 
394               if ((x = fcntl (s, F_GETFL)) < 0)
395                 {
396                   perror ("fcntl(F_GETFL)");
397                   close (s);
398                   return -1;
399                 }
400               if (fcntl (s, F_SETFL, x | O_NONBLOCK) < 0)
401                 {
402                   perror ("fcntl(F_SETFL)");
403                   close (s);
404                   return -1;
405                 }
406 
407 #ifdef SO_LINGER
408               {
409                 struct linger l;
410 
411                 l.l_onoff = 0;
412                 l.l_linger = 0;
413                 if (setsockopt (s, SOL_SOCKET, SO_LINGER, &l, sizeof (l)) < 0)
414                   perror ("setsockopt(SO_LINGER)");
415               }
416 #endif
417 #if defined LINUX && defined IPTOS_RELIABILITY
418               /*
419                * IP TOS (RFC791) is obsoleted by RFC2474
420                * RFC3168 deprecates IPTOS_MINCOST, as it conflicts with
421                * the "ECN capable" flags
422                */
423               x = IPTOS_RELIABILITY;
424               if (setsockopt (s, SOL_IP, IP_TOS, &x, sizeof (x)) < 0)
425                 perror ("setsockopt(IP_TOS");
426 #endif
427               bzero (&sa, sizeof (sa));
428               bzero (&sa6, sizeof (sa6));
429               if (IN6_IS_ADDR_V4MAPPED (pia))
430                 {
431                   sa.sin_addr.s_addr = pia->s6_addr[12];
432                   sa.sin_family = AF_INET;
433                   sa.sin_port = htons (port);
434                   len = sizeof (struct sockaddr_in);
435                   retval = connect (s, (struct sockaddr *) &sa, len);
436                 }
437               else
438                 {
439                   memcpy (&sa6.sin6_addr, pia, sizeof (struct in6_addr));
440                   sa6.sin6_family = AF_INET6;
441                   sa6.sin6_port = htons (port);
442                   len = sizeof (struct sockaddr_in6);
443                   retval = connect (s, (struct sockaddr *) &sa6, len);
444                 }
445               if (retval < 0)
446                 {
447                   switch (errno)
448                     {
449                     case EINPROGRESS:
450                     case EALREADY:
451                       sockets[open_sock_nb].fd = s;
452                       sockets[open_sock_nb].port = port;
453                       sockets[open_sock_nb].state = GRAB_SOCKET_OPENING;
454                       (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
455                       open_sock_nb++;
456                       FD_SET (s, &wfs);
457                       if (s > imax)
458                         imax = s;
459                       break;
460 
461                     case EAGAIN:
462                       x = open_sock_nb / 16; /* 6.25% */
463                       open_sock_max = open_sock_max2 =
464                         open_sock_nb - (x > 0 ? x : 1);
465                       /* If open_sock_max2 < 0, the scanner aborts */
466                       continue;
467 
468                     case ECONNREFUSED:
469                       ports_states[port] = GRAB_PORT_CLOSED;
470                       my_socket_close (s);
471                       unfiltered_ports_nb++;
472                       closed_ports_nb++;
473                       closed_ports_nb1++;
474                       untested_ports_nb--;
475                       continue;
476 
477                     case ENETUNREACH:
478                     case EHOSTUNREACH:
479                       ports_states[port] = GRAB_PORT_REJECTED;
480                       my_socket_close (s);
481                       filtered_ports_nb++;
482                       untested_ports_nb--;
483                       continue;
484 
485                     default:
486                       perror ("connect");
487                       return -1;
488                     }
489                 }
490               else /* This should not happen! */
491                 {
492                   sockets[open_sock_nb].fd = s;
493                   sockets[open_sock_nb].port = port;
494                   sockets[open_sock_nb].state = GRAB_SOCKET_OPEN;
495                   (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
496                   open_sock_nb++;
497                   ports_states[port] = GRAB_PORT_OPEN;
498                   unfiltered_ports_nb++;
499                   open_ports_nb++;
500                   open_ports_nb1++;
501                   wait_sock_nb++;
502                   untested_ports_nb--;
503                   scanner_add_port (desc, port, "tcp");
504                 }
505               if (imax >= 0)
506                 {
507                   timeout.tv_sec = timeout.tv_usec = 0;
508                   if (select (imax + 1, NULL, &wfs, NULL, &timeout) > 0)
509                     break;
510                 }
511             }
512 
513           if (open_sock_max2 <= 0) /* file table is full */
514             return -1;
515 
516           if (open_sock_nb == 0)
517             goto end;
518 
519           FD_ZERO (&rfs);
520           FD_ZERO (&wfs);
521           FD_ZERO (&efs);
522           imax = -1;
523 
524           for (i = 0; i < open_sock_nb; i++)
525             {
526               if (sockets[i].fd >= 0)
527                 {
528                   switch (sockets[i].state)
529                     {
530                     case GRAB_SOCKET_OPEN:
531                       FD_SET (sockets[i].fd, &rfs);
532                       break;
533                     case GRAB_SOCKET_OPENING:
534                       FD_SET (sockets[i].fd, &wfs);
535                       break;
536                     default:
537                       break;
538                     }
539                   if (sockets[i].fd > imax)
540                     imax = sockets[i].fd;
541                 }
542             }
543 
544           if (imax < 0)
545             {
546               if (untested_ports_nb > 0)
547                 return -1;
548               else
549                 goto end;
550             }
551 
552           timeout_nb = 0;
553           dropped_nb = 0;
554           dropped_flag = 0;
555 #if defined COMPUTE_RTT
556           if (rtt_nb[0] > 1)
557             {
558               /* All values are in micro-seconds */
559               int em, moy;
560 
561               mean = rtt_sum[0] / (double) rtt_nb[0];
562               if ((double) rtt_max[0] > mean)
563                 {
564                   sd = sqrt ((rtt_sum2[0] / rtt_nb[0] - mean * mean)
565                              * (double) rtt_nb[0] / (rtt_nb[0] - 1));
566                   emax = mean + 3 * sd;
567                   em = floor (emax + 0.5);
568                   moy = floor (rtt_sum[0] / rtt_nb[0] + 0.5);
569                   if (em <= moy)
570                     em = moy;
571                   if (rtt_max[0] > em)
572                     rtt_max[0] = em;
573                 }
574               if (rtt_max[0] < rtt_min[0])
575                 rtt_max[0] = rtt_min[0];
576             }
577 #endif
578           /*
579            * Some randomness is added to the timeout so that not all
580            * scanners fire at the same time when several firewalled
581            * machines are scanned in parallel.
582            */
583           if (wait_sock_nb == 0)
584             if (rtt_max[0] > 0 || ping_rtt > 0)
585               {
586                 if (rtt_max[0] > 0)
587                   x = rtt_max[0];
588                 else
589                   x = ping_rtt;
590 
591                 if (doublecheck_flag)
592                   {
593                     x = 3 * x + 20000;
594                     if (x > MAX_SANE_RTT)
595                       x = MAX_SANE_RTT;
596                   }
597                 if (x > 1000000) /* more that 1 s */
598                   x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 100000;
599                 else if (x > 20000) /* between 20 ms and 1 s */
600                   x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 50000;
601                 else /* less than 20 ms */
602                   x = 20000 + (unsigned) (lrand48 () & 0x7FFFFFFF) % 20000;
603                 timeout.tv_sec = x / 1000000;
604                 timeout.tv_usec = x % 1000000;
605               }
606             else
607               {
608                 /* Max RTT = 2 s ? */
609                 timeout.tv_sec = 2;
610                 timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 250000;
611               }
612           else
613             {
614               timeout.tv_sec = read_timeout; /* * 2 ? */
615               timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 500000;
616             }
617           i = 0;
618           do
619             x = select (imax + 1, &rfs, &wfs, NULL, &timeout);
620           while (i++ < 10 && x < 0 && errno == EINTR);
621 
622           if (x < 0)
623             {
624               perror ("select");
625               return -1;
626             }
627           else if (x == 0) /* timeout */
628             {
629               for (i = 0; i < open_sock_nb; i++)
630                 {
631                   if (sockets[i].fd > 0)
632                     {
633                       my_socket_close (sockets[i].fd);
634                       sockets[i].fd = -1;
635                       switch (sockets[i].state)
636                         {
637                         case GRAB_SOCKET_OPENING:
638                           ports_states[sockets[i].port] = GRAB_PORT_SILENT;
639                           filtered_ports_nb++;
640                           dropped_nb++;
641                           untested_ports_nb--;
642                           break;
643                         case GRAB_SOCKET_OPEN:
644                           wait_sock_nb--;
645                           break;
646                         }
647                     }
648                   sockets[i].state = GRAB_SOCKET_UNUSED;
649                 }
650             }
651           else /* something to do */
652             {
653               (void) gettimeofday (&ti, NULL);
654               for (i = 0; i < open_sock_nb; i++)
655                 {
656                   if (sockets[i].fd > 0)
657                     {
658                       if (FD_ISSET (sockets[i].fd, &wfs))
659                         {
660                           opt = 0;
661                           optsz = sizeof (opt);
662                           if (getsockopt (sockets[i].fd, SOL_SOCKET, SO_ERROR,
663                                           &opt, &optsz)
664                               < 0)
665                             {
666                               perror ("getsockopt");
667                               return -1;
668                             }
669 
670                           x = DIFFTVu (ti, sockets[i].tictac);
671                           if (opt != 0)
672                             {
673                               errno = opt;
674                               if (x > cnx_max[2])
675                                 cnx_max[2] = x;
676                               if (x < rtt_min[2])
677                                 rtt_min[2] = x;
678                               if (x < MAX_SANE_RTT)
679                                 {
680                                   if (x > rtt_max[2])
681                                     rtt_max[2] = x;
682 #if defined COMPUTE_RTT
683                                   rtt_nb[2]++;
684                                   rtt_sum[2] += (double) x;
685                                   rtt_sum2[2] += (double) x * (double) x;
686 #endif
687                                 }
688 
689                               my_socket_close (sockets[i].fd);
690                               sockets[i].fd = -1;
691                               sockets[i].state = GRAB_SOCKET_UNUSED;
692 
693                               untested_ports_nb--;
694                               switch (opt)
695                                 {
696                                 case ENETUNREACH:
697                                 case EHOSTUNREACH:
698                                   ports_states[sockets[i].port] =
699                                     GRAB_PORT_REJECTED;
700                                   filtered_ports_nb++;
701                                   break;
702 
703                                 case ECONNREFUSED:
704                                 default:
705                                   ports_states[sockets[i].port] =
706                                     GRAB_PORT_CLOSED;
707                                   unfiltered_ports_nb++;
708                                   closed_ports_nb++;
709                                   closed_ports_nb1++;
710                                   break;
711                                 }
712                             }
713                           else
714                             {
715                               sockets[i].state = GRAB_SOCKET_OPEN;
716                               if (x > cnx_max[1])
717                                 cnx_max[1] = x;
718                               if (x < rtt_min[1])
719                                 rtt_min[1] = x;
720                               if (x < MAX_SANE_RTT)
721                                 {
722                                   if (x > rtt_max[1])
723                                     rtt_max[1] = x;
724 #if defined COMPUTE_RTT
725                                   rtt_nb[1]++;
726                                   rtt_sum[1] += (double) x;
727                                   rtt_sum2[1] += (double) x * (double) x;
728 #endif
729                                 }
730 
731                               unfiltered_ports_nb++;
732                               open_ports_nb++;
733                               open_ports_nb1++;
734                               untested_ports_nb--;
735                               ports_states[sockets[i].port] = GRAB_PORT_OPEN;
736                               scanner_add_port (desc, sockets[i].port, "tcp");
737                               wait_sock_nb++;
738                               snprintf (kb, sizeof (kb),
739                                         "TCPScanner/CnxTime1000/%u",
740                                         sockets[i].port);
741                               plug_set_key (desc, kb, ARG_INT,
742                                             GSIZE_TO_POINTER (x / 1000));
743                               snprintf (kb, sizeof (kb),
744                                         "TCPScanner/CnxTime/%u",
745                                         sockets[i].port);
746                               plug_set_key (
747                                 desc, kb, ARG_INT,
748                                 GSIZE_TO_POINTER ((x + 500000) / 1000000));
749                               sockets[i].tictac = ti;
750                             }
751                           if (x > cnx_max[0])
752                             cnx_max[0] = x;
753                           if (x < rtt_min[0])
754                             rtt_min[0] = x;
755                           if (x < MAX_SANE_RTT)
756                             {
757                               if (x > rtt_max[0])
758                                 rtt_max[0] = x;
759 #if defined COMPUTE_RTT
760                               rtt_nb[0]++;
761                               rtt_sum[0] += (double) x;
762                               rtt_sum2[0] += (double) x * (double) x;
763 #endif
764                             }
765                         }
766                       else if (FD_ISSET (sockets[i].fd, &rfs))
767                         {
768                           x = read (sockets[i].fd, buf, sizeof (buf) - 1);
769                           if (x > 0)
770                             {
771                               char buf2[sizeof (buf) * 2 + 1];
772                               int y, flag = 0;
773 
774                               for (y = 0; y < x; y++)
775                                 {
776                                   sprintf (buf2 + 2 * y, "%02x",
777                                            (unsigned char) buf[y]);
778                                   if (buf[y] == '\0')
779                                     flag = 1;
780                                 }
781                               buf2[2 * x - 1] = '\0';
782                               if (flag)
783                                 {
784                                   snprintf (kb, sizeof (kb), "BannerHex/%u",
785                                             sockets[i].port);
786                                   plug_set_key (desc, kb, ARG_STRING, buf2);
787                                 }
788 
789                               buf[x] = '\0';
790                               snprintf (kb, sizeof (kb), "Banner/%u",
791                                         sockets[i].port);
792                               plug_set_key (desc, kb, ARG_STRING, buf);
793                               x = DIFFTVu (ti, sockets[i].tictac) / 1000;
794                               snprintf (kb, sizeof (kb),
795                                         "TCPScanner/RwTime1000/%u",
796                                         sockets[i].port);
797                               plug_set_key (desc, kb, ARG_INT,
798                                             GSIZE_TO_POINTER (x));
799                               snprintf (kb, sizeof (kb), "TCPScanner/RwTime/%u",
800                                         sockets[i].port);
801                               plug_set_key (
802                                 desc, kb, ARG_INT,
803                                 GSIZE_TO_POINTER ((x + 500) / 1000));
804                             }
805                           wait_sock_nb--;
806                           my_socket_close (sockets[i].fd);
807                           sockets[i].fd = -1;
808                           sockets[i].state = GRAB_SOCKET_UNUSED;
809                         }
810                     }
811                 }
812             }
813 
814           (void) gettimeofday (&ti, NULL);
815           for (i = 0; i < open_sock_nb; i++)
816             if (sockets[i].fd >= 0
817                 && DIFFTV (ti, sockets[i].tictac) >= read_timeout)
818               {
819                 switch (sockets[i].state)
820                   {
821                   case GRAB_SOCKET_OPEN:
822                     timeout_nb++;
823                     wait_sock_nb--;
824                     snprintf (kb, sizeof (kb), "/tmp/NoBanner/%u",
825                               sockets[i].port);
826                     plug_set_key (desc, kb, ARG_INT, (void *) 1);
827                     break;
828                   case GRAB_SOCKET_OPENING:
829                     ports_states[sockets[i].port] = GRAB_PORT_SILENT;
830                     filtered_ports_nb++;
831                     dropped_nb++;
832                     untested_ports_nb--;
833                     break;
834                   default:
835                     g_message (
836                       "openvas_tcp_scanner: Unhandled case %d at %s:%d",
837                       sockets[i].state, __FILE__, __LINE__);
838                     break;
839                   }
840                 my_socket_close (sockets[i].fd);
841                 sockets[i].fd = -1;
842                 sockets[i].state = GRAB_SOCKET_UNUSED;
843               }
844 
845           if (dropped_nb > 0 && dropped_nb >= (open_sock_nb * 3) / 4
846               && (dropped_nb < filtered_ports_nb
847                   || dropped_nb > unfiltered_ports_nb))
848             {
849               /* firewalled machine? */
850               open_sock_max += dropped_nb;
851               if (open_sock_max2 < max_cnx)
852                 open_sock_max2++;
853             }
854           else if (dropped_nb > 0)
855             {
856               dropped_flag = 1;
857               open_sock_max -= (dropped_nb + 2) / 3;
858               if (open_sock_max < min_cnx)
859                 open_sock_max = min_cnx;
860               open_sock_max2 = (open_sock_max + 3 * open_sock_max2) / 4;
861             }
862           else if (dropped_nb == 0 && dropped_flag)
863             {
864               /* re-increase number of open sockets */
865               open_sock_max++;
866             }
867           open_sock_max += timeout_nb;
868           if (open_sock_max > open_sock_max2)
869             {
870               open_sock_max = open_sock_max2;
871             }
872           if (open_sock_max < min_cnx)
873             open_sock_max = min_cnx;
874           for (i = 0; i < open_sock_nb;)
875             if (sockets[i].state == GRAB_SOCKET_UNUSED || sockets[i].fd < 0)
876               {
877                 for (j = i + 1; j < open_sock_nb
878                                 && (sockets[j].state == GRAB_SOCKET_UNUSED
879                                     || sockets[j].fd < 0);
880                      j++)
881                   ;
882                 if (j < open_sock_nb)
883                   memmove (sockets + i, sockets + j,
884                            sizeof (*sockets) * (max_cnx - j));
885                 open_sock_nb -= j - i;
886               }
887             else
888               i++;
889         }
890 
891     end:
892       end_time = time (NULL);
893       diff_time1 = end_time - start_time_1pass;
894       diff_time = end_time - start_time;
895       if (dropped_flag
896           || (pass == 1 && filtered_ports_nb > 10 && closed_ports_nb > 10)
897           || (pass > 1 && filtered_ports_nb > 0))
898         {
899           if (doublecheck_flag && rst_rate_limit_flag
900               && open_ports_nb == old_opened)
901             break;
902           old_opened = open_ports_nb;
903 
904           doublecheck_flag = 0;
905           if (filtered_ports_nb == old_filtered)
906             break;
907 
908           if (pass > 1 && open_ports_nb1 == 0 && closed_ports_nb1 >= min_cnx &&
909               /*
910                * Default value is 100 RST per second on OpenBSD,
911                * 200 on FreeBSD and 40 on Solaris
912                */
913               /* 1st check on this pass only */
914               closed_ports_nb1 >= (diff_time1 + 1) * 10
915               && closed_ports_nb1 < (diff_time1 + 1) * 201 &&
916               /* 2nd check on all passes */
917               closed_ports_nb >= (diff_time + 1) * 10
918               && closed_ports_nb < (diff_time + 1) * 201)
919             {
920               /* BSD-like system */
921               int break_flag =
922                 (open_sock_max2 <= GRAB_MAX_SOCK_SAFE) || rst_rate_limit_flag;
923               int tbd = break_flag && !doublecheck_flag
924                           ? double_check_std_ports (ports_states)
925                           : 0;
926               if (tbd > 0)
927                 {
928                   doublecheck_flag = 1;
929                   break_flag = 0;
930                 }
931               rst_rate_limit_flag++;
932               if (break_flag)
933                 break;
934             }
935           /*
936            * With doublecheck_flag, the range of tested port is different, so
937            * we'd better count the number of filtered ports
938            */
939           old_filtered = 0;
940           for (port = 1; port <= 65535; port++)
941             if (ports_states[port] == GRAB_PORT_SILENT)
942               {
943                 ports_states[port] = GRAB_PORT_UNKNOWN;
944                 old_filtered++;
945               }
946           untested_ports_nb = old_filtered;
947           filtered_ports_nb = 0;
948           open_sock_max = min_cnx / (pass + 1);
949           if (open_sock_max < 1)
950             open_sock_max = 1;
951           if (!dropped_flag)
952             {
953               open_sock_max2 *= 2;
954               open_sock_max2 /= 3;
955             }
956           else if (rst_rate_limit_flag)
957             {
958               if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
959                 open_sock_max2 = GRAB_MAX_SOCK_SAFE;
960               if (open_sock_max > GRAB_MAX_SOCK_SAFE)
961                 open_sock_max = GRAB_MAX_SOCK_SAFE;
962             }
963           else if (open_sock_max2 <= open_sock_max)
964             open_sock_max2 = open_sock_max * 2;
965         }
966       else if (filtered_ports_nb > 0)
967         {
968           int tbd_nb = 0;
969           doublecheck_flag = 1;
970           /* Double check standard ports, just to avoid being ridiculous */
971 
972           if ((tbd_nb = double_check_std_ports (ports_states)) == 0)
973             break;
974           old_filtered = untested_ports_nb = tbd_nb;
975           filtered_ports_nb = 0;
976           open_sock_max = min_cnx / pass;
977           if (open_sock_max2 <= open_sock_max)
978             open_sock_max2 = open_sock_max * 2;
979           if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
980             open_sock_max2 = GRAB_MAX_SOCK_SAFE;
981           if (open_sock_max > GRAB_MAX_SOCK_SAFE)
982             open_sock_max = GRAB_MAX_SOCK_SAFE;
983         }
984       else
985         break;
986     } /* for pass = ... */
987 
988   if (pass > MAX_PASS_NB)
989     {
990       pass--;
991       filtered_ports_nb = old_filtered;
992     }
993 
994   plug_set_key (desc, "TCPScanner/NbPasses", ARG_INT, GSIZE_TO_POINTER (pass));
995 
996 #if defined COMPUTE_RTT
997   for (i = 0; i < 3; i++)
998     if (rtt_nb[i] > 0)
999       {
1000         char rep[64];
1001         double mean, sd = -1.0, emax = -1.0;
1002 
1003         /* Convert from micro-seconds to seconds */
1004         rtt_sum[i] /= 1e6;
1005         rtt_sum2[i] /= 1e12;
1006 
1007         mean = rtt_sum[i] / rtt_nb[i];
1008         snprintf (rep, sizeof (rep), "%6g", mean);
1009         snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT", rtt_type[i]);
1010         plug_set_key (desc, kb, ARG_STRING, rep);
1011         x = floor (mean * 1000 + 0.5);
1012         snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT1000", rtt_type[i]);
1013         plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1014         /* rtt_max is integer (uS) */
1015         snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT1000", rtt_type[i]);
1016         plug_set_key (desc, kb, ARG_INT,
1017                       GSIZE_TO_POINTER ((rtt_max[i] + 500) / 1000));
1018         snprintf (rep, sizeof (rep), "%6g",
1019                   (rtt_max[i] + 500000.0) / 1000000.0);
1020         snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT", rtt_type[i]);
1021         plug_set_key (desc, kb, ARG_STRING, rep);
1022         if (rtt_nb[i] > 1)
1023           {
1024             sd = sqrt ((rtt_sum2[i] / rtt_nb[i] - mean * mean) * rtt_nb[i]
1025                        / (rtt_nb[i] - 1));
1026             emax = mean + 3 * sd;
1027             snprintf (rep, sizeof (rep), "%6g", sd);
1028             snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT", rtt_type[i]);
1029             plug_set_key (desc, kb, ARG_STRING, rep);
1030             x = floor (sd * 1000 + 0.5);
1031             snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT1000", rtt_type[i]);
1032             plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1033             snprintf (rep, sizeof (rep), "%6g", emax);
1034             snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT",
1035                       rtt_type[i]);
1036             plug_set_key (desc, kb, ARG_STRING, rep);
1037             x = floor (emax * 1000 + 0.5);
1038             snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT1000",
1039                       rtt_type[i]);
1040             plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1041           }
1042       }
1043 #endif
1044   plug_set_key (desc, "TCPScanner/OpenPortsNb", ARG_INT,
1045                 GSIZE_TO_POINTER (open_ports_nb));
1046   plug_set_key (desc, "TCPScanner/ClosedPortsNb", ARG_INT,
1047                 GSIZE_TO_POINTER (closed_ports_nb));
1048   plug_set_key (desc, "TCPScanner/FilteredPortsNb", ARG_INT,
1049                 GSIZE_TO_POINTER (filtered_ports_nb));
1050   plug_set_key (desc, "TCPScanner/RSTRateLimit", ARG_INT,
1051                 GSIZE_TO_POINTER (rst_rate_limit_flag));
1052   if (untested_ports_nb <= 0)
1053     plug_set_key (desc, "Host/full_scan", ARG_INT, GSIZE_TO_POINTER (1));
1054   plug_set_key (desc, "Host/num_ports_scanned", ARG_INT,
1055                 GSIZE_TO_POINTER ((total_ports_nb - untested_ports_nb)));
1056   return 0;
1057 }
1058 
1059 tree_cell *
plugin_run_openvas_tcp_scanner(lex_ctxt * lexic)1060 plugin_run_openvas_tcp_scanner (lex_ctxt *lexic)
1061 {
1062   struct script_infos *desc = lexic->script_infos;
1063   const char *port_range = prefs_get ("port_range");
1064   const char *p;
1065   struct in6_addr *p_addr;
1066   unsigned int timeout = 0, max_cnx, min_cnx, x;
1067   int safe_checks = prefs_get_bool ("safe_checks");
1068 
1069   p = prefs_get ("checks_read_timeout");
1070   if (p != NULL)
1071     timeout = atoi (p);
1072   if (timeout <= 0)
1073     timeout = 5;
1074   {
1075     int max_host = 0, max_checks = 0, cur_sys_fd = 0, max_sys_fd = 0;
1076     struct rlimit rlim;
1077     FILE *fp;
1078     int i;
1079     double loadavg[3], maxloadavg = -1.0;
1080     int stderr_fd = dup (2);
1081     int devnull_fd = open ("/dev/null", O_WRONLY);
1082     /* Avoid error messages from sysctl */
1083     if (devnull_fd <= 0)
1084       {
1085         if (stderr_fd != -1)
1086           close (stderr_fd);
1087         return NULL;
1088       }
1089     dup2 (devnull_fd, 2);
1090 
1091     p = prefs_get ("max_hosts");
1092     if (p != NULL)
1093       max_host = atoi (p);
1094     if (max_host <= 0)
1095       max_host = 15;
1096 
1097     p = prefs_get ("max_checks");
1098     if (p != NULL)
1099       max_checks = atoi (p);
1100     if (max_checks <= 0 || max_checks > 5)
1101       {
1102         max_checks = 5; /* bigger values do not make sense */
1103         g_debug ("openvas_tcp_scanner: max_checks forced to %d", max_checks);
1104       }
1105 
1106     min_cnx = 8 * max_checks;
1107     if (safe_checks)
1108       max_cnx = 24 * max_checks;
1109     else
1110       max_cnx = 80 * max_checks;
1111 
1112     getloadavg (loadavg, 3);
1113     for (i = 0; i < 3; i++)
1114       if (loadavg[i] > maxloadavg)
1115         maxloadavg = loadavg[i];
1116 
1117     if (max_sys_fd <= 0)
1118       {
1119         fp = popen ("sysctl fs.file-nr", "r");
1120         if (fp != NULL)
1121           {
1122             if (fscanf (fp, "%*s = %*d %d %d", &cur_sys_fd, &max_sys_fd) == 1)
1123               max_sys_fd -= cur_sys_fd;
1124             else
1125               max_sys_fd = 0;
1126             pclose (fp);
1127           }
1128       }
1129     if (max_sys_fd <= 0)
1130       {
1131         fp = popen ("sysctl fs.file-max", "r");
1132         if (fp != NULL)
1133           {
1134             if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1135               max_sys_fd = 0;
1136             pclose (fp);
1137           }
1138       }
1139 
1140     if (max_sys_fd <= 0)
1141       {
1142         fp = popen ("sysctl kern.maxfiles", "r");
1143         if (fp != NULL)
1144           {
1145             if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1146               max_sys_fd = 0;
1147             pclose (fp);
1148           }
1149       }
1150 
1151     /* Restore stderr */
1152     close (devnull_fd);
1153     dup2 (stderr_fd, 2);
1154     close (stderr_fd);
1155 
1156     if (maxloadavg >= 0.0)
1157       max_cnx /= (1.0 + maxloadavg);
1158 
1159     if (max_sys_fd <= 0)
1160       max_sys_fd = 16384; /* reasonable default */
1161     /* Let's leave at least 1024 FD for other processes */
1162     if (max_sys_fd < 1024)
1163       x = GRAB_MIN_SOCK;
1164     else
1165       {
1166         max_sys_fd -= 1024;
1167         x = max_sys_fd / max_host;
1168       }
1169     if (max_cnx > x)
1170       max_cnx = x;
1171     if (max_cnx > GRAB_MAX_SOCK)
1172       max_cnx = GRAB_MAX_SOCK;
1173     if (max_cnx < GRAB_MIN_SOCK)
1174       max_cnx = GRAB_MIN_SOCK;
1175 
1176     if (safe_checks && max_cnx > GRAB_MAX_SOCK_SAFE)
1177       max_cnx = GRAB_MAX_SOCK_SAFE;
1178 
1179     if (getrlimit (RLIMIT_NOFILE, &rlim) < 0)
1180       perror ("getrlimit(RLIMIT_NOFILE)");
1181     else
1182       {
1183         /* value = one greater than the maximum  file  descriptor number */
1184         if (rlim.rlim_cur != RLIM_INFINITY && max_cnx >= rlim.rlim_cur)
1185           max_cnx = rlim.rlim_cur - 1;
1186       }
1187     x = max_cnx / 2;
1188     if (min_cnx > x)
1189       min_cnx = x > 0 ? x : 1;
1190   }
1191 
1192   p_addr = desc->ip;
1193   if (p_addr == NULL)
1194     return NULL; // TODO: before it returned "1";
1195   if (banner_grab (p_addr, port_range, timeout, min_cnx, max_cnx, desc) < 0)
1196     return NULL; // TODO: before it returned "1";
1197   plug_set_key (desc, "Host/scanned", ARG_INT, (void *) 1);
1198   plug_set_key (desc, "Host/scanners/openvas_tcp_scanner", ARG_INT, (void *) 1);
1199   return NULL;
1200 }
1201