OpenVAS Libraries  9.0.3
nasl_socket.c
Go to the documentation of this file.
1 /* openvas-libraries/nasl/nasl_socket.c
2  * $Id$
3  * Description: NASL socket API
4  *
5  * Authors:
6  * Unknown
7  * Werner Koch <wk@gnupg.org>
8  *
9  * Copyright:
10  * Copyright (C) 2002 - 2004 Tenable Network Security
11  * Copyright (C) 2012 Greenbone Networks GmbH
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2,
15  * as published by the Free Software Foundation
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  *
26  */
27 
39 /*--------------------------------------------------------------------------*/
40 #include <arpa/inet.h> /* for inet_aton */
41 #include <errno.h> /* for errno */
42 #include <fcntl.h> /* for fnctl */
43 #include <netinet/in.h> /* for sockaddr_in */
44 #include <string.h> /* for bzero */
45 #include <unistd.h> /* for close */
46 #include <stdlib.h> /* for atoi() */
47 #include <sys/time.h> /* for gettimeofday and timeval */
48 
49 #include <gnutls/gnutls.h>
50 
51 #include "../misc/network.h"
52 #include "../base/openvas_networking.h" /* for openvas_source_set_socket */
53 #include "../misc/plugutils.h" /* for plug_get_host_ip */
54 #include "../misc/openvas_logging.h"
55 #include "../misc/prefs.h" /* for prefs_get */
56 
57 #include "nasl.h"
58 
59 #include "nasl_tree.h"
60 #include "nasl_global_ctxt.h"
61 #include "nasl_func.h"
62 #include "nasl_var.h"
63 #include "nasl_lex_ctxt.h"
64 #include "exec.h"
65 
66 #include "nasl_packet_forgery.h"
67 #include "nasl_debug.h"
68 
69 #ifndef EADDRNOTAVAIL
70 #define EADDRNOTAVAIL EADDRINUSE
71 #endif
72 /*----------------------- Private functions ---------------------------*/
73 
74 static int
75 unblock_socket (int soc)
76 {
77  int flags = fcntl (soc, F_GETFL, 0);
78  if (flags < 0)
79  {
80  perror ("fcntl(F_GETFL)");
81  return -1;
82  }
83  if (fcntl (soc, F_SETFL, O_NONBLOCK | flags) < 0)
84  {
85  perror ("fcntl(F_SETFL,O_NONBLOCK)");
86  return -1;
87  }
88  return 0;
89 }
90 
91 static int
92 block_socket (int soc)
93 {
94  int flags = fcntl (soc, F_GETFL, 0);
95  if (flags < 0)
96  {
97  perror ("fcntl(F_GETFL)");
98  return -1;
99  }
100  if (fcntl (soc, F_SETFL, (~O_NONBLOCK) & flags) < 0)
101  {
102  perror ("fcntl(F_SETFL,~O_NONBLOCK)");
103  return -1;
104  }
105  return 0;
106 }
107 
108 static void
109 wait_before_next_probe ()
110 {
111  const char *time_between_request;
112  int minwaittime = 0;
113 
114  time_between_request = prefs_get ("time_between_request");
115  if (time_between_request)
116  minwaittime = atoi (time_between_request);
117 
118  if (minwaittime > 0)
119  {
120  static double lastprobesec = 0;
121  static double lastprobeusec = 0;
122  struct timeval tvnow, tvdiff;
123  double diff_msec;
124  int time2wait = 0;
125 
126  gettimeofday (&tvnow, NULL);
127  if (lastprobesec <= 0)
128  {
129  lastprobesec = tvnow.tv_sec - 10;
130  lastprobeusec = tvnow.tv_usec;
131  }
132 
133  tvdiff.tv_sec = tvnow.tv_sec - lastprobesec;
134  tvdiff.tv_usec = tvnow.tv_usec - lastprobeusec;
135  if (tvdiff.tv_usec <= 0)
136  {
137  tvdiff.tv_sec += 1;
138  tvdiff.tv_usec *= -1;
139  }
140 
141  diff_msec = tvdiff.tv_sec * 1000 + tvdiff.tv_usec / 1000;
142  time2wait = (minwaittime - diff_msec) * 1000;
143  if (time2wait > 0)
144  usleep (time2wait);
145 
146  gettimeofday (&tvnow, NULL);
147  lastprobesec = tvnow.tv_sec;
148  lastprobeusec = tvnow.tv_usec;
149  }
150 }
151 
152 /*
153  * NASL automatically re-send data when a recv() on a UDP packet
154  * fails. The point is to take care of packets lost en route.
155  *
156  * To do this, we store a copy of the data sent by a given socket
157  * each time send() is called, and we re-send() it each time
158  * recv() is called and fails
159  *
160  */
161 
162 struct udp_record {
163  int len;
164  char * data;
165 };
166 
167 /* add udp data in our cache */
168 static int
169 add_udp_data (struct arglist *script_infos, int soc, char *data, int len)
170 {
171  GHashTable * udp_data = arg_get_value (script_infos, "udp_data");
172  struct udp_record * data_record = g_malloc0 (sizeof(struct udp_record));
173  int * key = g_memdup (&soc, sizeof(int));
174 
175  data_record->len = len;
176  data_record->data = g_memdup ((gconstpointer)data, (guint)len);
177 
178  if (udp_data == NULL)
179  {
180  udp_data = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free);
181  arg_add_value (script_infos, "udp_data", ARG_PTR, udp_data);
182  }
183 
184  g_hash_table_replace (udp_data, (gpointer)key, (gpointer)data_record);
185 
186  return 0;
187 }
188 
189 /* get the udp data for socket <soc> */
190 static char *
191 get_udp_data (struct arglist *script_infos, int soc, int *len)
192 {
193  GHashTable *udp_data;
194  struct udp_record *data_record;
195 
196  if ((udp_data = arg_get_value (script_infos, "udp_data")) == NULL)
197  {
198  udp_data = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free);
199  arg_add_value (script_infos, "udp_data", ARG_PTR, udp_data);
200  return NULL;
201  }
202  data_record = g_hash_table_lookup (udp_data, (gconstpointer)&soc);
203 
204  if (!data_record) return NULL;
205 
206  *len = data_record->len;
207  return data_record->data;
208 }
209 
210 /* remove the udp data for socket <soc> */
211 static void
212 rm_udp_data (struct arglist *script_infos, int soc)
213 {
214  GHashTable * udp_data = arg_get_value (script_infos, "udp_data");
215 
216  if (udp_data)
217  g_hash_table_remove (udp_data, (gconstpointer)&soc);
218 }
219 
220 
221 /*-------------------------------------------------------------------*/
222 
224 
225 static tree_cell *
226 nasl_open_privileged_socket (lex_ctxt * lexic, int proto)
227 {
228  struct arglist *script_infos = lexic->script_infos;
229  int sport, current_sport = -1;
230  int dport;
231  int sock;
232  int e;
233  struct sockaddr_in addr, daddr;
234  struct sockaddr_in6 addr6, daddr6;
235  struct in6_addr *p;
236  int to = get_int_local_var_by_name (lexic, "timeout", lexic->recv_timeout);
237  tree_cell *retc;
238  struct timeval tv;
239  fd_set rd;
240  int opt;
241  unsigned int opt_sz;
242  int family;
243 
244 
245 
246  sport = get_int_local_var_by_name (lexic, "sport", -1);
247  dport = get_int_local_var_by_name (lexic, "dport", -1);
248  if (dport <= 0)
249  {
250  nasl_perror (lexic,
251  "open_private_socket: missing or undefined parameter dport!\n");
252  return NULL;
253  }
254 
255  if (sport < 0)
256  current_sport = 1023;
257 
258 
259 restart:
260  if (proto == IPPROTO_TCP)
261  wait_before_next_probe ();
262  p = plug_get_host_ip (script_infos);
263  if (IN6_IS_ADDR_V4MAPPED (p))
264  {
265  family = AF_INET;
266  bzero (&addr, sizeof (addr));
267  if (proto == IPPROTO_TCP)
268  sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
269  else
270  sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
271  }
272  else
273  {
274  family = AF_INET6;
275  bzero (&addr6, sizeof (addr6));
276  if (proto == IPPROTO_TCP)
277  sock = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
278  else
279  sock = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
280  }
281 
282 
283  /*
284  * We will bind to a privileged port. Let's declare
285  * our socket ready for reuse
286  */
287 
288  if (sock < 0)
289  return NULL;
290 
291 tryagain:
292  if (current_sport < 128 && sport < 0)
293  return NULL;
294  e =
295  openvas_source_set_socket (sock, sport > 0 ? sport : current_sport--, family);
296 
297  /*
298  * bind() failed - try again on a lower port
299  */
300  if (e < 0)
301  {
302  close (sock);
303  if (sport > 0)
304  return NULL;
305  else
306  goto tryagain;
307  }
308 
309 
310  /*
311  * Connect to the other end
312  */
313  p = plug_get_host_ip (script_infos);
314 
315  if (IN6_IS_ADDR_V4MAPPED (p))
316  {
317  bzero (&daddr, sizeof (daddr));
318  daddr.sin_addr.s_addr = p->s6_addr32[3];
319  daddr.sin_family = AF_INET;
320  daddr.sin_port = htons (dport);
321  unblock_socket (sock);
322  e = connect (sock, (struct sockaddr *) &daddr, sizeof (daddr));
323  }
324  else
325  {
326  bzero (&daddr6, sizeof (daddr6));
327  memcpy (&daddr6.sin6_addr, p, sizeof (struct in6_addr));
328  daddr6.sin6_family = AF_INET6;
329  daddr6.sin6_port = htons (dport);
330  unblock_socket (sock);
331  e = connect (sock, (struct sockaddr *) &daddr6, sizeof (daddr6));
332  }
333 
334 
335  if (e < 0)
336  {
337  if (errno == EADDRINUSE || errno == EADDRNOTAVAIL)
338  {
339  close (sock);
340  if (sport < 0)
341  goto restart;
342  else
343  return NULL;
344  }
345  else if (errno != EINPROGRESS)
346  {
347  close (sock);
348  return NULL;
349  }
350  }
351 
352  do
353  {
354  tv.tv_sec = to;
355  tv.tv_usec = 0;
356  FD_ZERO (&rd);
357  FD_SET (sock, &rd);
358  e = select (sock + 1, NULL, &rd, NULL, to > 0 ? &tv : NULL);
359  }
360  while (e < 0 && errno == EINTR);
361 
362  if (e <= 0)
363  {
364  close (sock);
365  return FAKE_CELL;
366  }
367 
368  block_socket (sock);
369  opt_sz = sizeof (opt);
370 
371  if (getsockopt (sock, SOL_SOCKET, SO_ERROR, &opt, &opt_sz) < 0)
372  {
373  log_legacy_write ("[%d] open_priv_sock()->getsockopt() failed : %s\n",
374  getpid (), strerror (errno));
375  close (sock);
376  return NULL;
377  }
378 
379 
380  switch (opt)
381  {
382  case EADDRINUSE:
383  case EADDRNOTAVAIL:
384  close (sock);
385  if (sport < 0)
386  goto restart;
387  else
388  return FAKE_CELL;
389 
390  case 0:
391  break;
392  default:
393  close (sock);
394  return FAKE_CELL;
395  break;
396  }
397 
398  if (lowest_socket == 0)
399  lowest_socket = sock;
400  if (proto == IPPROTO_TCP)
401  sock = openvas_register_connection (sock, NULL, NULL, OPENVAS_ENCAPS_IP);
402 
403  retc = alloc_tree_cell (0, NULL);
404  retc->type = CONST_INT;
405  retc->x.i_val = sock < 0 ? 0 : sock;
406  return retc;
407 }
408 
409 
410 tree_cell *
412 {
413  return nasl_open_privileged_socket (lexic, IPPROTO_TCP);
414 }
415 
416 tree_cell *
418 {
419  return nasl_open_privileged_socket (lexic, IPPROTO_UDP);
420 }
421 
422 
423 /*--------------------------------------------------------------------------*/
424 
425 tree_cell *
426 nasl_open_sock_tcp_bufsz (lex_ctxt * lexic, int bufsz)
427 {
428  int soc = -1;
429  struct arglist *script_infos = lexic->script_infos;
430  int to, port;
431  int transport = -1;
432  const char *priority;
433  tree_cell *retc;
434 
435  to = get_int_local_var_by_name (lexic, "timeout", lexic->recv_timeout * 2);
436  if (to < 0)
437  to = 10;
438 
439  transport = get_int_local_var_by_name (lexic, "transport", -1);
440 
441  if (transport == OPENVAS_ENCAPS_TLScustom)
442  {
443  int type;
444  priority = get_str_local_var_by_name (lexic, "priority");
445  if (!priority)
446  priority = NULL;
447  type = get_local_var_type_by_name (lexic, "priority");
448  if (type != VAR2_STRING && type != VAR2_DATA)
449  priority = NULL;
450  }
451  else
452  priority = NULL;
453 
454  if (bufsz < 0)
455  bufsz = get_int_local_var_by_name (lexic, "bufsz", 0);
456 
457  port = get_int_var_by_num (lexic, 0, -1);
458  if (port < 0)
459  return NULL;
460 
461  wait_before_next_probe ();
462 
463  /* If "transport" has not been given, use auto detection if enabled
464  in the KB. if "transport" has been given with a value of 0 force
465  autodetection reagardless of what the KB tells. */
466  if (transport < 0)
467  soc = open_stream_auto_encaps_ext (script_infos, port, to, 0);
468  else if (transport == 0)
469  soc = open_stream_auto_encaps_ext (script_infos, port, to, 1);
470  else
471  soc = open_stream_connection_ext (script_infos, port, transport, to,
472  priority);
473  if (bufsz > 0 && soc >= 0)
474  {
475  if (stream_set_buffer (soc, bufsz) < 0)
476  nasl_perror (lexic, "stream_set_buffer: soc=%d,bufsz=%d\n", soc, bufsz);
477  }
478 
479  retc = alloc_tree_cell (0, NULL);
480  retc->type = CONST_INT;
481  retc->x.i_val = soc < 0 ? 0 : soc;
482 
483  return retc;
484 }
485 
526 tree_cell *
528 {
529  return nasl_open_sock_tcp_bufsz (lexic, -1);
530 }
531 
532 /*
533  * Opening a UDP socket is a little more tricky, since
534  * UDP works in a way which is different from TCP...
535  *
536  * Our goal is to hide this difference for the end-user
537  */
538 tree_cell *
540 {
541  int soc;
542  tree_cell *retc;
543  int port;
544  struct sockaddr_in soca;
545  struct sockaddr_in6 soca6;
546  struct arglist *script_infos = lexic->script_infos;
547  struct in6_addr *ia;
548 
549  port = get_int_var_by_num (lexic, 0, -1);
550  if (port < 0)
551  return NULL;
552 
553  ia = plug_get_host_ip (script_infos);
554  if (ia == NULL)
555  return NULL;
556  if (IN6_IS_ADDR_V4MAPPED (ia))
557  {
558  bzero (&soca, sizeof (soca));
559  soca.sin_addr.s_addr = ia->s6_addr32[3];
560  soca.sin_port = htons (port);
561  soca.sin_family = AF_INET;
562 
563  soc = socket (AF_INET, SOCK_DGRAM, 0);
564  openvas_source_set_socket (soc, 0, AF_INET);
565  connect (soc, (struct sockaddr *) &soca, sizeof (soca));
566  }
567  else
568  {
569  bzero (&soca6, sizeof (soca6));
570  memcpy (&soca6.sin6_addr, ia, sizeof (struct in6_addr));
571  soca6.sin6_port = htons (port);
572  soca6.sin6_family = AF_INET6;
573 
574  soc = socket (AF_INET6, SOCK_DGRAM, 0);
575  openvas_source_set_socket (soc, 0, AF_INET6);
576  connect (soc, (struct sockaddr *) &soca6, sizeof (soca6));
577  }
578 
579  if (soc > 0 && lowest_socket == 0)
580  lowest_socket = soc;
581 
582  retc = alloc_tree_cell (0, NULL);
583  retc->type = CONST_INT;
584  retc->x.i_val = soc < 0 ? 0 : soc;
585  return retc;
586 }
587 
588 tree_cell *
590 {
591  int soc, transport, ret;
592  tree_cell *retc;
593 
594 
595  soc = get_int_local_var_by_name (lexic, "socket", -1);
596  transport = get_int_local_var_by_name (lexic, "transport",
598  if (soc < 0)
599  {
600  nasl_perror (lexic, "socket_ssl_negotiate: Erroneous socket value %d\n",
601  soc);
602  return NULL;
603  }
604  if (transport == -1)
605  transport = OPENVAS_ENCAPS_TLScustom;
606  else if (!IS_ENCAPS_SSL (transport))
607  {
608  nasl_perror (lexic, "socket_ssl_negotiate: Erroneous transport value %d\n",
609  transport);
610  return NULL;
611  }
612  ret = socket_negotiate_ssl (soc, transport, lexic->script_infos);
613  if (ret < 0)
614  return NULL;
615 
616  retc = alloc_tree_cell (0, NULL);
617  retc->type = CONST_INT;
618  retc->x.i_val = ret;
619  return retc;
620 }
621 
622 tree_cell *
624 {
625  int soc, cert_len = 0;
626  tree_cell *retc;
627  void *cert;
628 
629  soc = get_int_local_var_by_name (lexic, "socket", -1);
630  if (soc < 0)
631  {
632  nasl_perror (lexic, "socket_get_cert: Erroneous socket value %d\n",
633  soc);
634  return NULL;
635  }
636  socket_get_cert (soc, &cert, &cert_len);
637  if (cert_len <= 0)
638  return NULL;
639  retc = alloc_tree_cell (0, NULL);
640  retc->type = CONST_DATA;
641  retc->x.str_val = cert;
642  retc->size = cert_len;
643  return retc;
644 }
645 
646 tree_cell *
648 {
649  int soc;
650  size_t sid_len = 0;
651  tree_cell *retc;
652  void *sid;
653 
654  soc = get_int_local_var_by_name (lexic, "socket", -1);
655  if (soc < 0)
656  {
657  nasl_perror (lexic, "socket_get_cert: Erroneous socket value %d\n",
658  soc);
659  return NULL;
660  }
661  socket_get_ssl_session_id (soc, &sid, &sid_len);
662  if (sid == NULL || sid_len == 0)
663  return NULL;
664  retc = alloc_tree_cell (0, NULL);
665  retc->type = CONST_DATA;
666  retc->x.str_val = sid;
667  retc->size = sid_len;
668  return retc;
669 }
670 
671 tree_cell *
673 {
674  int soc;
675  tree_cell *retc;
676 
677  soc = get_int_local_var_by_name (lexic, "socket", -1);
678  if (soc < 0)
679  {
680  nasl_perror (lexic, "socket_get_cert: Erroneous socket value %d\n",
681  soc);
682  return NULL;
683  }
684  retc = alloc_tree_cell (0, NULL);
685  retc->type = CONST_INT;
686  retc->x.i_val = socket_get_ssl_compression (soc);
687  return retc;
688 }
689 
690 tree_cell *
692 {
693  int soc;
694  int version;
695  tree_cell *retc;
696 
697  soc = get_int_local_var_by_name (lexic, "socket", -1);
698  version = socket_get_ssl_version (soc);
699  if (version < 0)
700  return NULL;
701  retc = alloc_tree_cell (0, NULL);
702  retc->type = CONST_INT;
703  retc->x.i_val = version;
704  return retc;
705 }
706 
707 tree_cell *
709 {
710  int soc, result;
711  tree_cell *retc;
712 
713  soc = get_int_local_var_by_name (lexic, "socket", -1);
714  result = socket_get_ssl_ciphersuite (soc);
715  if (result < 0)
716  return NULL;
717  retc = alloc_tree_cell (0, NULL);
718  retc->type = CONST_INT;
719  retc->x.i_val = result;
720  return retc;
721 }
722 
723 /*---------------------------------------------------------------------*/
724 
725 tree_cell *
727 {
728  char *data;
729  int len = get_int_local_var_by_name (lexic, "length", -1);
730  int min_len = get_int_local_var_by_name (lexic, "min", -1);
731  int soc = get_int_local_var_by_name (lexic, "socket", 0);
732  int to = get_int_local_var_by_name (lexic, "timeout", lexic->recv_timeout);
733  fd_set rd;
734  struct timeval tv;
735  int new_len = 0;
736  int type = -1;
737  unsigned int opt_len = sizeof (type);
738  int e;
739 
740  if (len <= 0 || soc <= 0)
741  return NULL;
742 
743  tv.tv_sec = to;
744  tv.tv_usec = 0;
745 
746  data = g_malloc0 (len);
747  if (!fd_is_stream (soc))
748  e = getsockopt (soc, SOL_SOCKET, SO_TYPE, &type, &opt_len);
749  else
750  e = -1;
751 
752  if (e == 0 && type == SOCK_DGRAM)
753  {
754  /* As UDP packets may be lost, we retry up to 5 times */
755  int retries = 5;
756  int i;
757 
758  tv.tv_sec = to / retries;
759  tv.tv_usec = (to % retries) * 100000;
760 
761  for (i = 0; i < retries; i++)
762  {
763  FD_ZERO (&rd);
764  FD_SET (soc, &rd);
765 
766  if (select (soc + 1, &rd, NULL, NULL, &tv) > 0)
767  {
768  int e;
769  e = recv (soc, data + new_len, len - new_len, 0);
770 
771  if (e <= 0)
772  {
773  if (!new_len)
774  {
775  g_free (data);
776  return NULL;
777  }
778  else
779  break;
780  }
781  else
782  new_len += e;
783 
784  if (new_len >= len)
785  break;
786 
787  break; /* UDP data is never fragmented */
788  }
789  else
790  {
791  /* The packet may have been lost en route - we resend it */
792  char *data;
793  int len;
794 
795  data = get_udp_data (lexic->script_infos, soc, &len);
796  if (data != NULL)
797  send (soc, data, len, 0);
798  tv.tv_sec = to / retries;
799  tv.tv_usec = (to % retries) * 100000;
800  }
801  }
802  }
803  else
804  {
805  int old = stream_set_timeout (soc, tv.tv_sec);
806  new_len = read_stream_connection_min (soc, data, min_len, len);
807  stream_set_timeout (soc, old);
808  }
809  if (new_len > 0)
810  {
811  tree_cell *retc = alloc_tree_cell (0, NULL);
812  retc->type = CONST_DATA;
813  retc->x.str_val = g_memdup (data, new_len);
814  retc->size = new_len;
815  g_free (data);
816  return retc;
817  }
818  else
819  {
820  g_free (data);
821  return NULL;
822  }
823 }
824 
825 
826 
827 tree_cell *
829 {
830  int len = get_int_local_var_by_name (lexic, "length", -1);
831  int soc = get_int_local_var_by_name (lexic, "socket", 0);
832  int timeout = get_int_local_var_by_name (lexic, "timeout", -1);
833  char *data;
834  int new_len = 0;
835  int n = 0;
836  tree_cell *retc;
837  time_t t1 = 0;
838 
839  if (len == -1 || soc <= 0)
840  {
841  nasl_perror (lexic, "recv_line: missing or undefined parameter"
842  " length or socket\n");
843  return NULL;
844  }
845 
846  if (timeout >= 0) /* sycalls are much more expensive than simple tests */
847  t1 = time (NULL);
848 
849  if (fd_is_stream (soc) != 0)
850  {
851  int bufsz = stream_get_buffer_sz (soc);
852  if (bufsz <= 0)
853  stream_set_buffer (soc, len + 1);
854  }
855 
856  data = g_malloc0 (len + 1);
857  for (;;)
858  {
859  int e = read_stream_connection_min (soc, data + n, 1, 1);
860  if (e < 0)
861  break;
862  if (e == 0)
863  {
864  if (timeout >= 0 && time (NULL) - t1 < timeout)
865  continue;
866  else
867  break;
868  }
869  n++;
870  if ((data[n - 1] == '\n') || (n >= len))
871  break;
872  }
873 
874 
875 
876  if (n <= 0)
877  {
878  g_free (data);
879  return NULL;
880  }
881 
882  new_len = n;
883 
884 
885 
886  retc = alloc_tree_cell (0, NULL);
887  retc->type = CONST_DATA;
888  retc->size = new_len;
889  retc->x.str_val = g_memdup (data, new_len + 1);
890 
891  g_free (data);
892 
893  return retc;
894 }
895 
896 /*---------------------------------------------------------------------*/
897 
898 tree_cell *
900 {
901  int soc = get_int_local_var_by_name (lexic, "socket", 0);
902  char *data = get_str_local_var_by_name (lexic, "data");
903  int option = get_int_local_var_by_name (lexic, "option", 0);
904  int length = get_int_local_var_by_name (lexic, "length", 0);
905  int data_length = get_var_size_by_name (lexic, "data");
906  int n;
907  tree_cell *retc;
908  int type;
909  unsigned int type_len = sizeof (type);
910 
911 
912  if (soc <= 0 || data == NULL)
913  {
914  nasl_perror (lexic, "Syntax error with the send() function\n");
915  nasl_perror (lexic,
916  "Correct syntax is : send(socket:<soc>, data:<data>\n");
917  return NULL;
918  }
919 
920  if (length <= 0 || length > data_length)
921  length = data_length;
922 
923 
924  if (!fd_is_stream (soc)
925  && getsockopt (soc, SOL_SOCKET, SO_TYPE, &type, &type_len) == 0
926  && type == SOCK_DGRAM)
927  {
928  n = send (soc, data, length, option);
929  add_udp_data (lexic->script_infos, soc, data, length);
930  }
931  else
932  {
933  wait_before_next_probe ();
934  n = nsend (soc, data, length, option);
935  }
936 
937  retc = alloc_tree_cell (0, NULL);
938  retc->type = CONST_INT;
939  retc->x.i_val = n;
940 
941  return retc;
942 }
943 
944 
945 /*---------------------------------------------------------------------*/
946 tree_cell *
948 {
949  int soc;
950  int type;
951  unsigned int opt_len = sizeof (type);
952  int e;
953 
954  soc = get_int_var_by_num (lexic, 0, -1);
955  if (fd_is_stream (soc))
956  {
957  wait_before_next_probe ();
958  return close_stream_connection (soc) < 0 ? NULL : FAKE_CELL;
959  }
960  if (lowest_socket == 0 || soc < lowest_socket)
961  {
962  nasl_perror (lexic, "close(%d): Invalid socket value\n", soc);
963  return NULL;
964  }
965 
966  e = getsockopt (soc, SOL_SOCKET, SO_TYPE, &type, &opt_len);
967  if (e == 0)
968  {
969  if (type == SOCK_DGRAM)
970  {
971  rm_udp_data (lexic->script_infos, soc);
972  return FAKE_CELL;
973  }
974  close (soc);
975  return FAKE_CELL;
976  }
977  else
978  nasl_perror (lexic, "close(%d): %s\n", soc, strerror (errno));
979 
980  return NULL;
981 }
982 
983 
984 static struct jmg
985 {
986  struct in_addr in;
987  int count;
988  int s;
989 } *jmg_desc = NULL;
990 static int jmg_max = 0;
991 
992 tree_cell *
994 {
995  char *a;
996  int i, j;
997  struct ip_mreq m;
998  tree_cell *retc = NULL;
999 
1000  a = get_str_var_by_num (lexic, 0);
1001  if (a == NULL)
1002  {
1003  nasl_perror (lexic, "join_multicast_group: missing parameter\n");
1004  return NULL;
1005  }
1006  if (!inet_aton (a, &m.imr_multiaddr))
1007  {
1008  nasl_perror (lexic, "join_multicast_group: invalid parameter '%s'\n", a);
1009  return NULL;
1010  }
1011  m.imr_interface.s_addr = INADDR_ANY;
1012 
1013  j = -1;
1014  for (i = 0; i < jmg_max; i++)
1015  if (jmg_desc[i].in.s_addr == m.imr_multiaddr.s_addr
1016  && jmg_desc[i].count > 0)
1017  {
1018  jmg_desc[i].count++;
1019  break;
1020  }
1021  else if (jmg_desc[i].count <= 0)
1022  j = i;
1023 
1024 
1025  if (i >= jmg_max)
1026  {
1027  int s = socket (AF_INET, SOCK_DGRAM, 0);
1028  if (s < 0)
1029  {
1030  nasl_perror (lexic, "join_multicast_group: socket: %s\n",
1031  strerror (errno));
1032  return NULL;
1033  }
1034 
1035  if (setsockopt (s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &m, sizeof (m)) < 0)
1036  {
1037  nasl_perror (lexic,
1038  "join_multicast_group: setsockopt(IP_ADD_MEMBERSHIP): %s\n",
1039  strerror (errno));
1040  close (s);
1041  return NULL;
1042  }
1043 
1044  if (j < 0)
1045  {
1046  jmg_desc = g_realloc (jmg_desc, sizeof (*jmg_desc) * (jmg_max + 1));
1047  j = jmg_max++;
1048  }
1049  jmg_desc[j].s = s;
1050  jmg_desc[j].in = m.imr_multiaddr;
1051  jmg_desc[j].count = 1;
1052  }
1053 
1054  retc = alloc_typed_cell (CONST_INT);
1055  retc->x.i_val = 1;
1056  return retc;
1057 }
1058 
1059 
1060 tree_cell *
1062 {
1063  char *a;
1064  struct in_addr ia;
1065  int i;
1066 
1067  a = get_str_var_by_num (lexic, 0);
1068  if (a == NULL)
1069  {
1070  nasl_perror (lexic, "leave_multicast_group: missing parameter\n");
1071  return NULL;
1072  }
1073  if (!inet_aton (a, &ia))
1074  {
1075  nasl_perror (lexic, "leave_multicast_group: invalid parameter '%s'\n", a);
1076  return NULL;
1077  }
1078 
1079  for (i = 0; i < jmg_max; i++)
1080  if (jmg_desc[i].count > 0 && jmg_desc[i].in.s_addr == ia.s_addr)
1081  {
1082  if (--jmg_desc[i].count <= 0)
1083  close (jmg_desc[i].s);
1084  return FAKE_CELL;
1085  }
1086 
1087  nasl_perror (lexic, "leave_multicast_group: never joined group %s\n", a);
1088  return NULL;
1089 }
1090 
1091 
1092 /* Fixme: Merge this into nasl_get_sock_info. */
1093 tree_cell *
1095 {
1096  struct sockaddr_in ia;
1097  int s, fd;
1098  unsigned int l;
1099  tree_cell *retc;
1100  int type;
1101  unsigned int type_len = sizeof (type);
1102 
1103  s = get_int_var_by_num (lexic, 0, -1);
1104  if (s < 0)
1105  {
1106  nasl_perror (lexic, "get_source_port: missing socket parameter\n");
1107  return NULL;
1108  }
1109  if (!fd_is_stream (s)
1110  && getsockopt (s, SOL_SOCKET, SO_TYPE, &type, &type_len) == 0
1111  && type == SOCK_DGRAM)
1112  fd = s;
1113  else
1115 
1116 
1117  if (fd < 0)
1118  {
1119  nasl_perror (lexic, "get_source_port: invalid socket parameter %d\n", s);
1120  return NULL;
1121  }
1122  l = sizeof (ia);
1123  if (getsockname (fd, (struct sockaddr *) &ia, &l) < 0)
1124  {
1125  nasl_perror (lexic, "get_source_port: getsockname(%d): %s\n", fd,
1126  strerror (errno));
1127  return NULL;
1128  }
1129  retc = alloc_typed_cell (CONST_INT);
1130  retc->x.i_val = ntohs (ia.sin_port);
1131  return retc;
1132 }
1133 
1134 
1135 
1136 tree_cell *
1138 {
1139  int soc = get_int_var_by_num (lexic, 0, -1);
1140  tree_cell *retc;
1141  int err;
1142 
1143  if (soc < 0 || !fd_is_stream (soc))
1144  return NULL;
1145 
1146  err = stream_get_err (soc);
1147  retc = alloc_typed_cell (CONST_INT);
1148 
1149  switch (err)
1150  {
1151  case 0:
1152  retc->x.i_val = NASL_ERR_NOERR;
1153  break;
1154  case ETIMEDOUT:
1155  retc->x.i_val = NASL_ERR_ETIMEDOUT;
1156  break;
1157  case EBADF:
1158  case EPIPE:
1159  case ECONNRESET:
1160  case ENOTSOCK:
1161  retc->x.i_val = NASL_ERR_ECONNRESET;
1162  break;
1163 
1164  case ENETUNREACH:
1165  case EHOSTUNREACH:
1166  retc->x.i_val = NASL_ERR_EUNREACH;
1167  break;
1168 
1169  default:
1170  log_legacy_write ("Unknown error %d %s\n", err, strerror (err));
1171  }
1172 
1173  return retc;
1174 }
1175 
1176 
1239 tree_cell *
1241 {
1242  int sock;
1243  int type;
1244  int err;
1245  const char *keyword, *s;
1246  tree_cell *retc;
1247  int as_string;
1248  int transport;
1249  gnutls_session_t tls_session;
1250  char *strval;
1251  int intval;
1252 
1253  sock = get_int_var_by_num (lexic, 0, -1);
1254  if (sock <= 0)
1255  {
1256  nasl_perror (lexic, "error: socket %d is not valid\n");
1257  return NULL;
1258  }
1259 
1260  keyword = get_str_var_by_num (lexic, 1);
1261  if (!keyword || !((type = get_var_type_by_num (lexic, 1)) == VAR2_STRING
1262  || type == VAR2_DATA))
1263  {
1264  nasl_perror (lexic, "error: second argument is not of type string\n");
1265  return NULL;
1266  }
1267 
1268  as_string = !!get_int_local_var_by_name (lexic, "asstring", 0);
1269 
1270  transport = 0;
1271  strval = NULL;
1272  intval = 0;
1273  retc = FAKE_CELL; /* Dummy value to detect retc == NULL. */
1274 
1275  {
1276  void *tmp = NULL;
1277  err = get_sock_infos (sock, &transport, &tmp);
1278  tls_session = tmp;
1279  }
1280  if (err)
1281  {
1282  nasl_perror (lexic, "error retrieving infos for socket %d: %s\n",
1283  sock, strerror (err));
1284  retc = NULL;
1285  }
1286  else if (!strcmp (keyword, "encaps"))
1287  {
1288  if (as_string)
1289  strval = g_strdup (get_encaps_name (transport));
1290  else
1291  intval = transport;
1292  }
1293  else if (!strcmp (keyword, "tls-proto"))
1294  {
1295  if (!tls_session)
1296  s = "n/a";
1297  else
1298  s = gnutls_protocol_get_name
1299  (gnutls_protocol_get_version (tls_session));
1300  strval = g_strdup (s?s:"[?]");
1301  }
1302  else if (!strcmp (keyword, "tls-kx"))
1303  {
1304  if (!tls_session)
1305  s = "n/a";
1306  else
1307  s = gnutls_kx_get_name (gnutls_kx_get (tls_session));
1308  strval = g_strdup (s?s:"");
1309  }
1310  else if (!strcmp (keyword, "tls-certtype"))
1311  {
1312  if (!tls_session)
1313  s = "n/a";
1314  else
1315  s = gnutls_certificate_type_get_name
1316  (gnutls_certificate_type_get (tls_session));
1317  strval = g_strdup (s?s:"");
1318  }
1319  else if (!strcmp (keyword, "tls-cipher"))
1320  {
1321  if (!tls_session)
1322  s = "n/a";
1323  else
1324  s = gnutls_cipher_get_name (gnutls_cipher_get (tls_session));
1325  strval = g_strdup (s?s:"");
1326  }
1327  else if (!strcmp (keyword, "tls-mac"))
1328  {
1329  if (!tls_session)
1330  s = "n/a";
1331  else
1332  s = gnutls_mac_get_name (gnutls_mac_get (tls_session));
1333  strval = g_strdup (s?s:"");
1334  }
1335  else if (!strcmp (keyword, "tls-comp"))
1336  {
1337  if (!tls_session)
1338  s = "n/a";
1339  else
1340  s = gnutls_compression_get_name
1341  (gnutls_compression_get (tls_session));
1342  strval = g_strdup (s?s:"");
1343  }
1344  else if (!strcmp (keyword, "tls-auth"))
1345  {
1346  if (!tls_session)
1347  s = "n/a";
1348  else
1349  {
1350  switch (gnutls_auth_get_type (tls_session))
1351  {
1352  case GNUTLS_CRD_ANON: s = "ANON"; break;
1353  case GNUTLS_CRD_CERTIFICATE: s = "CERT"; break;
1354  case GNUTLS_CRD_PSK: s = "PSK"; break;
1355  case GNUTLS_CRD_SRP: s = "SRP"; break;
1356  default: s = "[?]"; break;
1357  }
1358  }
1359  strval = g_strdup (s?s:"");
1360  }
1361  else if (!strcmp (keyword, "tls-cert"))
1362  {
1363  /* We only support X.509 for now. GNUTLS also allows for
1364  OpenPGP, but we are not prepared for that. */
1365  if (tls_session
1366  && gnutls_certificate_type_get (tls_session) == GNUTLS_CRT_X509)
1367  {
1368  const gnutls_datum_t *list;
1369  unsigned int nlist = 0;
1370  nasl_array *a;
1371  anon_nasl_var v;
1372 
1373  list = gnutls_certificate_get_peers (tls_session, &nlist);
1374  if (!list)
1375  retc = NULL; /* No certificate or other error. */
1376  else
1377  {
1378  int i;
1379  retc = alloc_tree_cell (0, NULL);
1380  retc->type = DYN_ARRAY;
1381  retc->x.ref_val = a = g_malloc0 (sizeof *a);
1382 
1383  for (i=0; i < nlist; i++)
1384  {
1385  memset (&v, 0, sizeof v);
1386  v.var_type = VAR2_DATA;
1387  v.v.v_str.s_val = list[i].data;
1388  v.v.v_str.s_siz = list[i].size;
1389  add_var_to_list (a, i, &v);
1390  }
1391  }
1392  }
1393  }
1394  else
1395  {
1396  nasl_perror (lexic, "unknown keyword '%s'\n", keyword);
1397  retc = NULL;
1398  }
1399 
1400  if (!retc)
1401  ;
1402  else if (retc != FAKE_CELL)
1403  ; /* Already allocated. */
1404  else if (strval)
1405  {
1406  retc = alloc_typed_cell (CONST_STR);
1407  retc->x.str_val = strval;
1408  retc->size = strlen (strval);
1409  }
1410  else
1411  {
1412  retc = alloc_typed_cell (CONST_INT);
1413  retc->x.i_val = intval;
1414  }
1415 
1416  return retc;
1417 }
int open_stream_connection_ext(struct arglist *args, unsigned int port, int transport, int timeout, const char *priority)
Definition: network.c:1004
tree_cell * nasl_open_sock_tcp_bufsz(lex_ctxt *lexic, int bufsz)
Definition: nasl_socket.c:426
#define FAKE_CELL
Definition: nasl_tree.h:120
tree_cell * nasl_socket_get_ssl_version(lex_ctxt *lexic)
Definition: nasl_socket.c:691
#define err(x)
tree_cell * nasl_leave_multicast_group(lex_ctxt *lexic)
Definition: nasl_socket.c:1061
#define NASL_ERR_ETIMEDOUT
Definition: nasl.h:68
tree_cell * nasl_socket_get_ssl_session_id(lex_ctxt *lexic)
Definition: nasl_socket.c:647
char * data
Definition: nasl_socket.c:164
const char * get_encaps_name(openvas_encaps_t code)
Definition: network.c:1729
#define NASL_ERR_ECONNRESET
Definition: nasl.h:69
#define NASL_ERR_NOERR
Definition: nasl.h:67
tree_cell * nasl_socket_get_error(lex_ctxt *lexic)
Definition: nasl_socket.c:1137
short type
Definition: nasl_tree.h:107
#define NASL_ERR_EUNREACH
Definition: nasl.h:70
union st_a_nasl_var::@9 v
int open_stream_auto_encaps_ext(struct arglist *args, unsigned int port, int timeout, int force)
Definition: network.c:1127
char * str_val
Definition: nasl_tree.h:113
int openvas_get_socket_from_connection(int fd)
Definition: network.c:395
#define option
tree_cell * nasl_send(lex_ctxt *lexic)
Definition: nasl_socket.c:899
int openvas_register_connection(int soc, void *ssl, gnutls_certificate_credentials_t certcred, openvas_encaps_t encaps)
Definition: network.c:267
void * ref_val
Definition: nasl_tree.h:115
nasl_string_t v_str
Definition: nasl_var.h:60
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
int stream_set_buffer(int fd, int sz)
Definition: network.c:2163
long int get_int_local_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1240
const gchar * prefs_get(const gchar *key)
Get a string preference value via a key.
Definition: prefs.c:86
tree_cell * nasl_open_priv_sock_tcp(lex_ctxt *lexic)
Definition: nasl_socket.c:411
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
int type
Definition: arglists.h:34
int fd_is_stream(int fd)
Definition: network.c:2146
int nsend(int fd, void *data, int length, int i_opt)
Definition: network.c:1577
int add_var_to_list(nasl_array *a, int i, const anon_nasl_var *v)
Definition: nasl_var.c:1403
tree_cell * nasl_socket_get_ssl_ciphersuite(lex_ctxt *lexic)
Definition: nasl_socket.c:708
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
int var_type
Definition: nasl_var.h:54
tree_cell * nasl_open_priv_sock_udp(lex_ctxt *lexic)
Definition: nasl_socket.c:417
#define IS_ENCAPS_SSL(x)
Definition: network.h:64
int socket_get_ssl_version(int fd)
Definition: network.c:849
int socket_get_ssl_compression(int fd)
Definition: network.c:930
void socket_get_cert(int fd, void **cert, int *certlen)
Definition: network.c:813
int lowest_socket
Definition: nasl_socket.c:223
int read_stream_connection_min(int fd, void *buf0, int min_len, int max_len)
Definition: network.c:1360
void arg_add_value(struct arglist *arglst, const char *name, int type, void *value)
Definition: arglists.c:170
Definition: nasl_tree.h:105
int stream_get_buffer_sz(int fd)
Definition: network.c:2153
tree_cell * nasl_recv(lex_ctxt *lexic)
Definition: nasl_socket.c:726
#define ARG_PTR
Definition: arglists.h:39
struct in6_addr * plug_get_host_ip(struct arglist *desc)
Definition: plugutils.c:216
tree_cell * nasl_close_socket(lex_ctxt *lexic)
Definition: nasl_socket.c:947
tree_cell * nasl_join_multicast_group(lex_ctxt *lexic)
Definition: nasl_socket.c:993
int socket_get_ssl_ciphersuite(int fd)
Definition: network.c:965
int stream_get_err(int fd)
Definition: network.c:161
tree_cell * nasl_socket_get_cert(lex_ctxt *lexic)
Definition: nasl_socket.c:623
int get_local_var_type_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1322
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:94
int socket_negotiate_ssl(int fd, openvas_encaps_t transport, struct arglist *args)
Definition: network.c:771
tree_cell * nasl_socket_negotiate_ssl(lex_ctxt *lexic)
Definition: nasl_socket.c:589
char * get_str_var_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1248
struct timeval timeval(unsigned long val)
tree_cell * nasl_get_sock_info(lex_ctxt *lexic)
Get info pertaining to a socket.
Definition: nasl_socket.c:1240
int openvas_source_set_socket(int socket, int port, int family)
Binds a socket to use the global source address.
long int i_val
Definition: nasl_tree.h:114
tree_cell * alloc_tree_cell(int lnb, char *s)
Definition: nasl_tree.c:37
tree_cell * nasl_socket_get_ssl_compression(lex_ctxt *lexic)
Definition: nasl_socket.c:672
void socket_get_ssl_session_id(int fd, void **sid, size_t *ssize)
Definition: network.c:890
unsigned char * s_val
Definition: nasl_var.h:35
int get_sock_infos(int sock, int *r_transport, void **r_tls_session)
Definition: network.c:2376
tree_cell * nasl_open_sock_udp(lex_ctxt *lexic)
Definition: nasl_socket.c:539
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39
tree_cell * nasl_open_sock_tcp(lex_ctxt *lexic)
Open a TCP socket to the target host.
Definition: nasl_socket.c:527
void * arg_get_value(struct arglist *args, const char *name)
Definition: arglists.c:252
tree_cell * nasl_get_source_port(lex_ctxt *lexic)
Definition: nasl_socket.c:1094
#define EADDRNOTAVAIL
Definition: nasl_socket.c:70
int stream_set_timeout(int fd, int timeout)
Definition: network.c:1158
int get_var_size_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1291
tree_cell * nasl_recv_line(lex_ctxt *lexic)
Definition: nasl_socket.c:828
int get_var_type_by_num(lex_ctxt *, int)
Returns NASL variable/cell type, VAR2_UNDEF if value is NULL.
Definition: nasl_var.c:1315
int size
Definition: nasl_tree.h:110
int close_stream_connection(int fd)
Definition: network.c:1699