1 /* Portions Copyright (C) 2009-2021 Greenbone Networks GmbH
2 * Based on work Copyright (C) 1998 - 2002 Renaud Deraison
3 * SSL Support Copyright (C) 2001 Michel Arboi
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 /**
23 * @file network.c
24 * @brief Network Functions.
25 */
26
27 #include "../nasl/nasl_debug.h" /* for nasl_*_filename */
28
29 #include <arpa/inet.h> /* for inet_pton */
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <glib.h>
33 #include <gnutls/gnutls.h>
34 #include <gnutls/x509.h>
35 #include <gvm/base/logging.h>
36 #include <gvm/base/networking.h>
37 #include <gvm/base/prefs.h>
38 #include <gvm/util/kb.h> /* for kb_item_get_str() */
39 #include <gvm/util/serverutils.h> /* for load_gnutls_file */
40 #include <signal.h>
41 #include <stdarg.h>
42 #include <stdio.h> /* for FILE */
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/time.h> /* for gettimeofday */
46 #include <sys/types.h>
47 #include <sys/socket.h>
48 #include <unistd.h>
49 #if defined(__DragonFly__)
50 #include <netinet/in.h>
51 #endif
52
53 #ifdef __FreeBSD__
54 #include <netinet/in.h>
55 #define s6_addr32 __u6_addr.__u6_addr32
56 #endif
57
58 #include "network.h" /* for socket_close() */
59 #include "plugutils.h"
60 #include "support.h"
61
62 #define TIMEOUT 20
63
64 #ifndef INADDR_NONE
65 #define INADDR_NONE 0xffffffff
66 #endif
67
68 #undef G_LOG_DOMAIN
69 /**
70 * @brief GLib logging domain.
71 */
72 #define G_LOG_DOMAIN "lib misc"
73
74 /*----------------------------------------------------------------*
75 * Low-level connection management *
76 *----------------------------------------------------------------*/
77
78 /** OpenVAS "FILE" structure */
79 typedef struct
80 {
81 int fd; /**< socket number, or whatever */
82 /*
83 * "transport" layer code when stream is encapsultated. Negative transport
84 * signals a free descriptor.
85 */
86 openvas_encaps_t transport;
87 char *priority; /**< Malloced "priority" string for certain transports. */
88 int timeout; /**< timeout, in seconds. Special values: -2 for default */
89
90 int port;
91
92 gnutls_session_t tls_session; /**< GnuTLS session */
93 gnutls_certificate_credentials_t tls_cred; /**< GnuTLS credentials */
94
95 pid_t pid; /**< Owner - for debugging only */
96
97 char *buf; /**< NULL if unbuffered */
98 int bufsz, bufcnt, bufptr;
99 int last_err;
100 } openvas_connection;
101
102 /**
103 * The role of this offset is:
104 * 1. To detect bugs when the program tries to write to a bad fd
105 * 2. See if a fd is a real socket or a "openvas descriptor". This is a
106 * quick & dirty hack and should be changed!!!
107 */
108 #define OPENVAS_FD_MAX 1024
109 #define OPENVAS_FD_OFF 1000000
110
111 static openvas_connection connections[OPENVAS_FD_MAX];
112
113 /**
114 * @brief Object to store a list of hooks for close_stream_connection.
115 */
116 struct csc_hook_s
117 {
118 struct csc_hook_s *next;
119 int (*fnc) (int fd);
120 };
121
122 /**
123 * @brief Linked list of hooks to be run by close_stream_connection.
124 */
125 static struct csc_hook_s *csc_hooks;
126
127 /**
128 * OPENVAS_STREAM(x) is TRUE if \<x\> is a OpenVAS-ified fd
129 */
130 #define OPENVAS_STREAM(x) \
131 (((x - OPENVAS_FD_OFF) < OPENVAS_FD_MAX) && ((x - OPENVAS_FD_OFF) >= 0))
132
133 /**
134 * determine the openvas_connection* from the openvas fd
135 */
136 #define OVAS_CONNECTION_FROM_FD(fd) (connections + ((fd) -OPENVAS_FD_OFF))
137
138 /**
139 * Same as perror(), but prefixes the data by our pid.
140 */
141 static int
pid_perror(const char * error)142 pid_perror (const char *error)
143 {
144 g_debug ("[%d] %s : %s", getpid (), error, strerror (errno));
145 return 0;
146 }
147
148 int
stream_get_err(int fd)149 stream_get_err (int fd)
150 {
151 openvas_connection *p;
152
153 if (!OPENVAS_STREAM (fd))
154 {
155 errno = EINVAL;
156 return -1;
157 }
158
159 p = OVAS_CONNECTION_FROM_FD (fd);
160 return p->last_err;
161 }
162
163 /**
164 * @brief Returns a free file descriptor.
165 */
166 static int
get_connection_fd(void)167 get_connection_fd (void)
168 {
169 int i;
170
171 for (i = 0; i < OPENVAS_FD_MAX; i++)
172 {
173 if (connections[i].pid == 0) /* Not used */
174 {
175 bzero (&(connections[i]), sizeof (connections[i]));
176 connections[i].pid = getpid ();
177 return i + OPENVAS_FD_OFF;
178 }
179 }
180 g_message ("[%d] %s:%d : Out of OpenVAS file descriptors", getpid (),
181 __FILE__, __LINE__);
182 errno = EMFILE;
183 return -1;
184 }
185
186 static int
release_connection_fd(int fd,int already_closed)187 release_connection_fd (int fd, int already_closed)
188 {
189 openvas_connection *p;
190
191 if (!OPENVAS_STREAM (fd))
192 {
193 errno = EINVAL;
194 return -1;
195 }
196 p = OVAS_CONNECTION_FROM_FD (fd);
197
198 g_free (p->buf);
199 p->buf = 0;
200
201 /* TLS FIXME: we should call gnutls_bye somewhere. OTOH, the OpenSSL
202 * equivalent SSL_shutdown wasn't called anywhere in the OpenVAS
203 * (libopenvas nor elsewhere) code either.
204 */
205
206 /* So far, fd is always a socket. If this is changed in the future, this
207 * code shall be fixed. */
208 if (p->fd >= 0)
209 {
210 g_debug ("[%d] release_connection_fd: fd > 0 fd=%d", getpid (), p->fd);
211 if (shutdown (p->fd, 2) < 0)
212 {
213 /*
214 * It's not uncommon to see that one fail, since a lot of
215 * services close the connection before we ask them to
216 * (ie: http), so we don't show this error by default
217 */
218 pid_perror ("release_connection_fd: shutdown()");
219 }
220 if (!already_closed && socket_close (p->fd) < 0)
221 pid_perror ("release_connection_fd: close()");
222 }
223
224 if (p->tls_session != NULL)
225 gnutls_deinit (p->tls_session);
226 if (p->tls_cred != NULL)
227 gnutls_certificate_free_credentials (p->tls_cred);
228
229 g_free (p->priority);
230 p->priority = NULL;
231
232 bzero (p, sizeof (*p));
233 p->transport = -1;
234 p->pid = 0;
235
236 return 0;
237 }
238
239 /* ******** Compatibility function ******** */
240
241 /** @todo TLS FIXME: migrate this to TLS */
242 /** @todo Fix the voidness of the ssl parameter (problematic in 64bit env.)
243 * here or on caller-side */
244 /**
245 * @param soc Socket to use.
246 */
247 int
openvas_register_connection(int soc,void * ssl,gnutls_certificate_credentials_t certcred,openvas_encaps_t encaps)248 openvas_register_connection (int soc, void *ssl,
249 gnutls_certificate_credentials_t certcred,
250 openvas_encaps_t encaps)
251 {
252 int fd;
253 openvas_connection *p;
254
255 if ((fd = get_connection_fd ()) < 0)
256 return -1;
257 p = OVAS_CONNECTION_FROM_FD (fd);
258
259 p->tls_session = ssl;
260 p->tls_cred = certcred;
261
262 p->timeout = TIMEOUT; /* default value */
263 p->port = 0; /* just used for debug */
264 p->fd = soc;
265 p->transport = encaps;
266 p->priority = NULL;
267 p->last_err = 0;
268
269 return fd;
270 }
271
272 int
openvas_deregister_connection(int fd)273 openvas_deregister_connection (int fd)
274 {
275 openvas_connection *p;
276 if (!OPENVAS_STREAM (fd))
277 {
278 errno = EINVAL;
279 return -1;
280 }
281
282 p = connections + (fd - OPENVAS_FD_OFF);
283 /* Fixme: Code duplicated from release_connection_fd. Check usage
284 of this function make sure that TLS stuff is also released in
285 case it is used here. */
286 g_free (p->priority);
287 p->priority = NULL;
288 bzero (p, sizeof (*p));
289 p->transport = -1;
290 return 0;
291 }
292
293 /*----------------------------------------------------------------*
294 * High-level connection management *
295 *----------------------------------------------------------------*/
296
297 static int __port_closed;
298
299 static int
unblock_socket(int soc)300 unblock_socket (int soc)
301 {
302 int flags = fcntl (soc, F_GETFL, 0);
303 if (flags < 0)
304 {
305 pid_perror ("fcntl(F_GETFL)");
306 return -1;
307 }
308 if (fcntl (soc, F_SETFL, O_NONBLOCK | flags) < 0)
309 {
310 pid_perror ("fcntl(F_SETFL,O_NONBLOCK)");
311 return -1;
312 }
313 return 0;
314 }
315
316 static int
block_socket(int soc)317 block_socket (int soc)
318 {
319 int flags = fcntl (soc, F_GETFL, 0);
320 if (flags < 0)
321 {
322 pid_perror ("fcntl(F_GETFL)");
323 return -1;
324 }
325 if (fcntl (soc, F_SETFL, (~O_NONBLOCK) & flags) < 0)
326 {
327 pid_perror ("fcntl(F_SETFL,~O_NONBLOCK)");
328 return -1;
329 }
330 return 0;
331 }
332
333 /*
334 * Initialize the SSL library (error strings and algorithms) and try
335 * to set the pseudo random generator to something less silly than the
336 * default value: 1 according to SVID 3, BSD 4.3, ISO 9899 :-(
337 */
338
339 void
tlserror(char * txt,int err)340 tlserror (char *txt, int err)
341 {
342 g_message ("[%d] %s: %s", getpid (), txt, gnutls_strerror (err));
343 }
344
345 static void
log_message_gnutls(int level,const char * msg)346 log_message_gnutls (int level, const char *msg)
347 {
348 g_debug ("LEVEL %d: %s", level, msg);
349 }
350
351 /**
352 * @brief Initializes SSL support.
353 */
354 int
openvas_SSL_init()355 openvas_SSL_init ()
356 {
357 gnutls_global_set_log_level (2);
358 gnutls_global_set_log_function (log_message_gnutls);
359
360 int ret = gnutls_global_init ();
361 if (ret < 0)
362 {
363 tlserror ("gnutls_global_init", ret);
364 return -1;
365 }
366
367 return 0;
368 }
369
370 int
openvas_get_socket_from_connection(int fd)371 openvas_get_socket_from_connection (int fd)
372 {
373 openvas_connection *fp;
374
375 if (!OPENVAS_STREAM (fd))
376 {
377 g_message ("[%d] openvas_get_socket_from_connection: bad fd <%d>",
378 getpid (), fd);
379 return fd;
380 }
381 fp = connections + (fd - OPENVAS_FD_OFF);
382 if (fp->transport <= 0)
383 {
384 g_message ("openvas_get_socket_from_connection: fd <%d> is closed", fd);
385 return -1;
386 }
387 return fp->fd;
388 }
389
390 gnutls_session_t
ovas_get_tlssession_from_connection(int fd)391 ovas_get_tlssession_from_connection (int fd)
392 {
393 openvas_connection *fp;
394
395 if (!OPENVAS_STREAM (fd))
396 return NULL;
397
398 fp = connections + (fd - OPENVAS_FD_OFF);
399 return fp->tls_session;
400 }
401
402 /**
403 * Sets the priorities for the GnuTLS session according to encaps.
404 * PRIORITY is used to convey custom priorities; it is only used if ENCAPS is
405 * set to OPENVAS_ENCAPS_TLScustom.
406 */
407 static int
set_gnutls_protocol(gnutls_session_t session,openvas_encaps_t encaps,const char * priority)408 set_gnutls_protocol (gnutls_session_t session, openvas_encaps_t encaps,
409 const char *priority)
410 {
411 const char *priorities;
412 const char *errloc;
413 int err;
414
415 switch (encaps)
416 {
417 case OPENVAS_ENCAPS_SSLv3:
418 priorities = "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0:+ARCFOUR-128:%COMPAT";
419 break;
420 case OPENVAS_ENCAPS_TLSv1:
421 priorities = "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+ARCFOUR-128:%COMPAT";
422 break;
423 case OPENVAS_ENCAPS_TLSv11:
424 priorities = "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+ARCFOUR-128:%COMPAT";
425 break;
426 case OPENVAS_ENCAPS_TLSv12:
427 priorities = "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2:+ARCFOUR-128:%COMPAT";
428 break;
429 case OPENVAS_ENCAPS_TLSv13:
430 priorities = "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3:%COMPAT";
431 break;
432 case OPENVAS_ENCAPS_SSLv23: /* Compatibility mode */
433 priorities =
434 "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:+ARCFOUR-128:%COMPAT";
435 break;
436 default:
437 g_debug ("*Bug* at %s:%d. Unknown transport %d", __FILE__, __LINE__,
438 encaps);
439 /* fallthrough */
440 case OPENVAS_ENCAPS_TLScustom:
441 priorities = priority;
442 break;
443 }
444
445 if ((err = gnutls_priority_set_direct (session, priorities, &errloc)))
446 {
447 g_message ("[%d] setting session priorities '%.20s': %s", getpid (),
448 errloc, gnutls_strerror (err));
449 return -1;
450 }
451
452 return 0;
453 }
454
455 /**
456 * @brief Loads a certificate and the corresponding private key from PEM files.
457 *
458 * The private key may be encrypted, in which case the password to
459 * decrypt the key should be given as the passwd parameter.
460 *
461 * @return Returns 0 on success and -1 on failure.
462 */
463 static int
load_cert_and_key(gnutls_certificate_credentials_t xcred,const char * cert,const char * key,const char * passwd)464 load_cert_and_key (gnutls_certificate_credentials_t xcred, const char *cert,
465 const char *key, const char *passwd)
466 {
467 gnutls_x509_crt_t x509_crt = NULL;
468 gnutls_x509_privkey_t x509_key = NULL;
469 gnutls_datum_t data;
470 int ret;
471 int result = 0;
472
473 if (load_gnutls_file (cert, &data))
474 {
475 g_message ("[%d] load_cert_and_key: Error loading cert file %s",
476 getpid (), cert);
477 result = -1;
478 goto cleanup;
479 }
480 ret = gnutls_x509_crt_init (&x509_crt);
481 if (ret < 0)
482 {
483 tlserror ("gnutls_x509_crt_init", ret);
484 /* x509_crt may be != NULL even if gnutls_x509_crt_init fails */
485 x509_crt = NULL;
486 result = -1;
487 goto cleanup;
488 }
489 ret = gnutls_x509_crt_import (x509_crt, &data, GNUTLS_X509_FMT_PEM);
490 if (ret < 0)
491 {
492 tlserror ("gnutls_x509_crt_import", ret);
493 result = -1;
494 goto cleanup;
495 }
496 unload_gnutls_file (&data);
497
498 if (load_gnutls_file (key, &data))
499 {
500 g_message ("[%d] load_cert_and_key: Error loading key file %s", getpid (),
501 key);
502 result = -1;
503 goto cleanup;
504 }
505 ret = gnutls_x509_privkey_init (&x509_key);
506 if (ret < 0)
507 {
508 tlserror ("gnutls_x509_privkey_init", ret);
509 /* x509_key may be != NULL even if gnutls_x509_privkey_init fails */
510 x509_key = NULL;
511 result = -1;
512 goto cleanup;
513 }
514 if (passwd)
515 {
516 ret = gnutls_x509_privkey_import_pkcs8 (x509_key, &data,
517 GNUTLS_X509_FMT_PEM, passwd, 0);
518 if (ret < 0)
519 {
520 tlserror ("gnutls_x509_privkey_import_pkcs8", ret);
521 result = -1;
522 goto cleanup;
523 }
524 }
525 else
526 {
527 ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
528 if (ret < 0)
529 {
530 tlserror ("gnutls_x509_privkey_import", ret);
531 result = -1;
532 goto cleanup;
533 }
534 }
535 unload_gnutls_file (&data);
536
537 ret = gnutls_certificate_set_x509_key (xcred, &x509_crt, 1, x509_key);
538 if (ret < 0)
539 {
540 tlserror ("gnutls_certificate_set_x509_key", ret);
541 result = -1;
542 goto cleanup;
543 }
544
545 cleanup:
546
547 if (x509_crt)
548 gnutls_x509_crt_deinit (x509_crt);
549 if (x509_key)
550 gnutls_x509_privkey_deinit (x509_key);
551
552 return result;
553 }
554
555 static int
is_ip_address(const char * str)556 is_ip_address (const char *str)
557 {
558 struct sockaddr_in sa;
559 struct sockaddr_in6 sa6;
560
561 if (inet_pton (AF_INET, str, &(sa.sin_addr)) == 1)
562 return 1;
563
564 return inet_pton (AF_INET6, str, &(sa6.sin6_addr)) == 1;
565 }
566
567 static int
open_SSL_connection(openvas_connection * fp,const char * cert,const char * key,const char * passwd,const char * cafile,const char * hostname)568 open_SSL_connection (openvas_connection *fp, const char *cert, const char *key,
569 const char *passwd, const char *cafile,
570 const char *hostname)
571 {
572 int ret, err, d;
573 time_t tictac;
574 fd_set fdw, fdr;
575 struct timeval to;
576
577 ret = gnutls_init (&(fp->tls_session), GNUTLS_CLIENT);
578 if (ret < 0)
579 {
580 tlserror ("gnutls_init", ret);
581 return -1;
582 }
583
584 /* set_gnutls_protocol handles OPENVAS_ENCAPS_SSLv2 by falling back
585 * to OPENVAS_ENCAPS_SSLv23. However, this function
586 * (open_SSL_connection) is called only by open_stream_connection and
587 * open_stream_connection will exit with an error code if called with
588 * OPENVAS_ENCAPS_SSLv2, so it should never end up calling
589 * open_SSL_connection with OPENVAS_ENCAPS_SSLv2.
590 */
591 if (set_gnutls_protocol (fp->tls_session, fp->transport, fp->priority) < 0)
592 return -1;
593
594 if (hostname && !is_ip_address (hostname))
595 gnutls_server_name_set (fp->tls_session, GNUTLS_NAME_DNS, hostname,
596 strlen (hostname));
597
598 ret = gnutls_certificate_allocate_credentials (&(fp->tls_cred));
599 if (ret < 0)
600 {
601 tlserror ("gnutls_certificate_allocate_credentials", ret);
602 return -1;
603 }
604 ret = gnutls_credentials_set (fp->tls_session, GNUTLS_CRD_CERTIFICATE,
605 fp->tls_cred);
606 if (ret < 0)
607 {
608 tlserror ("gnutls_credentials_set", ret);
609 return -1;
610 }
611
612 if (cert != NULL && key != NULL)
613 {
614 if (load_cert_and_key (fp->tls_cred, cert, key, passwd) < 0)
615 return -1;
616 }
617
618 if (cafile != NULL)
619 {
620 ret = gnutls_certificate_set_x509_trust_file (fp->tls_cred, cafile,
621 GNUTLS_X509_FMT_PEM);
622 if (ret < 0)
623 {
624 tlserror ("gnutls_certificate_set_x509_trust_file", ret);
625 return -1;
626 }
627 }
628
629 unblock_socket (fp->fd);
630
631 gnutls_transport_set_ptr (fp->tls_session,
632 (gnutls_transport_ptr_t) GSIZE_TO_POINTER (fp->fd));
633
634 tictac = time (NULL);
635
636 for (;;)
637 {
638 err = gnutls_handshake (fp->tls_session);
639
640 if (err == 0)
641 return 1;
642
643 if (err != GNUTLS_E_INTERRUPTED && err != GNUTLS_E_AGAIN
644 && err != GNUTLS_E_WARNING_ALERT_RECEIVED)
645 {
646 g_debug ("[%d] gnutls_handshake: %s", getpid (),
647 gnutls_strerror (err));
648 return -1;
649 }
650
651 FD_ZERO (&fdr);
652 FD_SET (fp->fd, &fdr);
653 FD_ZERO (&fdw);
654 FD_SET (fp->fd, &fdw);
655
656 do
657 {
658 d = tictac + fp->timeout - time (NULL);
659 if (d <= 0)
660 {
661 fp->last_err = ETIMEDOUT;
662 return -1;
663 }
664 to.tv_sec = d;
665 to.tv_usec = 0;
666 errno = 0;
667 if ((ret = select (fp->fd + 1, &fdr, &fdw, NULL, &to)) <= 0)
668 pid_perror ("select");
669 }
670 while (ret < 0 && errno == EINTR);
671
672 if (ret <= 0)
673 {
674 fp->last_err = ETIMEDOUT;
675 return -1;
676 }
677 }
678 }
679
680 /*
681 * @brief Upgrade an ENCAPS_IP socket to an SSL/TLS encapsulated one.
682 *
683 * @param[in] fd Socket file descriptor.
684 * @param[in] transport Encapsulation type.
685 * @param[in] arg Script args.
686 *
687 * @return -1 if error, socket file descriptor value otherwise.
688 */
689 int
socket_negotiate_ssl(int fd,openvas_encaps_t transport,struct script_infos * args)690 socket_negotiate_ssl (int fd, openvas_encaps_t transport,
691 struct script_infos *args)
692 {
693 char *cert = NULL, *key = NULL, *passwd = NULL, *cafile = NULL;
694 char *hostname = NULL;
695 openvas_connection *fp;
696 kb_t kb;
697 char buf[1024];
698
699 if (!fd_is_stream (fd))
700 {
701 g_message ("Socket %d is not stream", fd);
702 return -1;
703 }
704 fp = OVAS_CONNECTION_FROM_FD (fd);
705 kb = plug_get_kb (args);
706 cert = kb_item_get_str (kb, "SSL/cert");
707 key = kb_item_get_str (kb, "SSL/key");
708 passwd = kb_item_get_str (kb, "SSL/password");
709 cafile = kb_item_get_str (kb, "SSL/CA");
710 snprintf (buf, sizeof (buf), "Host/SNI/%d/force_disable", fp->port);
711 if (kb_item_get_int (kb, buf) <= 0)
712 hostname = plug_get_host_fqdn (args);
713
714 fp->transport = transport;
715 fp->priority = NULL;
716 if (open_SSL_connection (fp, cert, key, passwd, cafile, hostname) <= 0)
717 {
718 g_free (hostname);
719 g_free (cert);
720 g_free (key);
721 g_free (passwd);
722 g_free (cafile);
723 g_message ("Function socket_negotiate_ssl called from %s: "
724 "SSL/TLS connection failed.",
725 nasl_get_plugin_filename ());
726 release_connection_fd (fd, 0);
727 return -1;
728 }
729 g_free (hostname);
730 g_free (cert);
731 g_free (key);
732 g_free (passwd);
733 g_free (cafile);
734 return fd;
735 }
736
737 /*
738 * @brief Get the peer's certificate from an SSL/TLS encapsulated connection.
739 *
740 * @param[in] fd Socket file descriptor.
741 * @param[out] cert Memory pointer to fill cert pointer.
742 * @param[out] certlen Size of cert.
743 */
744 void
socket_get_cert(int fd,void ** cert,int * certlen)745 socket_get_cert (int fd, void **cert, int *certlen)
746 {
747 gnutls_session_t session;
748 const gnutls_datum_t *cert_list;
749 unsigned int cert_list_len = 0;
750
751 if (!cert || !certlen)
752 return;
753 if (!fd_is_stream (fd))
754 {
755 g_message ("Socket %d is not stream", fd);
756 return;
757 }
758 session = ovas_get_tlssession_from_connection (fd);
759 if (!session)
760 {
761 g_message ("Socket %d is not SSL/TLS encapsulated", fd);
762 return;
763 }
764 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
765 return;
766 cert_list = gnutls_certificate_get_peers (session, &cert_list_len);
767 if (cert_list_len == 0)
768 return;
769 *certlen = cert_list[0].size;
770 *cert = g_memdup (cert_list[0].data, *certlen);
771 }
772
773 /*
774 * @brief Get the TLS version of a connection.
775 *
776 * @param[in] fd Socket file descriptor.
777 *
778 * @return OPENVAS_ENCAPS value if valid session and success, -1 if error.
779 */
780 int
socket_get_ssl_version(int fd)781 socket_get_ssl_version (int fd)
782 {
783 gnutls_session_t session;
784 gnutls_protocol_t version;
785
786 if (!fd_is_stream (fd))
787 {
788 g_message ("Socket %d is not stream", fd);
789 return -1;
790 }
791 session = ovas_get_tlssession_from_connection (fd);
792 if (!session)
793 {
794 g_message ("Socket %d is not SSL/TLS encapsulated", fd);
795 return -1;
796 }
797
798 version = gnutls_protocol_get_version (session);
799 switch (version)
800 {
801 case GNUTLS_SSL3:
802 return OPENVAS_ENCAPS_SSLv3;
803 case GNUTLS_TLS1:
804 return OPENVAS_ENCAPS_TLSv1;
805 case GNUTLS_TLS1_1:
806 return OPENVAS_ENCAPS_TLSv11;
807 case GNUTLS_TLS1_2:
808 return OPENVAS_ENCAPS_TLSv12;
809 case GNUTLS_TLS1_3:
810 return OPENVAS_ENCAPS_TLSv13;
811 default:
812 return -1;
813 }
814 }
815
816 /*
817 * @brief Get the session ID from an SSL/TLS encapsulated connection.
818 *
819 * @param[in] fd Socket file descriptor.
820 * @param[out] sid Pointer where to store Session ID pointer.
821 * @param[out] ssize Size of session id buffer.
822 */
823 void
socket_get_ssl_session_id(int fd,void ** sid,size_t * ssize)824 socket_get_ssl_session_id (int fd, void **sid, size_t *ssize)
825 {
826 gnutls_session_t session;
827 void *tmp;
828 *ssize = GNUTLS_MAX_SESSION_ID;
829 int ret;
830
831 if (!sid)
832 return;
833 if (!fd_is_stream (fd))
834 {
835 g_message ("Socket %d is not stream", fd);
836 return;
837 }
838 session = ovas_get_tlssession_from_connection (fd);
839 if (!session)
840 {
841 g_message ("Socket %d is not SSL/TLS encapsulated", fd);
842 return;
843 }
844 tmp = g_malloc0 (*ssize);
845 ret = gnutls_session_get_id (session, tmp, ssize);
846 if (ret == GNUTLS_E_SUCCESS)
847 *sid = tmp;
848 else
849 {
850 g_free (tmp);
851 *ssize = 0;
852 tlserror ("gnutls_session_id", ret);
853 }
854 }
855
856 /*
857 * @brief Get the cipher suite used by a SSL/TLS connection.
858 *
859 * @param[in] fd Socket file descriptor.
860 *
861 * @return Cipher Suite ID, -1 if error.
862 */
863 int
socket_get_ssl_ciphersuite(int fd)864 socket_get_ssl_ciphersuite (int fd)
865 {
866 gnutls_session_t session;
867 gnutls_kx_algorithm_t kx, kx2;
868 gnutls_cipher_algorithm_t cipher, cipher2;
869 gnutls_mac_algorithm_t mac, mac2;
870 size_t idx = 0;
871 unsigned char cs_id[2];
872
873 if (!fd_is_stream (fd))
874 {
875 g_message ("Socket %d is not stream", fd);
876 return -1;
877 }
878 session = ovas_get_tlssession_from_connection (fd);
879 if (!session)
880 {
881 g_message ("Socket %d is not SSL/TLS encapsulated", fd);
882 return -1;
883 }
884
885 kx = gnutls_kx_get (session);
886 cipher = gnutls_cipher_get (session);
887 mac = gnutls_mac_get (session);
888 while (
889 gnutls_cipher_suite_info (idx, (void *) cs_id, &kx2, &cipher2, &mac2, NULL))
890 {
891 if (kx == kx2 && cipher == cipher2 && mac == mac2)
892 return cs_id[0] + cs_id[1];
893 idx++;
894 }
895 return -1;
896 }
897
898 /* Extended version of open_stream_connection to allow passing a
899 priority string.
900
901 ABI_BREAK_NOTE: Merge this with open_stream_connection. */
902 int
open_stream_connection_ext(struct script_infos * args,unsigned int port,int transport,int timeout,const char * priority)903 open_stream_connection_ext (struct script_infos *args, unsigned int port,
904 int transport, int timeout, const char *priority)
905 {
906 int fd;
907 openvas_connection *fp;
908 char *cert = NULL;
909 char *key = NULL;
910 char *passwd = NULL;
911 char *cafile = NULL;
912 char *hostname = NULL;
913 char *hostname_aux = NULL;
914
915 /* Because plug_get_host_fqdn() forks for each vhost, we fork() before
916 creating the socket */
917 hostname_aux = plug_get_host_fqdn (args);
918
919 if (!priority)
920 priority = ""; /* To us an empty string is equivalent to NULL. */
921
922 g_debug ("[%d] open_stream_connection: TCP:%d transport:%d timeout:%d "
923 " priority: '%s'",
924 getpid (), port, transport, timeout, priority);
925
926 if (timeout == -2)
927 timeout = TIMEOUT;
928
929 switch (transport)
930 {
931 case OPENVAS_ENCAPS_IP:
932
933 case OPENVAS_ENCAPS_SSLv23:
934 case OPENVAS_ENCAPS_SSLv3:
935 case OPENVAS_ENCAPS_TLSv1:
936 case OPENVAS_ENCAPS_TLSv11:
937 case OPENVAS_ENCAPS_TLSv12:
938 case OPENVAS_ENCAPS_TLSv13:
939 case OPENVAS_ENCAPS_TLScustom:
940 case OPENVAS_ENCAPS_SSLv2:
941 break;
942
943 default:
944 g_message ("open_stream_connection_ext(): unsupported transport"
945 " layer %d passed by %s",
946 transport, args->name);
947 errno = EINVAL;
948
949 g_free (hostname_aux);
950 return -1;
951 }
952
953 if ((fd = get_connection_fd ()) < 0)
954 {
955 g_free (hostname_aux);
956 return -1;
957 }
958 fp = OVAS_CONNECTION_FROM_FD (fd);
959
960 fp->transport = transport;
961 g_free (fp->priority);
962 if (*priority)
963 fp->priority = g_strdup (priority);
964 else
965 fp->priority = NULL;
966 fp->timeout = timeout;
967 fp->port = port;
968 fp->last_err = 0;
969
970 fp->fd = open_sock_tcp (args, port, timeout);
971 if (fp->fd < 0)
972 goto failed;
973
974 kb_t kb = plug_get_kb (args);
975 switch (transport)
976 {
977 int ret;
978 char buf[1024];
979
980 case OPENVAS_ENCAPS_IP:
981 break;
982 case OPENVAS_ENCAPS_SSLv23:
983 case OPENVAS_ENCAPS_SSLv3:
984 case OPENVAS_ENCAPS_TLSv1:
985 case OPENVAS_ENCAPS_TLSv11:
986 case OPENVAS_ENCAPS_TLSv12:
987 case OPENVAS_ENCAPS_TLSv13:
988 case OPENVAS_ENCAPS_TLScustom:
989 cert = kb_item_get_str (kb, "SSL/cert");
990 key = kb_item_get_str (kb, "SSL/key");
991 passwd = kb_item_get_str (kb, "SSL/password");
992
993 cafile = kb_item_get_str (kb, "SSL/CA");
994
995 /* fall through */
996
997 case OPENVAS_ENCAPS_SSLv2:
998 /* We do not need a client certificate in this case */
999 snprintf (buf, sizeof (buf), "Host/SNI/%d/force_disable", fp->port);
1000 if (kb_item_get_int (kb, buf) <= 0)
1001 hostname = hostname_aux;
1002
1003 ret = open_SSL_connection (fp, cert, key, passwd, cafile, hostname);
1004 g_free (cert);
1005 g_free (key);
1006 g_free (passwd);
1007 g_free (cafile);
1008 if (ret <= 0)
1009 goto failed;
1010 break;
1011 }
1012
1013 g_free (hostname_aux);
1014
1015 return fd;
1016
1017 failed:
1018 release_connection_fd (fd, 0);
1019 return -1;
1020 }
1021
1022 int
open_stream_connection(struct script_infos * args,unsigned int port,int transport,int timeout)1023 open_stream_connection (struct script_infos *args, unsigned int port,
1024 int transport, int timeout)
1025 {
1026 return open_stream_connection_ext (args, port, transport, timeout,
1027 "NORMAL:+ARCFOUR-128:%COMPAT");
1028 }
1029
1030 /* Same as open_stream_auto_encaps but allows to force auto detection
1031 of the protocols if FORCE is true. */
1032 int
open_stream_auto_encaps_ext(struct script_infos * args,unsigned int port,int timeout,int force)1033 open_stream_auto_encaps_ext (struct script_infos *args, unsigned int port,
1034 int timeout, int force)
1035 {
1036 int fd, transport;
1037
1038 if (force)
1039 {
1040 /* Try SSL/TLS first */
1041 transport = OPENVAS_ENCAPS_TLScustom;
1042 fd = open_stream_connection (args, port, transport, timeout);
1043 if (fd < 0)
1044 {
1045 transport = OPENVAS_ENCAPS_IP;
1046 fd = open_stream_connection (args, port, OPENVAS_ENCAPS_IP, timeout);
1047 if (fd < 0)
1048 return -1;
1049 }
1050 /* Store that encapsulation mode in the KB. */
1051 plug_set_port_transport (args, port, transport);
1052 return fd;
1053 }
1054 else
1055 {
1056 transport = plug_get_port_transport (args, port);
1057 fd = open_stream_connection (args, port, transport, timeout);
1058 return fd;
1059 }
1060 /*NOTREACHED*/
1061 }
1062
1063 int
stream_set_timeout(int fd,int timeout)1064 stream_set_timeout (int fd, int timeout)
1065 {
1066 int old;
1067 openvas_connection *fp;
1068 if (!OPENVAS_STREAM (fd))
1069 {
1070 errno = EINVAL;
1071 return 0;
1072 }
1073 fp = OVAS_CONNECTION_FROM_FD (fd);
1074 old = fp->timeout;
1075 fp->timeout = timeout;
1076 return old;
1077 }
1078
1079 static int
read_stream_connection_unbuffered(int fd,void * buf0,int min_len,int max_len)1080 read_stream_connection_unbuffered (int fd, void *buf0, int min_len, int max_len)
1081 {
1082 int ret, realfd, trp, t, select_status;
1083 int total = 0, flag = 0, timeout = TIMEOUT, waitall = 0;
1084 unsigned char *buf = (unsigned char *) buf0;
1085 openvas_connection *fp = NULL;
1086 fd_set fdr, fdw;
1087 struct timeval tv;
1088 time_t now, then;
1089
1090 if (OPENVAS_STREAM (fd))
1091 {
1092 fp = OVAS_CONNECTION_FROM_FD (fd);
1093 trp = fp->transport;
1094 realfd = fp->fd;
1095 fp->last_err = 0;
1096 if (fp->timeout != -2)
1097 timeout = fp->timeout;
1098 }
1099 else
1100 {
1101 trp = OPENVAS_ENCAPS_IP;
1102 if (fd < 0 || fd > 1024)
1103 {
1104 errno = EBADF;
1105 return -1;
1106 }
1107 realfd = fd;
1108 }
1109
1110 #ifndef INCR_TIMEOUT
1111 #define INCR_TIMEOUT 1
1112 #endif
1113
1114 if (min_len == max_len || timeout <= 0)
1115 waitall = MSG_WAITALL;
1116 if (trp == OPENVAS_ENCAPS_IP)
1117 {
1118 for (t = 0; total < max_len && (timeout <= 0 || t < timeout);)
1119 {
1120 tv.tv_sec = INCR_TIMEOUT; /* Not timeout! */
1121 tv.tv_usec = 0;
1122 FD_ZERO (&fdr);
1123 FD_SET (realfd, &fdr);
1124 if (select (realfd + 1, &fdr, NULL, NULL, timeout > 0 ? &tv : NULL)
1125 <= 0)
1126 {
1127 t += INCR_TIMEOUT;
1128 /* Try to be smart */
1129 if (total > 0 && flag)
1130 return total;
1131 else if (total >= min_len)
1132 flag++;
1133 }
1134 else
1135 {
1136 errno = 0;
1137 ret = recv (realfd, buf + total, max_len - total, waitall);
1138 if (ret < 0)
1139 if (errno != EINTR)
1140 {
1141 return total;
1142 }
1143 else
1144 ret = 0;
1145 else if (ret == 0) /* EOF */
1146 {
1147 return total;
1148 }
1149 /*ret > 0 */
1150 total += ret;
1151 if (min_len > 0 && total >= min_len)
1152 return total;
1153 flag = 0;
1154 }
1155 }
1156 return total;
1157 }
1158
1159 switch (trp)
1160 {
1161 /* OPENVAS_ENCAPS_IP was treated before with the non-OpenVAS fd */
1162 case OPENVAS_ENCAPS_SSLv2:
1163 case OPENVAS_ENCAPS_SSLv23:
1164 case OPENVAS_ENCAPS_SSLv3:
1165 case OPENVAS_ENCAPS_TLSv1:
1166 case OPENVAS_ENCAPS_TLSv11:
1167 case OPENVAS_ENCAPS_TLSv12:
1168 case OPENVAS_ENCAPS_TLSv13:
1169 case OPENVAS_ENCAPS_TLScustom:
1170 if (getpid () != fp->pid)
1171 {
1172 g_debug ("PID %d tries to use a SSL/TLS connection established "
1173 "by PID %d\n",
1174 getpid (), fp->pid);
1175 errno = EINVAL;
1176 return -1;
1177 }
1178
1179 then = time (NULL);
1180 for (t = 0; timeout <= 0 || t < timeout; t = now - then)
1181 {
1182 now = time (NULL);
1183 tv.tv_sec = INCR_TIMEOUT;
1184 tv.tv_usec = 0;
1185 FD_ZERO (&fdr);
1186 FD_ZERO (&fdw);
1187 FD_SET (realfd, &fdr);
1188 FD_SET (realfd, &fdw);
1189
1190 select_status = select (realfd + 1, &fdr, &fdw, NULL, &tv);
1191
1192 if (select_status > 0)
1193 {
1194 /* TLS FIXME: handle rehandshake */
1195 ret = gnutls_record_recv (fp->tls_session, buf + total,
1196 max_len - total);
1197 if (ret > 0)
1198 {
1199 total += ret;
1200 if (total >= max_len)
1201 return total;
1202 }
1203 else if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN)
1204 {
1205 /* This branch also handles the case where ret == 0,
1206 * i.e. that the connection has been closed. This is
1207 * for compatibility with the old OpenSSL based openvas
1208 * code which treated SSL_ERROR_ZERO_RETURN as an
1209 * error too.
1210 */
1211 if (ret < 0)
1212 pid_perror ("gnutls_record_recv");
1213 else
1214 g_debug ("gnutls_record_recv[%d]: EOF\n", getpid ());
1215 fp->last_err = EPIPE;
1216 return total;
1217 }
1218 }
1219
1220 if (min_len > 0 && total >= min_len)
1221 return total;
1222 }
1223 if (t >= timeout)
1224 fp->last_err = ETIMEDOUT;
1225 return total;
1226
1227 default:
1228 if (fp->transport || fp->fd != 0)
1229 g_message ("Function %s (calling internal function %s) called from %s: "
1230 "Severe bug! Unhandled transport layer %d (fd=%d).",
1231 nasl_get_function_name () ?: "script_main_function",
1232 __func__, nasl_get_plugin_filename (), fp->transport, fd);
1233 else
1234 g_message ("read_stream_connection_unbuffered: "
1235 "fd=%d is closed",
1236 fd);
1237 errno = EINVAL;
1238 return -1;
1239 }
1240 /*NOTREACHED*/
1241 }
1242
1243 int
read_stream_connection_min(int fd,void * buf0,int min_len,int max_len)1244 read_stream_connection_min (int fd, void *buf0, int min_len, int max_len)
1245 {
1246 openvas_connection *fp;
1247
1248 if (OPENVAS_STREAM (fd))
1249 {
1250 fp = OVAS_CONNECTION_FROM_FD (fd);
1251 if (fp->buf != NULL)
1252 {
1253 int l1, l2;
1254
1255 if (max_len == 1)
1256 min_len = 1; /* avoid "magic read" later */
1257 l2 = max_len > fp->bufcnt ? fp->bufcnt : max_len;
1258 if (l2 > 0)
1259 {
1260 memcpy (buf0, fp->buf + fp->bufptr, l2);
1261 fp->bufcnt -= l2;
1262 if (fp->bufcnt == 0)
1263 {
1264 fp->bufptr = 0;
1265 fp->buf[0] = '\0'; /* debug */
1266 }
1267 else
1268 fp->bufptr += l2;
1269 if (l2 >= min_len || l2 >= max_len)
1270 return l2;
1271 max_len -= l2;
1272 min_len -= l2;
1273 }
1274 if (min_len > fp->bufsz)
1275 {
1276 l1 = read_stream_connection_unbuffered (fd, (char *) buf0 + l2,
1277 min_len, max_len);
1278 if (l1 > 0)
1279 return l1 + l2;
1280 else
1281 return l2;
1282 }
1283 /* Fill buffer */
1284 l1 =
1285 read_stream_connection_unbuffered (fd, fp->buf, min_len, fp->bufsz);
1286 if (l1 <= 0)
1287 return l2;
1288
1289 fp->bufcnt = l1;
1290 l1 = max_len > fp->bufcnt ? fp->bufcnt : max_len;
1291 memcpy ((char *) buf0 + l2, fp->buf + fp->bufptr, l1);
1292 fp->bufcnt -= l1;
1293 if (fp->bufcnt == 0)
1294 fp->bufptr = 0;
1295 else
1296 fp->bufptr += l1;
1297 return l1 + l2;
1298 }
1299 }
1300 return read_stream_connection_unbuffered (fd, buf0, min_len, max_len);
1301 }
1302
1303 int
read_stream_connection(int fd,void * buf0,int len)1304 read_stream_connection (int fd, void *buf0, int len)
1305 {
1306 return read_stream_connection_min (fd, buf0, -1, len);
1307 }
1308
1309 static int
write_stream_connection4(int fd,void * buf0,int n,int i_opt)1310 write_stream_connection4 (int fd, void *buf0, int n, int i_opt)
1311 {
1312 int ret, count;
1313 unsigned char *buf = (unsigned char *) buf0;
1314 openvas_connection *fp;
1315 fd_set fdr, fdw;
1316 struct timeval tv;
1317 int e;
1318
1319 if (!OPENVAS_STREAM (fd))
1320 {
1321 g_debug ("write_stream_connection: fd <%d> invalid\n", fd);
1322 errno = EINVAL;
1323 return -1;
1324 }
1325
1326 fp = OVAS_CONNECTION_FROM_FD (fd);
1327 fp->last_err = 0;
1328
1329 switch (fp->transport)
1330 {
1331 case OPENVAS_ENCAPS_IP:
1332 for (count = 0; count < n;)
1333 {
1334 ret = send (fp->fd, buf + count, n - count, i_opt);
1335
1336 if (ret <= 0)
1337 {
1338 if (ret < 0)
1339 fp->last_err = errno;
1340 else
1341 fp->last_err = EPIPE;
1342 break;
1343 }
1344
1345 count += ret;
1346 }
1347 break;
1348
1349 case OPENVAS_ENCAPS_SSLv2:
1350 case OPENVAS_ENCAPS_SSLv23:
1351 case OPENVAS_ENCAPS_SSLv3:
1352 case OPENVAS_ENCAPS_TLSv1:
1353 case OPENVAS_ENCAPS_TLSv11:
1354 case OPENVAS_ENCAPS_TLSv12:
1355 case OPENVAS_ENCAPS_TLSv13:
1356 case OPENVAS_ENCAPS_TLScustom:
1357
1358 /* i_opt ignored for SSL */
1359 for (count = 0; count < n;)
1360 {
1361 ret = gnutls_record_send (fp->tls_session, buf + count, n - count);
1362
1363 if (ret > 0)
1364 {
1365 count += ret;
1366 }
1367 else if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN)
1368 {
1369 /* This branch also handles the case where ret == 0,
1370 * i.e. that the connection has been closed. This is
1371 * for compatibility with the old openvas code which
1372 * treated SSL_ERROR_ZERO_RETURN as an error too.
1373 */
1374 if (ret < 0)
1375 pid_perror ("gnutls_record_send");
1376 else
1377 g_debug ("gnutls_record_send[%d]: EOF\n", getpid ());
1378 fp->last_err = EPIPE;
1379 break;
1380 }
1381
1382 if (fp->timeout >= 0)
1383 tv.tv_sec = fp->timeout;
1384 else
1385 tv.tv_sec = TIMEOUT;
1386 tv.tv_usec = 0;
1387
1388 do
1389 {
1390 errno = 0;
1391 FD_ZERO (&fdr);
1392 FD_ZERO (&fdw);
1393 FD_SET (fp->fd, &fdr);
1394 FD_SET (fp->fd, &fdw);
1395 e = select (fp->fd + 1, &fdr, &fdw, NULL, &tv);
1396 }
1397 while (e < 0 && errno == EINTR);
1398
1399 if (e <= 0)
1400 {
1401 pid_perror ("select");
1402 fp->last_err = ETIMEDOUT;
1403 break;
1404 }
1405 }
1406 break;
1407
1408 default:
1409 if (fp->transport || fp->fd != 0)
1410 g_message ("Function %s (calling internal function %s) called from %s: "
1411 "Severe bug! Unhandled transport layer %d (fd=%d).",
1412 nasl_get_function_name () ?: "script_main_function",
1413 __func__, nasl_get_plugin_filename (), fp->transport, fd);
1414 else
1415 g_message ("read_stream_connection_unbuffered: fd=%d is "
1416 "closed",
1417 fd);
1418 errno = EINVAL;
1419 return -1;
1420 }
1421
1422 if (count == 0 && n > 0)
1423 return -1;
1424 else
1425 return count;
1426 }
1427
1428 int
write_stream_connection(int fd,void * buf0,int n)1429 write_stream_connection (int fd, void *buf0, int n)
1430 {
1431 return write_stream_connection4 (fd, buf0, n, 0);
1432 }
1433
1434 int
nsend(int fd,void * data,int length,int i_opt)1435 nsend (int fd, void *data, int length, int i_opt)
1436 {
1437 int n = 0;
1438
1439 if (OPENVAS_STREAM (fd))
1440 {
1441 if (connections[fd - OPENVAS_FD_OFF].fd < 0)
1442 g_message ("OpenVAS file descriptor %d closed ?!", fd);
1443 else
1444 return write_stream_connection4 (fd, data, length, i_opt);
1445 }
1446 /* Trying OS's send() */
1447 block_socket (fd); /* ??? */
1448 do
1449 {
1450 struct timeval tv = {0, 5};
1451 fd_set wr;
1452 int e;
1453
1454 FD_ZERO (&wr);
1455 FD_SET (fd, &wr);
1456
1457 errno = 0;
1458 e = select (fd + 1, NULL, &wr, NULL, &tv);
1459 if (e > 0)
1460 n = os_send (fd, data, length, i_opt);
1461 else if (e < 0 && errno == EINTR)
1462 continue;
1463 else
1464 break;
1465 }
1466 while (n <= 0 && errno == EINTR);
1467 if (n < 0)
1468 g_message ("[%d] nsend():send %s", getpid (), strerror (errno));
1469
1470 return n;
1471 }
1472
1473 int
nrecv(int fd,void * data,int length,int i_opt)1474 nrecv (int fd, void *data, int length, int i_opt)
1475 {
1476 int e;
1477 if (OPENVAS_STREAM (fd))
1478 {
1479 if (connections[fd - OPENVAS_FD_OFF].fd < 0)
1480 g_message ("OpenVAS file descriptor %d closed ?!", fd);
1481 else
1482 return read_stream_connection (fd, data, length);
1483 }
1484 /* Trying OS's recv()
1485 *
1486 * Do *NOT* use os_recv() here, as it will be blocking until the exact
1487 * amount of requested data arrives
1488 */
1489 block_socket (fd);
1490 do
1491 {
1492 e = recv (fd, data, length, i_opt);
1493 }
1494 while (e < 0 && errno == EINTR);
1495 return e;
1496 }
1497
1498 /**
1499 * @brief Register a hook function for close_stream_connection.
1500 *
1501 * The function adds the given hook function to the list of hooks to
1502 * be run by close_stream_connection. These hooks are intended to
1503 * test whether they need to close the stream them self. See argument
1504 * to the hook function is the file descriptor of the stream. The
1505 * hook shall return 0 if it has taken over control of that file
1506 * descriptor. The same function is only aded once to the list of
1507 * hooks.
1508 *
1509 * @param fnc The hook function. See above for details.
1510 */
1511 void
add_close_stream_connection_hook(int (* fnc)(int fd))1512 add_close_stream_connection_hook (int (*fnc) (int fd))
1513 {
1514 struct csc_hook_s *hook;
1515
1516 for (hook = csc_hooks; hook; hook = hook->next)
1517 if (hook->fnc == fnc)
1518 return; /* Already added. */
1519
1520 hook = g_malloc0 (sizeof *hook);
1521 hook->fnc = fnc;
1522 hook->next = csc_hooks;
1523 csc_hooks = hook;
1524 }
1525
1526 /**
1527 * @brief Run the hooks for close_stream_connection.
1528 *
1529 * The function runs all registered hooks until the first hook returns
1530 * with zero to indicate that it has taken over control of the socket.
1531 * Further hooks are then not anymore run because the file descriptor
1532 * is not anymore valid.
1533 *
1534 * @param fd The file descriptor of the stream.
1535
1536 * @return Zero if one of the hooks has closed the connection;
1537 * non-zero otherwise.
1538 */
1539 static int
run_csc_hooks(int fd)1540 run_csc_hooks (int fd)
1541 {
1542 struct csc_hook_s *hook;
1543
1544 for (hook = csc_hooks; hook; hook = hook->next)
1545 if (hook->fnc && !hook->fnc (fd))
1546 return 0;
1547 return -1;
1548 }
1549
1550 int
close_stream_connection(int fd)1551 close_stream_connection (int fd)
1552 {
1553 openvas_connection *fp;
1554 if (!OPENVAS_STREAM (fd))
1555 {
1556 errno = EINVAL;
1557 return -1;
1558 }
1559 fp = OVAS_CONNECTION_FROM_FD (fd);
1560 g_debug ("close_stream_connection TCP:%d (fd=%d)", fp->port, fd);
1561
1562 if (!OPENVAS_STREAM (fd)) /* Will never happen if debug is on! */
1563 {
1564 if (fd < 0 || fd > 1024)
1565 {
1566 errno = EINVAL;
1567 return -1;
1568 }
1569 shutdown (fd, 2);
1570 return socket_close (fd);
1571 }
1572 if (!run_csc_hooks (fd))
1573 return release_connection_fd (fd, 1);
1574 else
1575 return release_connection_fd (fd, 0);
1576 }
1577
1578 const char *
get_encaps_name(openvas_encaps_t code)1579 get_encaps_name (openvas_encaps_t code)
1580 {
1581 static char str[100];
1582 switch (code)
1583 {
1584 case OPENVAS_ENCAPS_AUTO:
1585 return "auto";
1586 case OPENVAS_ENCAPS_IP:
1587 return "IP";
1588 case OPENVAS_ENCAPS_SSLv2:
1589 return "SSLv2";
1590 case OPENVAS_ENCAPS_SSLv23:
1591 return "SSLv23";
1592 case OPENVAS_ENCAPS_SSLv3:
1593 return "SSLv3";
1594 case OPENVAS_ENCAPS_TLSv1:
1595 return "TLSv1";
1596 case OPENVAS_ENCAPS_TLSv11:
1597 return "TLSv11";
1598 case OPENVAS_ENCAPS_TLSv12:
1599 return "TLSv12";
1600 case OPENVAS_ENCAPS_TLSv13:
1601 return "TLSv13";
1602 case OPENVAS_ENCAPS_TLScustom:
1603 return "TLScustom";
1604 default:
1605 snprintf (str, sizeof (str), "[unknown transport layer - code %d (0x%x)]",
1606 code, code);
1607 return str;
1608 }
1609 }
1610
1611 const char *
get_encaps_through(openvas_encaps_t code)1612 get_encaps_through (openvas_encaps_t code)
1613 {
1614 static char str[100];
1615 switch (code)
1616 {
1617 case OPENVAS_ENCAPS_IP:
1618 return "";
1619 case OPENVAS_ENCAPS_SSLv2:
1620 case OPENVAS_ENCAPS_SSLv23:
1621 case OPENVAS_ENCAPS_SSLv3:
1622 case OPENVAS_ENCAPS_TLSv1:
1623 case OPENVAS_ENCAPS_TLSv11:
1624 case OPENVAS_ENCAPS_TLSv12:
1625 case OPENVAS_ENCAPS_TLSv13:
1626 case OPENVAS_ENCAPS_TLScustom:
1627 return " through SSL";
1628 default:
1629 snprintf (str, sizeof (str),
1630 " through unknown transport layer - code %d (0x%x)", code,
1631 code);
1632 return str;
1633 }
1634 }
1635
1636 static int
open_socket(struct sockaddr * paddr,int type,int protocol,int timeout,int len)1637 open_socket (struct sockaddr *paddr, int type, int protocol, int timeout,
1638 int len)
1639 {
1640 fd_set fd_w;
1641 struct timeval to;
1642 int soc, x;
1643 int opt;
1644 unsigned int opt_sz;
1645 int family;
1646
1647 __port_closed = 0;
1648
1649 if (paddr->sa_family == AF_INET)
1650 {
1651 family = AF_INET;
1652 if ((soc = socket (AF_INET, type, protocol)) < 0)
1653 {
1654 pid_perror ("socket");
1655 return -1;
1656 }
1657 }
1658 else
1659 {
1660 family = AF_INET6;
1661 if ((soc = socket (AF_INET6, type, protocol)) < 0)
1662 {
1663 pid_perror ("socket");
1664 return -1;
1665 }
1666 }
1667
1668 if (timeout == -2)
1669 timeout = TIMEOUT;
1670
1671 if (timeout > 0)
1672 if (unblock_socket (soc) < 0)
1673 {
1674 close (soc);
1675 return -1;
1676 }
1677
1678 gvm_source_set_socket (soc, 0, family);
1679
1680 if (connect (soc, paddr, len) < 0)
1681 {
1682 pid_perror ("connect");
1683 again:
1684 switch (errno)
1685 {
1686 case EINPROGRESS:
1687 case EAGAIN:
1688 FD_ZERO (&fd_w);
1689 FD_SET (soc, &fd_w);
1690 to.tv_sec = timeout;
1691 to.tv_usec = 0;
1692 x = select (soc + 1, NULL, &fd_w, NULL, &to);
1693 if (x == 0)
1694 {
1695 pid_perror ("connect->select: timeout");
1696 socket_close (soc);
1697 errno = ETIMEDOUT;
1698 return -1;
1699 }
1700 else if (x < 0)
1701 {
1702 if (errno == EINTR)
1703 {
1704 errno = EAGAIN;
1705 goto again;
1706 }
1707 pid_perror ("select");
1708 socket_close (soc);
1709 return -1;
1710 }
1711
1712 opt = 0;
1713 opt_sz = sizeof (opt);
1714 if (getsockopt (soc, SOL_SOCKET, SO_ERROR, &opt, &opt_sz) < 0)
1715 {
1716 pid_perror ("getsockopt");
1717 socket_close (soc);
1718 return -1;
1719 }
1720 if (opt == 0)
1721 break;
1722 errno = opt;
1723 pid_perror ("SO_ERROR");
1724 /* fallthrough */
1725 default:
1726 __port_closed = 1;
1727 socket_close (soc);
1728 return -1;
1729 }
1730 }
1731 block_socket (soc);
1732 return soc;
1733 }
1734
1735 int
open_sock_opt_hn(const char * hostname,unsigned int port,int type,int protocol,int timeout)1736 open_sock_opt_hn (const char *hostname, unsigned int port, int type,
1737 int protocol, int timeout)
1738 {
1739 struct sockaddr_in addr;
1740 struct sockaddr_in6 addr6;
1741 struct in6_addr in6addr;
1742
1743 gvm_resolve_as_addr6 (hostname, &in6addr);
1744 if (IN6_IS_ADDR_V4MAPPED (&in6addr))
1745 {
1746 bzero ((void *) &addr, sizeof (addr));
1747 addr.sin_family = AF_INET;
1748 addr.sin_port = htons ((unsigned short) port);
1749 addr.sin_addr.s_addr = in6addr.s6_addr32[3];
1750 return open_socket ((struct sockaddr *) &addr, type, protocol, timeout,
1751 sizeof (struct sockaddr_in));
1752 }
1753 else
1754 {
1755 bzero ((void *) &addr6, sizeof (addr6));
1756 addr6.sin6_family = AF_INET6;
1757 addr6.sin6_port = htons ((unsigned short) port);
1758 memcpy (&addr6.sin6_addr, &in6addr, sizeof (struct in6_addr));
1759 return open_socket ((struct sockaddr *) &addr6, type, protocol, timeout,
1760 sizeof (struct sockaddr_in6));
1761 }
1762 }
1763
1764 int
open_sock_tcp(struct script_infos * args,unsigned int port,int timeout)1765 open_sock_tcp (struct script_infos *args, unsigned int port, int timeout)
1766 {
1767 int ret, retry = 0;
1768 const char *timeout_retry;
1769
1770 timeout_retry = prefs_get ("timeout_retry");
1771 if (timeout_retry)
1772 retry = atoi (timeout_retry);
1773 if (retry < 0)
1774 retry = 0;
1775
1776 while (retry >= 0)
1777 {
1778 errno = 0;
1779 ret = open_sock_option (args, port, SOCK_STREAM, IPPROTO_TCP, timeout);
1780 if (ret >= 0 || errno != ETIMEDOUT)
1781 break;
1782 retry--;
1783 }
1784 if (ret < 0 && errno == ETIMEDOUT)
1785 {
1786 int log_count, attempts = 0;
1787 char *ip_str = plug_get_host_ip_str (args), buffer[1024];
1788 kb_t kb = plug_get_kb (args);
1789 const char *max_attempts;
1790
1791 max_attempts = prefs_get ("open_sock_max_attempts");
1792 if (max_attempts)
1793 attempts = atoi (max_attempts);
1794 if (attempts < 0)
1795 attempts = 0;
1796
1797 g_snprintf (buffer, sizeof (buffer), "ConnectTimeout/%s/%d", ip_str,
1798 port);
1799 log_count = kb_item_get_int (kb, buffer);
1800 if (log_count == -1)
1801 log_count = 0;
1802 if (log_count < 3)
1803 {
1804 g_message ("open_sock_tcp: %s:%d time-out.", ip_str, port);
1805 log_count++;
1806 kb_item_set_int (kb, buffer, log_count);
1807 }
1808 if ((log_count >= attempts) && (attempts != 0))
1809 {
1810 /* After some unsuccessfully attempts, the port is set to closed to
1811 * avoid new attempts from other plugins.
1812 */
1813 if (host_get_port_state (args, port) > 0)
1814 {
1815 char ip_str[INET6_ADDRSTRLEN];
1816
1817 g_snprintf (buffer, sizeof (buffer), "Ports/tcp/%d", port);
1818 g_message ("open_sock_tcp: %s:%d too many timeouts. "
1819 "This port will be set to closed.",
1820 ip_str, port);
1821 kb_item_set_int (kb, buffer, 0);
1822
1823 addr6_to_str (args->ip, ip_str);
1824 snprintf (
1825 buffer, sizeof (buffer),
1826 "ERRMSG|||%s|||%s|||%d/tcp||| |||Too many timeouts. The port"
1827 " was set to closed.",
1828 ip_str, plug_current_vhost () ?: " ", port);
1829 kb_item_push_str (args->results, "internal/results", buffer);
1830 }
1831 }
1832 g_free (ip_str);
1833 }
1834
1835 return ret;
1836 }
1837
1838 int
open_sock_option(struct script_infos * args,unsigned int port,int type,int protocol,int timeout)1839 open_sock_option (struct script_infos *args, unsigned int port, int type,
1840 int protocol, int timeout)
1841 {
1842 struct sockaddr_in addr;
1843 struct sockaddr_in6 addr6;
1844 struct in6_addr *t;
1845
1846 t = plug_get_host_ip (args);
1847 if (!t)
1848 {
1849 g_message ("ERROR ! NO ADDRESS ASSOCIATED WITH NAME");
1850 return (-1);
1851 }
1852 if (IN6_ARE_ADDR_EQUAL (t, &in6addr_any))
1853 return (-1);
1854 if (IN6_IS_ADDR_V4MAPPED (t))
1855 {
1856 bzero ((void *) &addr, sizeof (addr));
1857 addr.sin_family = AF_INET;
1858 addr.sin_port = htons ((unsigned short) port);
1859 addr.sin_addr.s_addr = t->s6_addr32[3];
1860 return open_socket ((struct sockaddr *) &addr, type, protocol, timeout,
1861 sizeof (struct sockaddr_in));
1862 }
1863 else
1864 {
1865 bzero ((void *) &addr6, sizeof (addr6));
1866 addr6.sin6_family = AF_INET6;
1867 addr6.sin6_port = htons ((unsigned short) port);
1868 memcpy (&addr6.sin6_addr, t, sizeof (struct in6_addr));
1869 return open_socket ((struct sockaddr *) &addr6, type, protocol, timeout,
1870 sizeof (struct sockaddr_in6));
1871 }
1872 }
1873
1874 /**
1875 * @brief Reads a text from the socket stream into the argument buffer, always
1876 * @brief appending a '\\0' byte.
1877 *
1878 * @param buf Buffer to read into.
1879 *
1880 * @return Number of bytes read, without the trailing '\\0'.
1881 */
1882 int
recv_line(int soc,char * buf,size_t bufsiz)1883 recv_line (int soc, char *buf, size_t bufsiz)
1884 {
1885 int n;
1886 unsigned int ret = 0;
1887
1888 /* Dirty SSL hack */
1889 if (OPENVAS_STREAM (soc))
1890 {
1891 unsigned int ret = 0;
1892 buf[0] = '\0';
1893
1894 do
1895 {
1896 n = read_stream_connection_min (soc, buf + ret, 1, 1);
1897 switch (n)
1898 {
1899 case -1:
1900 if (ret == 0)
1901 return -1;
1902 else
1903 return ret;
1904 break;
1905
1906 case 0:
1907 return ret;
1908 break;
1909
1910 default:
1911 ret++;
1912 }
1913 }
1914 while (buf[ret - 1] != '\0' && buf[ret - 1] != '\n' && ret < bufsiz);
1915
1916 if (ret > 0)
1917 {
1918 if (buf[ret - 1] != '\0')
1919 {
1920 if (ret < bufsiz)
1921 buf[ret] = '\0';
1922 else
1923 buf[bufsiz - 1] = '\0';
1924 }
1925 }
1926
1927 return ret;
1928 }
1929 else
1930 {
1931 fd_set rd;
1932
1933 do
1934 {
1935 int e;
1936 again:
1937 errno = 0;
1938 FD_ZERO (&rd);
1939 FD_SET (soc, &rd);
1940 e = select (soc + 1, &rd, NULL, NULL, NULL);
1941 if (e == 0 && !FD_ISSET (soc, &rd))
1942 return -1;
1943 if (e < 0 && errno == EINTR)
1944 goto again;
1945 if (e > 0)
1946 {
1947 n = recv (soc, buf + ret, 1, 0);
1948 switch (n)
1949 {
1950 case -1:
1951 if (errno == EINTR)
1952 continue;
1953 if (ret == 0)
1954 return -1;
1955 else
1956 return ret;
1957 break;
1958 case 0:
1959 return ret;
1960 break;
1961 default:
1962 ret++;
1963 }
1964 }
1965 else
1966 break;
1967 }
1968 while (buf[ret - 1] != '\0' && buf[ret - 1] != '\n' && ret < bufsiz);
1969
1970 if (ret > 0)
1971 {
1972 if (buf[ret - 1] != '\0')
1973 {
1974 if (ret < bufsiz)
1975 buf[ret] = '\0';
1976 else
1977 buf[bufsiz - 1] = '\0';
1978 }
1979 }
1980 }
1981
1982 return ret;
1983 }
1984
1985 int
socket_close(int soc)1986 socket_close (int soc)
1987 {
1988 return close (soc);
1989 }
1990
1991 /*
1992 * Select() routines
1993 */
1994
1995 int
fd_is_stream(int fd)1996 fd_is_stream (int fd)
1997 {
1998 return OPENVAS_STREAM (fd); /* Should probably be smarter... */
1999 }
2000
2001 int
stream_get_buffer_sz(int fd)2002 stream_get_buffer_sz (int fd)
2003 {
2004 openvas_connection *p;
2005 if (!OPENVAS_STREAM (fd))
2006 return -1;
2007 p = OVAS_CONNECTION_FROM_FD (fd);
2008 return p->bufsz;
2009 }
2010
2011 int
stream_set_buffer(int fd,int sz)2012 stream_set_buffer (int fd, int sz)
2013 {
2014 openvas_connection *p;
2015 char *b;
2016
2017 if (!OPENVAS_STREAM (fd))
2018 return -1;
2019
2020 p = OVAS_CONNECTION_FROM_FD (fd);
2021 if (sz < p->bufcnt)
2022 return -1; /* Do not want to lose data */
2023
2024 if (sz == 0)
2025 {
2026 g_free (p->buf);
2027 p->buf = NULL;
2028 p->bufsz = 0;
2029 return 0;
2030 }
2031 else if (p->buf == 0)
2032 {
2033 p->buf = g_malloc0 (sz);
2034 if (p->buf == NULL)
2035 return -1;
2036 p->bufsz = sz;
2037 p->bufptr = 0;
2038 p->bufcnt = 0;
2039 return 0;
2040 }
2041 else
2042 {
2043 if (p->bufcnt > 0)
2044 {
2045 memmove (p->buf, p->buf + p->bufptr, p->bufcnt);
2046 p->bufptr = 0;
2047 }
2048 b = g_realloc (p->buf, sz);
2049 if (b == NULL)
2050 return -1;
2051 p->buf = b;
2052 p->bufsz = sz;
2053 return 0;
2054 }
2055 }
2056
2057 /*------------------------------------------------------------------*/
2058
2059 int
os_send(int soc,void * buf,int len,int opt)2060 os_send (int soc, void *buf, int len, int opt)
2061 {
2062 char *buf0 = (char *) buf;
2063 int e, n;
2064 for (n = 0; n < len;)
2065 {
2066 errno = 0;
2067 e = send (soc, buf0 + n, len - n, opt);
2068 if (e < 0 && errno == EINTR)
2069 continue;
2070 else if (e <= 0)
2071 return -1;
2072 else
2073 n += e;
2074 }
2075 return n;
2076 }
2077
2078 int
os_recv(int soc,void * buf,int len,int opt)2079 os_recv (int soc, void *buf, int len, int opt)
2080 {
2081 char *buf0 = (char *) buf;
2082 int e, n;
2083 for (n = 0; n < len;)
2084 {
2085 errno = 0;
2086 e = recv (soc, buf0 + n, len - n, opt);
2087 if (e < 0 && errno == EINTR)
2088 continue;
2089 else if (e <= 0)
2090 return -1;
2091 else
2092 n += e;
2093 }
2094 return n;
2095 }
2096
2097 /* This is a helper function for nasl_get_sock_info. It is used to
2098 retrieve information about SOCK. */
2099 int
get_sock_infos(int sock,int * r_transport,void ** r_tls_session)2100 get_sock_infos (int sock, int *r_transport, void **r_tls_session)
2101 {
2102 openvas_connection *fp;
2103
2104 if (!OPENVAS_STREAM (sock))
2105 return ENOTSOCK;
2106 fp = &(connections[sock - OPENVAS_FD_OFF]);
2107
2108 *r_transport = fp->transport;
2109 *r_tls_session = fp->tls_session;
2110 return 0;
2111 }
2112
2113 /*
2114 * 0 is considered as the biggest number, since it
2115 * ends our string
2116 */
2117 static int
qsort_compar(const void * a,const void * b)2118 qsort_compar (const void *a, const void *b)
2119 {
2120 u_short *aa = (u_short *) a;
2121 u_short *bb = (u_short *) b;
2122 if (*aa == 0)
2123 return (1);
2124 else if (*bb == 0)
2125 return (-1);
2126 else
2127 return (*aa - *bb);
2128 }
2129
2130 /**
2131 * @brief Converts a string like "-100,200-1024,3000-4000,60000-" into an array
2132 * @brief of port numbers
2133 *
2134 * This function is (c) Fyodor <fyodor@dhp.com> and was taken from
2135 * his excellent and outstanding scanner Nmap
2136 * See http://www.insecure.org/nmap/ for details about
2137 * Nmap
2138 */
2139 unsigned short *
getpts(char * origexpr,int * len)2140 getpts (char *origexpr, int *len)
2141 {
2142 int exlen;
2143 char *p, *q;
2144 unsigned short *tmp, *ports;
2145 int i = 0, j = 0, start, end;
2146 char *expr;
2147 char *mem;
2148 char *s_start, *s_end;
2149 static unsigned short *last_ret = NULL;
2150 static char *last_expr = NULL;
2151 static int last_num;
2152
2153 expr = g_strdup (origexpr);
2154 exlen = strlen (origexpr);
2155 mem = expr;
2156
2157 if (last_expr != NULL)
2158 {
2159 if (strcmp (last_expr, expr) == 0)
2160 {
2161 if (len != NULL)
2162 *len = last_num;
2163 g_free (mem);
2164 return last_ret;
2165 }
2166 else
2167 {
2168 g_free (last_expr);
2169 last_expr = NULL;
2170 g_free (&last_ret);
2171 last_ret = NULL;
2172 }
2173 }
2174
2175 ports = g_malloc0 (65536 * sizeof (short));
2176 for (; j < exlen; j++)
2177 if (expr[j] != ' ')
2178 expr[i++] = expr[j];
2179 expr[i] = '\0';
2180
2181 if ((s_start = strstr (expr, "T:")) != NULL)
2182 expr = &(s_start[2]);
2183
2184 if ((s_end = strstr (expr, "U:")) != NULL)
2185 {
2186 if (s_end[-1] == ',')
2187 s_end--;
2188 s_end[0] = '\0';
2189 }
2190
2191 i = 0;
2192 while ((p = strchr (expr, ',')))
2193 {
2194 *p = '\0';
2195 if (*expr == '-')
2196 {
2197 start = 1;
2198 end = atoi (expr + 1);
2199 }
2200 else
2201 {
2202 start = end = atoi (expr);
2203 if ((q = strchr (expr, '-')) && *(q + 1))
2204 end = atoi (q + 1);
2205 else if (q && !*(q + 1))
2206 end = 65535;
2207 }
2208 if (start < 1)
2209 start = 1;
2210 if (start > end)
2211 {
2212 g_free (mem);
2213 g_free (ports);
2214 return NULL;
2215 }
2216 for (j = start; j <= end; j++)
2217 ports[i++] = j;
2218 expr = p + 1;
2219 }
2220 if (*expr == '-')
2221 {
2222 start = 1;
2223 end = atoi (expr + 1);
2224 }
2225 else
2226 {
2227 start = end = atoi (expr);
2228 if ((q = strchr (expr, '-')) && *(q + 1))
2229 end = atoi (q + 1);
2230 else if (q && !*(q + 1))
2231 end = 65535;
2232 }
2233 if (start < 1)
2234 start = 1;
2235 if (start > end)
2236 {
2237 g_free (mem);
2238 g_free (ports);
2239 return NULL;
2240 }
2241 for (j = start; j <= end; j++)
2242 ports[i++] = j;
2243 ports[i++] = 0;
2244
2245 qsort (ports, i, sizeof (u_short), qsort_compar);
2246 tmp = g_realloc (ports, i * sizeof (short));
2247 if (len != NULL)
2248 *len = i - 1;
2249 g_free (mem);
2250
2251 last_ret = tmp;
2252 last_expr = g_strdup (origexpr);
2253 last_num = i - 1;
2254 return tmp;
2255 }
2256