OpenVAS Scanner  7.0.1~git
nasl.c
Go to the documentation of this file.
1 /* Based on work Copyright (C) 2002 - 2005 Tenable Network Security
2  *
3  * SPDX-License-Identifier: GPL-2.0-only
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
24 #include "nasl.h"
25 
26 #include "../misc/network.h"
27 #include "../misc/nvt_categories.h"
28 #include "../misc/vendorversion.h"
29 #include "exec.h"
30 #include "nasl_lex_ctxt.h"
31 
32 #include <errno.h> /* for errno */
33 #include <gcrypt.h> /* for gcry_control */
34 #include <glib.h>
35 #include <gnutls/gnutls.h> /* for gnutls_check_version */
36 #include <gpgme.h> /* for gpgme_check_version */
37 #include <gvm/base/hosts.h> /* for gvm_hosts_* and gvm_host_* */
38 #include <gvm/base/networking.h> /* for gvm_source_iface_init */
39 #include <gvm/base/nvti.h>
40 #include <gvm/base/prefs.h> /* for prefs_get */
41 #include <gvm/util/kb.h> /* for kb_new */
42 #include <libssh/libssh.h> /* for ssh_version */
43 #include <signal.h> /* for SIGINT */
44 #include <stdlib.h> /* for exit */
45 #include <string.h> /* for strlen */
46 #include <sys/wait.h>
47 #include <unistd.h> /* for geteuid */
48 
49 #ifndef MAP_FAILED
50 #define MAP_FAILED ((void *) -1)
51 #endif
52 
53 #undef G_LOG_DOMAIN
54 
57 #define G_LOG_DOMAIN "lib nasl"
58 
59 extern char *
60 nasl_version (void);
61 
62 void
64 {
65  exit (0);
66 }
67 
68 static void
69 my_gnutls_log_func (int level, const char *text)
70 {
71  fprintf (stderr, "[%d] (%d) %s", getpid (), level, text);
72  if (*text && text[strlen (text) - 1] != '\n')
73  putc ('\n', stderr);
74 }
75 
76 struct script_infos *
77 init (struct in6_addr *ip, GSList *vhosts, kb_t kb)
78 {
79  struct script_infos *infos = g_malloc0 (sizeof (struct script_infos));
80 
81  infos->standalone = 1;
82  infos->key = kb;
83  infos->ip = ip;
84  infos->vhosts = vhosts;
85  if (prefs_get_bool ("test_empty_vhost"))
86  {
87  gvm_vhost_t *vhost =
88  gvm_vhost_new (addr6_as_str (ip), g_strdup ("IP-address"));
89  infos->vhosts = g_slist_prepend (infos->vhosts, vhost);
90  }
91  infos->globals = g_malloc0 (sizeof (struct scan_globals));
92 
93  return infos;
94 }
95 
96 extern FILE *nasl_trace_fp;
97 
98 static nvti_t *
100 {
101  nvti_t *nvti;
102  int mode = NASL_EXEC_DESCR | NASL_ALWAYS_SIGNED;
103 
104  nvti = nvti_new ();
105  infos->nvti = nvti;
106  if (exec_nasl_script (infos, mode) < 0)
107  {
108  printf ("%s could not be loaded\n", infos->name);
109  return NULL;
110  }
111  infos->nvti = NULL;
112  infos->oid = g_strdup (nvti_oid (nvti));
113 
114  return nvti;
115 }
116 
124 static int
125 nvti_category_is_safe (int category)
126 {
127  if (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST
128  || category == ACT_FLOOD || category == ACT_DENIAL)
129  return 0;
130  return 1;
131 }
132 
136 static void
138 {
139  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
140  return;
141  gcry_check_version (NULL);
142  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
143  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
144  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
145  gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
146 }
147 
153 int
154 main (int argc, char **argv)
155 {
156  struct script_infos *script_infos;
157  gvm_hosts_t *hosts;
158  gvm_host_t *host;
159  static gchar *target = NULL;
160  gchar *default_target = "127.0.0.1";
161  int mode = 0, err = 0;
162  extern int global_nasl_debug;
163  GSList *unresolved;
164 
165  static gboolean display_version = FALSE;
166  static gboolean nasl_debug = FALSE;
167  static gboolean description_only = FALSE;
168  static gboolean both_modes = FALSE;
169  static gboolean parse_only = FALSE;
170  static gboolean do_lint = FALSE;
171  static gchar *trace_file = NULL;
172  static gchar *config_file = NULL;
173  static gchar *source_iface = NULL;
174  static gboolean with_safe_checks = FALSE;
175  static gboolean signing_mode = FALSE;
176  static gchar *include_dir = NULL;
177  static gchar **nasl_filenames = NULL;
178  static gchar **kb_values = NULL;
179  static int debug_tls = 0;
180  GError *error = NULL;
181  GOptionContext *option_context;
182  static GOptionEntry entries[] = {
183  {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
184  "Display version information", NULL},
185  {"debug", 'd', 0, G_OPTION_ARG_NONE, &nasl_debug,
186  "Output debug information to stderr.", NULL},
187  {"description", 'D', 0, G_OPTION_ARG_NONE, &description_only,
188  "Only run the 'description' part of the script", NULL},
189  {"both", 'B', 0, G_OPTION_ARG_NONE, &both_modes,
190  "Run in description mode before running the script.", NULL},
191  {"parse", 'p', 0, G_OPTION_ARG_NONE, &parse_only,
192  "Only parse the script, don't execute it", NULL},
193  {"lint", 'L', 0, G_OPTION_ARG_NONE, &do_lint,
194  "'lint' the script (extended checks)", NULL},
195  {"target", 't', 0, G_OPTION_ARG_STRING, &target,
196  "Execute the scripts against <target>", "<target>"},
197  {"trace", 'T', 0, G_OPTION_ARG_FILENAME, &trace_file,
198  "Log actions to <file> (or '-' for stderr)", "<file>"},
199  {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
200  "Configuration file", "<filename>"},
201  {"source-iface", 'e', 0, G_OPTION_ARG_STRING, &source_iface,
202  "Source network interface for established connections.", "<iface_name>"},
203  {"safe", 's', 0, G_OPTION_ARG_NONE, &with_safe_checks,
204  "Specifies that the script should be run with 'safe checks' enabled",
205  NULL},
206  {"disable-signing", 'X', 0, G_OPTION_ARG_NONE, &signing_mode,
207  "Run the script with disabled signature verification", NULL},
208  {"include-dir", 'i', 0, G_OPTION_ARG_STRING, &include_dir,
209  "Search for includes in <dir>", "<dir>"},
210  {"debug-tls", 0, 0, G_OPTION_ARG_INT, &debug_tls,
211  "Enable TLS debugging at <level>", "<level>"},
212  {"kb", 'k', 0, G_OPTION_ARG_STRING_ARRAY, &kb_values,
213  "Set KB key to value. Can be used multiple times", "<key=value>"},
214  {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &nasl_filenames,
215  "Absolute path to one or more nasl scripts", "NASL_FILE..."},
216  {NULL, 0, 0, 0, NULL, NULL, NULL}};
217 
218  option_context =
219  g_option_context_new ("- standalone NASL interpreter for OpenVAS");
220  g_option_context_add_main_entries (option_context, entries, NULL);
221  if (!g_option_context_parse (option_context, &argc, &argv, &error))
222  {
223  g_print ("%s\n\n", error->message);
224  exit (0);
225  }
226  g_option_context_free (option_context);
227  /*--------------------------------------------
228  Command-line options
229  ---------------------------------------------*/
230 
231  if (display_version)
232  {
233  printf ("openvas-nasl %s\n", nasl_version ());
234  if (debug_tls)
235  {
236  printf ("gnutls %s\n", gnutls_check_version (NULL));
237  printf ("libssh %s\n", ssh_version (0));
238  printf ("gpgme %s\n", gpgme_check_version (NULL));
239  }
240  else
241  putchar ('\n');
242  printf ("Copyright (C) 2002 - 2004 Tenable Network Security\n");
243  printf ("Copyright (C) 2013 Greenbone Networks GmbH\n\n");
244  exit (0);
245  }
246  if (nasl_debug)
247  global_nasl_debug = 1;
248  mode |= NASL_COMMAND_LINE;
249  if (signing_mode)
250  mode |= NASL_ALWAYS_SIGNED;
251  if (description_only)
252  mode |= NASL_EXEC_DESCR;
253  if (do_lint)
254  mode |= NASL_LINT;
255  if (parse_only)
256  mode |= NASL_EXEC_PARSE_ONLY;
257  if (trace_file)
258  {
259  if (!strcmp (trace_file, "-"))
260  nasl_trace_fp = stderr;
261  else
262  {
263  FILE *fp = fopen (trace_file, "w");
264  if (fp == NULL)
265  {
266  perror (optarg);
267  exit (2);
268  }
269  setvbuf (fp, NULL, _IOLBF, BUFSIZ);
270  nasl_trace_fp = fp;
271  }
272  }
273  if (with_safe_checks)
274  prefs_set ("safe_checks", "yes");
275 
276  gcrypt_init ();
277  openvas_SSL_init ();
278  if (!nasl_filenames)
279  {
280  fprintf (stderr, "Error. No input file(s) specified !\n");
281  exit (1);
282  }
283 
284  if (!(mode & (NASL_EXEC_PARSE_ONLY | NASL_LINT)) && geteuid ())
285  {
286  fprintf (stderr, "** WARNING : packet forgery will not work\n");
287  fprintf (stderr, "** as NASL is not running as root\n");
288  }
289  signal (SIGINT, sighandler);
290  signal (SIGTERM, sighandler);
291  signal (SIGPIPE, SIG_IGN);
292 
293  if (source_iface && gvm_source_iface_init (source_iface))
294  {
295  fprintf (stderr, "Erroneous network source interface: %s\n",
296  source_iface);
297  exit (1);
298  }
299  if (debug_tls)
300  {
301  gnutls_global_set_log_function (my_gnutls_log_func);
302  gnutls_global_set_log_level (debug_tls);
303  }
304 
305  if (!target)
306  target = g_strdup (default_target);
307 
308  hosts = gvm_hosts_new (target);
309  if (!hosts)
310  {
311  fprintf (stderr, "Erroneous target %s\n", target);
312  exit (1);
313  }
314  unresolved = gvm_hosts_resolve (hosts);
315  while (unresolved)
316  {
317  g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
318  unresolved = unresolved->next;
319  }
320  g_slist_free_full (unresolved, g_free);
321  g_free (target);
322 
323  // for absolute and relative paths
324  add_nasl_inc_dir ("");
325  if (include_dir != NULL)
326  {
327  add_nasl_inc_dir (include_dir);
328  }
329 
330  prefs_config (config_file ?: OPENVAS_CONF);
331 
332  if (prefs_get ("vendor_version") != NULL)
333  vendor_version_set (prefs_get ("vendor_version"));
334 
335  while ((host = gvm_hosts_next (hosts)))
336  {
337  struct in6_addr ip6;
338  kb_t kb;
339  int rc, i = 0;
340 
341  if (prefs_get_bool ("expand_vhosts"))
342  gvm_host_add_reverse_lookup (host);
343  gvm_vhosts_exclude (host, prefs_get ("exclude_hosts"));
344  gvm_host_get_addr6 (host, &ip6);
345  rc = kb_new (&kb, prefs_get ("db_address") ?: KB_PATH_DEFAULT);
346  if (rc)
347  exit (1);
348 
349  script_infos = init (&ip6, host->vhosts, kb);
350  while (nasl_filenames[i])
351  {
352  pid_t pid;
353 
354  script_infos->name = nasl_filenames[i];
355  if (both_modes || with_safe_checks)
356  {
357  nvti_t *nvti = parse_script_infos (script_infos);
358  if (!nvti)
359  {
360  err++;
361  i++;
362  continue;
363  }
364  else if (with_safe_checks
365  && !nvti_category_is_safe (nvti_category (nvti)))
366  {
367  printf ("%s isn't safe\n", nasl_filenames[i]);
368  nvti_free (nvti);
369  err++;
370  i++;
371  continue;
372  }
373  nvti_free (nvti);
374  }
375  if (kb_values)
376  {
377  while (*kb_values)
378  {
379  gchar **splits = g_strsplit (*kb_values, "=", -1);
380  if (splits[2] || !splits[1])
381  {
382  fprintf (stderr, "Erroneous --kb entry %s\n", *kb_values);
383  exit (1);
384  }
385  kb_item_add_str_unique (kb, splits[0], splits[1], 0);
386  kb_values++;
387  g_strfreev (splits);
388  }
389  }
390 
391  if ((pid = fork ()) == 0)
392  {
393  if (exec_nasl_script (script_infos, mode) < 0)
394  exit (1);
395  else
396  exit (0);
397  }
398  else if (pid < 0)
399  {
400  fprintf (stderr, "fork(): %s\n", strerror (errno));
401  exit (1);
402  }
403  else
404  {
405  int status;
406  waitpid (pid, &status, 0);
407  if (status)
408  err++;
409  }
410  i++;
411  }
412  g_free (script_infos->globals);
413  g_free (script_infos);
414  kb_delete (kb);
415  }
416 
417  if (nasl_trace_fp != NULL)
418  fflush (nasl_trace_fp);
419 
420  gvm_hosts_free (hosts);
421  return err;
422 }
init
struct script_infos * init(struct in6_addr *ip, GSList *vhosts, kb_t kb)
Definition: nasl.c:77
script_infos::standalone
int standalone
Definition: scanneraux.h:53
nvti_category_is_safe
static int nvti_category_is_safe(int category)
Checks that an NVT category is safe.
Definition: nasl.c:125
script_infos::ip
struct in6_addr * ip
Definition: scanneraux.h:51
script_infos
Definition: scanneraux.h:43
ACT_FLOOD
@ ACT_FLOOD
Definition: nvt_categories.h:47
script_infos::key
kb_t key
Definition: scanneraux.h:46
add_nasl_inc_dir
int add_nasl_inc_dir(const char *)
Adds the given string as directory for searching for includes.
Definition: nasl_grammar.tab.c:2738
script_infos::name
char * name
Definition: scanneraux.h:49
script_infos::nvti
nvti_t * nvti
Definition: scanneraux.h:47
pid
static pid_t pid
Definition: nasl_builtin_nmap.c:499
exec.h
sighandler
void sighandler()
Definition: nasl.c:63
ACT_DENIAL
@ ACT_DENIAL
Definition: nvt_categories.h:45
NASL_EXEC_DESCR
#define NASL_EXEC_DESCR
Definition: nasl.h:57
openvas_SSL_init
int openvas_SSL_init()
Initializes SSL support.
Definition: network.c:351
script_infos::globals
struct scan_globals * globals
Definition: scanneraux.h:45
nasl_trace_fp
FILE * nasl_trace_fp
Definition: exec.c:368
nasl_lex_ctxt.h
nasl.h
script_infos::oid
char * oid
Definition: scanneraux.h:48
scan_globals
Definition: scanneraux.h:32
NASL_COMMAND_LINE
#define NASL_COMMAND_LINE
Definition: nasl.h:60
main
int main(int argc, char **argv)
Main of the standalone nasl interpreter.
Definition: nasl.c:154
host
Host information, implemented as doubly linked list.
Definition: hosts.c:47
parse_script_infos
static nvti_t * parse_script_infos(struct script_infos *infos)
Definition: nasl.c:99
script_infos::vhosts
GSList * vhosts
Definition: scanneraux.h:52
global_nasl_debug
int global_nasl_debug
Definition: plugutils.c:48
ACT_KILL_HOST
@ ACT_KILL_HOST
Definition: nvt_categories.h:46
NASL_ALWAYS_SIGNED
#define NASL_ALWAYS_SIGNED
Definition: nasl.h:59
exec_nasl_script
int exec_nasl_script(struct script_infos *script_infos, int mode)
Execute a NASL script.
Definition: exec.c:1624
gcrypt_init
static void gcrypt_init()
Initialize Gcrypt.
Definition: nasl.c:137
my_gnutls_log_func
static void my_gnutls_log_func(int level, const char *text)
Definition: nasl.c:69
vendor_version_set
void vendor_version_set(const gchar *version)
Set vendor version.
Definition: vendorversion.c:40
NASL_EXEC_PARSE_ONLY
#define NASL_EXEC_PARSE_ONLY
Definition: nasl.h:58
hosts
static struct host * hosts
Definition: hosts.c:59
ACT_DESTRUCTIVE_ATTACK
@ ACT_DESTRUCTIVE_ATTACK
Definition: nvt_categories.h:44
nasl_version
char * nasl_version(void)
Definition: nasl_init.c:502
NASL_LINT
#define NASL_LINT
Definition: nasl.h:61