OpenVAS Libraries  9.0.3
nasl_builtin_nmap.c
Go to the documentation of this file.
1 /* OpenVAS
2 * $Id$
3 * Description: Advanced wrapper from nmap
4 *
5 * Authors:
6 * Henri Doreau <henri.doreau@greenbone.net>
7 *
8 * Copyright:
9 * Copyright (C) 2011 Greenbone Networks GmbH
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25 
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include <signal.h>
59 #include <sys/types.h>
60 #include <sys/wait.h>
61 #include <glib.h>
62 
63 #include "../misc/arglists.h"
64 #include "../misc/plugutils.h"
65 #include "../misc/popen.h"
66 #include "../misc/openvas_logging.h"
67 #include "../misc/prefs.h" /* for prefs_get */
68 #include "../base/kb.h"
69 
70 #include "nasl_lex_ctxt.h"
71 
72 
73 #ifndef NDEBUG
74  #define dbg(...) do { log_legacy_write (__VA_ARGS__); } while (0)
75  #define err(x) do { perror (x); } while (0)
76 #else
77  #define dbg(...)
78  #define err(x)
79 #endif
80 
81 
85 #define CHUNK_LEN 512
86 
90 #define MAX_TRACE_HOPS 64
91 
95 #define NMAP_CMD "nmap"
96 
97 
98 /* -- script options -- */
99 
103 #define PREF_TREAT_ALL_HOST_ONLINE "Treat all hosts as online"
104 
108 #define PREF_TRACEROUTE "Trace hop path to each host"
109 
114 #define PREF_NO_DNS "Disable DNS resolution"
115 
119 #define PREF_TCP_SCANNING_TECHNIQUE "TCP scanning technique"
120 
125 #define PREF_SERVICE_SCAN "Service scan"
126 
130 #define PREF_RPC_PORT_SCAN "RPC port scan"
131 
135 #define PREF_IDENTIFY_REMOTE_OS "Identify the remote OS"
136 
141 #define PREF_AGGRESSIVE_OS_DETECT "Aggressive OS detection"
142 
147 #define PREF_FRAGMENT_IP "Fragment IP packets (bypasses firewalls)"
148 
152 #define PREF_SOURCE_PORT "Source port"
153 
157 #define PREF_TIMING_POLICY "Timing policy"
158 
163 #define PREF_HOST_TIMEOUT "Host Timeout (ms)"
164 
169 #define PREF_MIN_RTT_TIMEOUT "Min RTT Timeout (ms)"
170 
175 #define PREF_MAX_RTT_TIMEOUT "Max RTT Timeout (ms)"
176 
181 #define PREF_INITIAL_RTT_TIMEOUT "Initial RTT timeout (ms)"
182 
187 #define PREF_MIN_PARALLELISM "Ports scanned in parallel (min)"
188 
193 #define PREF_MAX_PARALLELISM "Ports scanned in parallel (max)"
194 
199 #define PREF_MIN_HOSTGROUP "Hosts scanned in parallel (min)"
200 
205 #define PREF_MAX_HOSTGROUP "Hosts scanned in parallel (max)"
206 
210 #define PREF_INTERPROBE_DELAY "Minimum wait between probes (ms)"
211 
216 #define PREF_EXCLUDE_HOSTS "Exclude hosts"
217 
221 #define PREF_IMPORT_XML_FILE "File containing XML results"
222 
223 
227 #define OPT_SET "yes"
228 
232 #define OPT_UNSET "no"
233 
234 
239 {
240  gchar *name;
241  gchar *output;
242 };
243 
248 {
249  gchar *addr;
250  gchar *host;
251  gchar *rtt;
252 };
253 
257 struct nmap_port
258 {
259  gchar *proto;
260  gchar *portno;
261  gchar *state;
262  gchar *service;
263  gchar *version;
264  GSList *port_scripts;
265  GSList *version_cpes;
266 };
267 
275 struct nmap_host
276 {
277  gchar *addr;
278  gchar *state;
279  gchar *best_os;
280  gchar *tcpseq_index;
282  gchar *ipidseq;
284  int distance;
287  GSList *host_scripts;
288  GSList *ports;
289  GSList *os_cpes;
290 };
291 
296 {
297  GHashTable *opentag;
298  GHashTable *closetag;
300  gboolean in_host;
301  gboolean in_ports;
302  gboolean in_port;
303  gboolean in_hostscript;
304  gboolean enable_read;
305  gchar *rbuff;
306 };
307 
311 typedef struct
312 {
313  /* Command line generation */
314  gchar **args;
315  int arg_idx;
316 
317  /* External XML file parsing */
318  const gchar *filename;
319 
320  /* General execution environment */
321  struct arglist *env;
322 
323  /* OID of this NVT */
324  const char *oid;
325 
326  /* XML parsing states */
327  struct nmap_parser parser;
328 
329  struct nmap_host tmphost;
330  struct nmap_port tmpport;
331 } nmap_t;
332 
336 typedef struct
337 {
338  gchar *optname;
339  gchar *flag;
340  gboolean argument_required;
341 } nmap_opt_t;
342 
343 
344 /* --------------------- INTERNAL FUNCTIONS PROTOTYPES ---------------------- */
345 
346 /*
347  * Nmap handler ctor/dtor.
348  */
349 static nmap_t *nmap_create (lex_ctxt * lexic);
350 static void nmap_destroy (nmap_t * nmap);
351 
352 
353 /*
354  * Command line generation from supplied options and parameters.
355  */
356 static int build_cmd_line (nmap_t * nmap);
357 static int add_arg (nmap_t * nmap, const gchar * name, const gchar * value);
358 static int add_nse_arguments (nmap_t * nmap);
359 static gchar *get_script_list (nmap_t * nmap);
360 static gchar *get_script_args (nmap_t * nmap);
361 static int add_scantype_arguments (nmap_t * nmap);
362 static int add_timing_arguments (nmap_t * nmap);
363 static int add_portrange (nmap_t * nmap);
364 static void setup_xml_parser (nmap_t * nmap);
365 static void set_opentag_callbacks (GHashTable * open);
366 static void set_closetag_callbacks (GHashTable * close);
367 static int add_target (nmap_t * nmap);
368 static void dbg_display_cmdline (nmap_t * nmap);
369 
370 
371 /*
372  * Execution control and high level results parsing.
373  */
374 static void sig_h ();
375 static void sig_c ();
376 static int nmap_run_and_parse (nmap_t * nmap);
377 static void current_host_reset (nmap_t * nmap);
378 static void port_destroy (gpointer data, gpointer udata);
379 static void nse_script_destroy (gpointer data, gpointer udata);
380 static void simple_item_destroy (gpointer data, gpointer udata);
381 static void tmphost_add_port (nmap_t * nmap);
382 static void tmphost_add_nse_hostscript (nmap_t * nmap, gchar * name,
383  gchar * output);
384 static void tmphost_add_nse_portscript (nmap_t * nmap, gchar * name,
385  gchar * output);
386 
387 
388 /*
389  * Top level callbacks to handle opening/closing XML elements.
390  */
391 static void
392 xml_start_element (GMarkupParseContext * context, const gchar * element_name,
393  const gchar ** attribute_names,
394  const gchar ** attribute_values, gpointer user_data,
395  GError ** error);
396 static void
397 xml_end_element (GMarkupParseContext * context, const gchar * element_name,
398  gpointer user_data, GError ** error);
399 
400 static void
401 xml_read_text (GMarkupParseContext * context, const gchar * text,
402  gsize text_len, gpointer user_data, GError ** error);
403 
404 
405 /*
406  * Callbacks for opening recognized elements.
407  */
408 static void xmltag_open_host (nmap_t * nmap, const gchar ** attrnames,
409  const gchar ** attrval);
410 static void xmltag_open_status (nmap_t * nmap, const gchar ** attrnames,
411  const gchar ** attrval);
412 static void xmltag_open_address (nmap_t * nmap, const gchar ** attrnames,
413  const gchar ** attrval);
414 static void xmltag_open_ports (nmap_t * nmap, const gchar ** attrnames,
415  const gchar ** attrval);
416 static void xmltag_open_port (nmap_t * nmap, const gchar ** attrnames,
417  const gchar ** attrval);
418 static void xmltag_open_state (nmap_t * nmap, const gchar ** attrnames,
419  const gchar ** attrval);
420 static void xmltag_open_service (nmap_t * nmap, const gchar ** attrnames,
421  const gchar ** attrval);
422 static void xmltag_open_cpe (nmap_t * nmap, const gchar ** attrnames,
423  const gchar ** attrval);
424 static void xmltag_open_hostscript (nmap_t * nmap, const gchar ** attrnames,
425  const gchar ** attrval);
426 static void xmltag_open_osmatch (nmap_t * nmap, const gchar ** attrnames,
427  const gchar ** attrval);
428 static void xmltag_open_script (nmap_t * nmap, const gchar ** attrnames,
429  const gchar ** attrval);
430 static void xmltag_open_tcpsequence (nmap_t * nmap, const gchar ** attrnames,
431  const gchar ** attrval);
432 static void xmltag_open_ipidsequence (nmap_t * nmap, const gchar ** attrnames,
433  const gchar ** attrval);
434 static void xmltag_open_hop (nmap_t * nmap, const gchar ** attrnames,
435  const gchar ** attrval);
436 static void xmltag_open_distance (nmap_t * nmap, const gchar ** attrnames,
437  const gchar ** attrval);
438 
439 
440 /*
441  * Callbacks for closing recognized elements.
442  */
443 static void xmltag_close_host (nmap_t * nmap);
444 static void xmltag_close_ports (nmap_t * nmap);
445 static void xmltag_close_port (nmap_t * nmap);
446 static void xmltag_close_cpe (nmap_t * nmap);
447 static void xmltag_close_hostscript (nmap_t * nmap);
448 
449 
450 /*
451  * Helper function to get the strdup'ed value of a given attribute.
452  */
453 static gchar *get_attr_value (const gchar * name,
454  const gchar ** attribute_names,
455  const gchar ** attribute_values);
456 
457 
458 /*
459  * Store host results in the KB.
460  */
461 static void current_host_saveall (nmap_t * nmap);
462 static void save_host_state (nmap_t * nmap);
463 static void save_open_ports (nmap_t * nmap);
464 static void register_service (nmap_t * nmap, struct nmap_port * p);
465 static void save_detected_os (nmap_t * nmap);
466 static void save_tcpseq_details (nmap_t * nmap);
467 static void save_ipidseq_details (nmap_t * nmap);
468 static void save_traceroute_details (nmap_t * nmap);
469 static void save_portscripts (nmap_t * nmap);
470 static void save_hostscripts (nmap_t * nmap);
471 
472 /* -------------------------------------------------------------------------- */
473 
474 /* PID of the nmap subprocess. Declared global for access from within sighandlers. */
475 static pid_t pid;
476 
484 tree_cell *
486 {
487  nmap_t *nmap;
488 
489  dbg ("Starting Nmap builtin wrapper\n");
490 
491  /* Initialize our nmap handler */
492  if ((nmap = nmap_create (lexic)) == NULL)
493  {
494  dbg ("Unable to initialize Nmap\n");
495  return NULL;
496  }
497 
498  /* Execute nmap and store results */
499  nmap_run_and_parse (nmap);
500 
501  /* release resources */
502  nmap_destroy (nmap);
503 
504  return FAKE_CELL;
505 }
506 
515 nmap_t *
516 nmap_create (lex_ctxt * lexic)
517 {
518  gchar *pref;
519  nmap_t *nmap;
520 
521  nmap = (nmap_t *) g_malloc0 (sizeof (nmap_t));
522 
523  nmap->env = lexic->script_infos;
524  nmap->oid = lexic->oid;
525 
526  /* import results from external file? */
528  if (!pref || !strlen (pref))
529  {
530  /* no: build command line to execute */
531  if (build_cmd_line (nmap) < 0)
532  {
533  nmap_destroy (nmap);
534  return NULL;
535  }
536 
537  /* Display command line to use */
538  dbg ("Nmap initialized: ");
539  dbg_display_cmdline (nmap);
540  }
541  else
542  {
543  /* yes: store filename */
544  nmap->filename = get_plugin_preference_fname (nmap->env, pref);
545  dbg ("Reading nmap results from file: %s\n", nmap->filename);
546  }
547 
548  setup_xml_parser (nmap);
549  return nmap;
550 }
551 
557 void
558 nmap_destroy (nmap_t * nmap)
559 {
560  if (!nmap)
561  return;
562 
563  if (nmap->args)
564  {
565  int i;
566 
567  for (i = 0; i < nmap->arg_idx; i++)
568  g_free (nmap->args[i]);
569 
570  g_free (nmap->args);
571  }
572 
573  if (nmap->parser.opentag)
574  g_hash_table_destroy (nmap->parser.opentag);
575 
576  if (nmap->parser.closetag)
577  g_hash_table_destroy (nmap->parser.closetag);
578 
579  g_free (nmap);
580 }
581 
589 int
590 build_cmd_line (nmap_t * nmap)
591 {
592  int i;
593  /* this list handles basic options (simple flag or name/value) */
594  nmap_opt_t options[] = {
595  /* --- Host discovery --- */
596  {PREF_TREAT_ALL_HOST_ONLINE, "-Pn", FALSE},
597  {PREF_TRACEROUTE, "--traceroute", FALSE},
598  {PREF_NO_DNS, "-n", FALSE},
599 
600  /* --- Scan techniques --- */
601  {PREF_SERVICE_SCAN, "-sV", FALSE},
602  {PREF_RPC_PORT_SCAN, "-sR", FALSE},
603 
604  /* --- OS Detection --- */
605  {PREF_IDENTIFY_REMOTE_OS, "-O", FALSE},
606  {PREF_AGGRESSIVE_OS_DETECT, "--osscan-guess", FALSE},
607 
608  /* --- Firewall/IDS evasion --- */
609  {PREF_FRAGMENT_IP, "-f", FALSE},
610  {PREF_SOURCE_PORT, "-g", TRUE},
611 
612  /* --- Timing and performances --- */
613  {PREF_HOST_TIMEOUT, "--host-timeout", TRUE},
614  {PREF_MIN_RTT_TIMEOUT, "--min-rtt-timeout", TRUE},
615  {PREF_MAX_RTT_TIMEOUT, "--max-rtt-timeout", TRUE},
616  {PREF_INITIAL_RTT_TIMEOUT, "--initial-rtt-timeout", TRUE},
617  {PREF_MIN_PARALLELISM, "--min-parallelism", TRUE},
618  {PREF_MAX_PARALLELISM, "--max-parallelism", TRUE},
619  {PREF_MIN_HOSTGROUP, "--min-hostgroup", TRUE},
620  {PREF_MAX_HOSTGROUP, "--max-hostgroup", TRUE},
621  {PREF_INTERPROBE_DELAY, "--delay", TRUE},
622 
623  /* --- Targets specification --- */
624  {PREF_EXCLUDE_HOSTS, "--exclude", TRUE},
625 
626  {NULL, NULL, FALSE}
627  };
628 
629  /* Nmap invocation */
630  add_arg (nmap, NMAP_CMD, NULL);
631 
632  /* Enable XML output on stdout */
633  add_arg (nmap, "-oX", "-");
634 
635  for (i = 0; options[i].optname; i++)
636  {
637  gchar *optval;
638 
639  optval = get_plugin_preference (nmap->oid, options[i].optname);
640  if (!optval)
641  continue;
642 
643  if (options[i].argument_required)
644  {
645  if (strlen (optval) > 0)
646  if (add_arg (nmap, options[i].flag, optval) < 0)
647  return -1;
648  }
649  else
650  {
651  if (g_strcmp0 (optval, OPT_SET) == 0)
652  if (add_arg (nmap, options[i].flag, NULL) < 0)
653  return -1;
654  }
655  }
656 
657  if (add_portrange (nmap) < 0)
658  return -1;
659 
660  /* Always enable UDP port scan, so that the port list controls this. */
661  if (add_arg (nmap, "-sU", NULL) < 0)
662  return -1;
663 
664  /* Scan technique */
665  if (add_scantype_arguments (nmap) < 0)
666  return -1;
667 
668  /* Timing policy */
669  if (add_timing_arguments (nmap) < 0)
670  return -1;
671 
672  /* Script scan */
673  if (add_nse_arguments (nmap) < 0)
674  return -1;
675 
676  if (add_target (nmap) < 0)
677  return -1;
678 
679  return 1;
680 }
681 
691 int
692 add_arg (nmap_t * nmap, const gchar * name, const gchar * value)
693 {
694  if (!name)
695  return -1;
696 
697  if (!nmap->args)
698  {
699  /* Initial call, instanciate the NULL terminated list of arguments */
700  nmap->args = (gchar **) g_malloc (sizeof (gchar **));
701  nmap->arg_idx = 0;
702  }
703 
704  if (!value)
705  {
706  /* simple flag (no value) */
707  nmap->args = g_realloc (nmap->args,
708  (nmap->arg_idx + 2) * sizeof (gchar *));
709  nmap->args[nmap->arg_idx++] = g_strdup (name);
710  }
711  else
712  {
713  /* name->value argument */
714  nmap->args = g_realloc (nmap->args,
715  (nmap->arg_idx + 3) * sizeof (gchar *));
716  nmap->args[nmap->arg_idx++] = g_strdup (name);
717  nmap->args[nmap->arg_idx++] = g_strdup (value);
718  }
719 
720  /* NULL-terminate the list */
721  nmap->args[nmap->arg_idx] = NULL;
722 
723  return 1;
724 }
725 
734 int
735 add_nse_arguments (nmap_t * nmap)
736 {
737  gchar *pscript, *pargs;
738 
739  pscript = get_script_list (nmap);
740  pargs = get_script_args (nmap);
741  if (strlen (pscript))
742  {
743  /* Add script flags if user requested some NSE */
744  add_arg (nmap, "--script", pscript);
745 
746  if (strlen (pargs))
747  add_arg (nmap, "--script-args", pargs);
748  }
749  g_free (pscript);
750  g_free (pargs);
751 
752  return 1;
753 }
754 
763 gchar *
764 get_script_list (nmap_t * nmap)
765 {
766  kb_t kb = plug_get_kb (nmap->env);
767  struct kb_item *top, *res;
768  gchar **scriptv, *scriptstr;
769  int i = 0;
770 
771  scriptv = NULL;
772 
773  /* Read list of scripts from the KB */
774  top = res = kb_item_get_all (kb, "NmapNSE/scripts");
775  while (res)
776  {
777  scriptv = (gchar **) g_realloc (scriptv, (i + 1) * sizeof (gchar *));
778  scriptv[i++] = g_strdup (res->v_str);
779  res = res->next;
780  }
781 
782  scriptv = (gchar **) g_realloc (scriptv, (i + 1) * sizeof (gchar *));
783  scriptv[i] = NULL;
784 
785  kb_item_free (top);
786 
787  scriptstr = g_strjoinv (",", scriptv);
788 
789  for (i = 0; scriptv[i]; i++)
790  g_free (scriptv[i]);
791 
792  g_free (scriptv);
793 
794  return scriptstr;
795 }
796 
805 gchar *
806 get_script_args (nmap_t * nmap)
807 {
808  kb_t kb = plug_get_kb (nmap->env);
809  struct kb_item *top, *res;
810  gchar **argv, *argstr;
811  int i = 0;
812 
813  argv = NULL;
814 
815  top = res = kb_item_get_all (kb, "NmapNSE/arguments");
816  while (res)
817  {
818  argv = (gchar **) g_realloc (argv, (i + 1) * sizeof (gchar *));
819  argv[i++] = g_strdup (res->v_str);
820  res = res->next;
821  }
822 
823  argv = (gchar **) g_realloc (argv, (i + 1) * sizeof (gchar *));
824  argv[i] = NULL;
825 
826  kb_item_free (top);
827 
828  argstr = g_strjoinv (",", argv);
829 
830  for (i = 0; argv[i]; i++)
831  g_free (argv[i]);
832  g_free (argv);
833 
834  return argstr;
835 }
836 
844 int
845 add_scantype_arguments (nmap_t * nmap)
846 {
847  int i;
848  gchar *scantype;
849  nmap_opt_t flagmap[] = {
850  {"connect()", "-sT", FALSE},
851  {"SYN", "-sS", FALSE},
852  {"ACK", "-sA", FALSE},
853  {"FIN", "-sF", FALSE},
854  {"Window", "-sW", FALSE},
855  {"Maimon", "-sM", FALSE},
856  {"Xmas tree", "-sX", FALSE},
857  {"Null", "-sN", FALSE},
858  {"SCTP Init", "-sY", FALSE},
859  {"SCTP COOKIE_ECHO", "-sZ", FALSE},
860  {NULL, NULL, FALSE}
861  };
862 
864  if (!scantype)
865  return -1;
866 
867  for (i = 0; flagmap[i].optname; i++)
868  if (g_strcmp0 (scantype, flagmap[i].optname) == 0)
869  return add_arg (nmap, flagmap[i].flag, NULL);
870 
871  return -1;
872 }
873 
881 int
882 add_timing_arguments (nmap_t * nmap)
883 {
884  int i;
885  gchar *timing;
886  nmap_opt_t flagmap[] = {
887  {"Paranoid", "-T0", FALSE},
888  {"Sneaky", "-T1", FALSE},
889  {"Polite", "-T2", FALSE},
890  {"Normal", "-T3", FALSE},
891  {"Aggressive", "-T4", FALSE},
892  {"Insane", "-T5", FALSE},
893  {NULL, NULL, FALSE}
894  };
895 
896  timing = get_plugin_preference (nmap->oid, PREF_TIMING_POLICY);
897  if (!timing)
898  return -1;
899 
900  for (i = 0; flagmap[i].optname; i++)
901  if (g_strcmp0 (timing, flagmap[i].optname) == 0)
902  return add_arg (nmap, flagmap[i].flag, NULL);
903 
904  return -1;
905 }
906 
914 int
915 add_portrange (nmap_t * nmap)
916 {
917  const char *portrange = prefs_get ("port_range");
918 
919  if (!portrange)
920  {
921  dbg ("Invalid environment: unavailable \"port_range\"\n");
922  return -1;
923  }
924 
925  return add_arg (nmap, "-p", portrange);
926 }
927 
933 void
934 setup_xml_parser (nmap_t * nmap)
935 {
936  /* reset internal states */
937  nmap->parser.in_host = FALSE;
938  nmap->parser.in_ports = FALSE;
939  nmap->parser.in_port = FALSE;
940  nmap->parser.in_hostscript = FALSE;
941  nmap->parser.enable_read = FALSE;
942 
943  nmap->parser.opentag = g_hash_table_new (g_str_hash, g_str_equal);
944  nmap->parser.closetag = g_hash_table_new (g_str_hash, g_str_equal);
945 
946  set_opentag_callbacks (nmap->parser.opentag);
947  set_closetag_callbacks (nmap->parser.closetag);
948 }
949 
955 void
956 set_opentag_callbacks (GHashTable * open)
957 {
958  const struct
959  {
960  const gchar *tag;
961  void (*func) (nmap_t *, const gchar **, const gchar **);
962  } callbacks[] = {
963  {"hop", xmltag_open_hop},
964  {"osmatch", xmltag_open_osmatch},
965  {"port", xmltag_open_port},
966  {"service", xmltag_open_service},
967  {"cpe", xmltag_open_cpe},
968  {"state", xmltag_open_state},
969  {"status", xmltag_open_status},
970  {"host", xmltag_open_host},
971  {"address", xmltag_open_address},
972  {"script", xmltag_open_script},
973  {"ports", xmltag_open_ports},
974  {"distance", xmltag_open_distance},
975  {"hostscript", xmltag_open_hostscript},
976  {"tcpsequence", xmltag_open_tcpsequence},
977  {"ipidsequence", xmltag_open_ipidsequence},
978  {NULL, NULL}
979  };
980  int i;
981 
982  for (i = 0; callbacks[i].tag; i++)
983  g_hash_table_insert (open, (void *) callbacks[i].tag, callbacks[i].func);
984 }
985 
991 void
992 set_closetag_callbacks (GHashTable * close)
993 {
994  const struct
995  {
996  const gchar *tag;
997  void (*func) (nmap_t *);
998  } callbacks[] = {
999  {"host", xmltag_close_host},
1000  {"ports", xmltag_close_ports},
1001  {"port", xmltag_close_port},
1002  {"cpe", xmltag_close_cpe},
1003  {"hostscript", xmltag_close_hostscript},
1004  {NULL, NULL}
1005  };
1006  int i;
1007 
1008  for (i = 0; callbacks[i].tag; i++)
1009  g_hash_table_insert (close, (void *) callbacks[i].tag, callbacks[i].func);
1010 }
1011 
1019 int
1020 add_target (nmap_t * nmap)
1021 {
1022  struct arglist *globals;
1023  gchar *network;
1024 
1025  globals = arg_get_value (nmap->env, "globals");
1026  if (!globals)
1027  {
1028  dbg ("Invalid environment: unavailable \"globals\"\n");
1029  return -1;
1030  }
1031 
1032  network = arg_get_value (globals, "network_targets");
1033  if (!network)
1034  {
1035  dbg ("Invalid environment: unavailable \"network_targets\"\n");
1036  return -1;
1037  }
1038 
1039  return add_arg (nmap, network, NULL);
1040 }
1041 
1047 void
1048 dbg_display_cmdline (nmap_t * nmap)
1049 {
1050  int i;
1051 
1052  for (i = 0; nmap->args[i]; i++)
1053  dbg ("%s ", nmap->args[i]);
1054 
1055  if (i == 0)
1056  dbg ("<empty>");
1057 
1058  dbg ("\n");
1059 }
1060 
1064 void
1065 sig_h ()
1066 {
1067  if (pid > 0)
1068  kill (pid, SIGKILL);
1069 }
1070 
1074 void
1075 sig_c ()
1076 {
1077  if (pid > 0)
1078  waitpid (pid, NULL, WNOHANG);
1079 }
1080 
1089 int
1090 nmap_run_and_parse (nmap_t * nmap)
1091 {
1092  FILE *fproc;
1093  size_t len;
1094  int ret = 1; /* success */
1095  gchar chunk[CHUNK_LEN];
1096  void (*old_sig_t) () = NULL;
1097  void (*old_sig_i) () = NULL;
1098  void (*old_sig_c) () = NULL;
1099  GMarkupParseContext *ctx;
1100  const GMarkupParser callbacks = {
1101  xml_start_element,
1102  xml_end_element,
1103  xml_read_text,
1104  NULL, /* passthrough */
1105  NULL /* error */
1106  };
1107 
1108 
1109  if (nmap->filename)
1110  {
1111  /* read results from external file */
1112  fproc = fopen (nmap->filename, "r");
1113  }
1114  else
1115  {
1116  /* Update signal handlers. */
1117  old_sig_t = signal (SIGTERM, sig_h);
1118  old_sig_i = signal (SIGINT, sig_h);
1119  old_sig_c = signal (SIGCHLD, sig_c);
1120 
1121  /* execute nmap and read results from the process output */
1122  fproc = openvas_popen4 (nmap->args[0], nmap->args, &pid, 0);
1123  }
1124 
1125  if (!fproc)
1126  {
1127  err ("nmap_run_and_parse()");
1128  return -1;
1129  }
1130 
1131  ctx = g_markup_parse_context_new (&callbacks, 0, nmap, NULL);
1132 
1133  while ((len = fread (chunk, sizeof (gchar), CHUNK_LEN, fproc)) > 0)
1134  {
1135  GError *err = NULL;
1136 
1137  if (!g_markup_parse_context_parse (ctx, chunk, len, &err))
1138  {
1139  if (err)
1140  {
1141  dbg ("g_markup_parse_context_parse() failed (%s)\n",
1142  err->message);
1143  g_error_free (err);
1144 
1145  /* display the problematic chunk */
1146  chunk[len] = '\0';
1147  dbg ("Error occurred while parsing: %s\n", chunk);
1148 
1149  ret = -1;
1150  }
1151  break;
1152  }
1153  }
1154 
1155  if (nmap->filename && ferror (fproc))
1156  {
1157  err ("nmap_run_and_parse()");
1158  ret = -1;
1159  }
1160 
1161  if (nmap->filename)
1162  {
1163  fclose (fproc);
1164  }
1165  else
1166  {
1167  openvas_pclose (fproc, pid);
1168 
1169  signal (SIGINT, old_sig_i);
1170  signal (SIGTERM, old_sig_t);
1171  signal (SIGCHLD, old_sig_c);
1172  }
1173 
1174  g_markup_parse_context_free (ctx);
1175 
1176  return ret;
1177 }
1178 
1179 #define list_free(list, dtor, udata) do { \
1180  if (list) \
1181  { \
1182  g_slist_foreach (list, (GFunc) dtor, udata); \
1183  g_slist_free (list); \
1184  list = NULL; \
1185  } \
1186  } while (0)
1187 
1193 void
1194 current_host_reset (nmap_t * nmap)
1195 {
1196  int i;
1197 
1198  g_free (nmap->tmphost.addr);
1199  g_free (nmap->tmphost.state);
1200  g_free (nmap->tmphost.best_os);
1201  g_free (nmap->tmphost.tcpseq_index);
1202  g_free (nmap->tmphost.tcpseq_difficulty);
1203  g_free (nmap->tmphost.ipidseq);
1204 
1205  for (i = 0; i < MAX_TRACE_HOPS; i++)
1206  {
1207  g_free (nmap->tmphost.trace[i].addr);
1208  g_free (nmap->tmphost.trace[i].rtt);
1209  g_free (nmap->tmphost.trace[i].host);
1210  }
1211 
1212  list_free (nmap->tmphost.ports, port_destroy, nmap);
1213  list_free (nmap->tmphost.host_scripts, nse_script_destroy, nmap);
1214  list_free (nmap->tmphost.os_cpes, simple_item_destroy, NULL);
1215 
1216  memset (&nmap->tmphost, 0x00, sizeof (struct nmap_host));
1217 }
1218 
1227 void
1228 port_destroy (gpointer data, gpointer udata)
1229 {
1230  struct nmap_port *port;
1231  nmap_t *nmap;
1232 
1233  port = (struct nmap_port *) data;
1234  nmap = (nmap_t *) udata;
1235 
1236  if (port)
1237  {
1238  g_free (port->proto);
1239  g_free (port->portno);
1240  g_free (port->state);
1241  g_free (port->service);
1242  g_free (port->version);
1243 
1244  list_free (port->port_scripts, nse_script_destroy, nmap);
1245  list_free (port->version_cpes, simple_item_destroy, NULL);
1246  g_free (port);
1247  }
1248 }
1249 
1258 void
1259 nse_script_destroy (gpointer data, gpointer udata)
1260 {
1261  struct nse_script *script;
1262 
1263  script = (struct nse_script *) data;
1264  if (script)
1265  {
1266  g_free (script->name);
1267  g_free (script->output);
1268  g_free (script);
1269  }
1270 }
1271 
1281 void
1282 simple_item_destroy (gpointer data, gpointer udata)
1283 {
1284  g_free (data);
1285 }
1286 
1292 void
1293 tmphost_add_port (nmap_t * nmap)
1294 {
1295  struct nmap_port *newport;
1296 
1297  newport = g_malloc0 (sizeof (struct nmap_port));
1298  memcpy (newport, &nmap->tmpport, sizeof (struct nmap_port));
1299  nmap->tmphost.ports = g_slist_prepend (nmap->tmphost.ports, newport);
1300 }
1301 
1309 void
1310 tmphost_add_nse_hostscript (nmap_t * nmap, gchar * name, gchar * output)
1311 {
1312  struct nse_script *s;
1313 
1314  s = g_malloc0 (sizeof (struct nse_script));
1315  s->name = name;
1316  s->output = output;
1317  nmap->tmphost.host_scripts = g_slist_prepend (nmap->tmphost.host_scripts, s);
1318 }
1319 
1327 void
1328 tmphost_add_nse_portscript (nmap_t * nmap, gchar * name, gchar * output)
1329 {
1330  struct nse_script *s;
1331 
1332  s = g_malloc0 (sizeof (struct nse_script));
1333  s->name = name;
1334  s->output = output;
1335  nmap->tmpport.port_scripts = g_slist_prepend (nmap->tmpport.port_scripts, s);
1336 }
1337 
1349 void
1350 xml_start_element (GMarkupParseContext * context, const gchar * element_name,
1351  const gchar ** attribute_names,
1352  const gchar ** attribute_values, gpointer user_data,
1353  GError ** error)
1354 {
1355  nmap_t *nmap = (nmap_t *) user_data;
1356  void (*callback) (nmap_t *, const gchar **, const gchar **);
1357 
1358  callback = g_hash_table_lookup (nmap->parser.opentag, element_name);
1359  if (callback)
1360  callback (nmap, attribute_names, attribute_values);
1361 }
1362 
1372 void
1373 xml_end_element (GMarkupParseContext * context, const gchar * element_name,
1374  gpointer user_data, GError ** error)
1375 {
1376  nmap_t *nmap = (nmap_t *) user_data;
1377  void (*callback) (nmap_t *);
1378 
1379  callback = g_hash_table_lookup (nmap->parser.closetag, element_name);
1380  if (callback)
1381  callback (nmap);
1382 }
1383 
1394 void
1395 xml_read_text (GMarkupParseContext * context, const gchar * text,
1396  gsize text_len, gpointer user_data, GError ** error)
1397 {
1398  nmap_t *nmap = (nmap_t *) user_data;
1399 
1400  if (!nmap->parser.enable_read)
1401  return;
1402 
1403  if (nmap->parser.rbuff)
1404  {
1405  gchar *tmpbuff;
1406 
1407  tmpbuff = g_strdup_printf ("%s%s", nmap->parser.rbuff, text);
1408  g_free (nmap->parser.rbuff);
1409  nmap->parser.rbuff = tmpbuff;
1410  }
1411  else
1412  {
1413  nmap->parser.rbuff = g_strdup (text);
1414  }
1415 }
1416 
1424 void
1425 xmltag_open_host (nmap_t * nmap, const gchar ** attrnames,
1426  const gchar ** attrval)
1427 {
1428  nmap->parser.in_host = TRUE;
1429 }
1430 
1438 void
1439 xmltag_open_status (nmap_t * nmap, const gchar ** attrnames,
1440  const gchar ** attrval)
1441 {
1442  if (!nmap->parser.in_host)
1443  dbg ("Error: opening <status> tag out of host description\n");
1444  else
1445  nmap->tmphost.state = get_attr_value ("state", attrnames, attrval);
1446 }
1447 
1455 void
1456 xmltag_open_address (nmap_t * nmap, const gchar ** attrnames,
1457  const gchar ** attrval)
1458 {
1459  if (!nmap->parser.in_host)
1460  dbg ("Error: opening <address> tag out of host description\n");
1461  else
1462  nmap->tmphost.addr = get_attr_value ("addr", attrnames, attrval);
1463 }
1464 
1472 void
1473 xmltag_open_ports (nmap_t * nmap, const gchar ** attrnames,
1474  const gchar ** attrval)
1475 {
1476  nmap->parser.in_ports = TRUE;
1477 }
1478 
1486 void
1487 xmltag_open_port (nmap_t * nmap, const gchar ** attrnames,
1488  const gchar ** attrval)
1489 {
1490  nmap->parser.in_port = TRUE;
1491  nmap->tmpport.proto = get_attr_value ("protocol", attrnames, attrval);
1492  nmap->tmpport.portno = get_attr_value ("portid", attrnames, attrval);
1493 }
1494 
1502 void
1503 xmltag_open_state (nmap_t * nmap, const gchar ** attrnames,
1504  const gchar ** attrval)
1505 {
1506  if (!nmap->parser.in_port || !nmap->tmpport.proto || !nmap->tmpport.portno)
1507  dbg ("Error: opening <state> tag out of port description\n");
1508  else
1509  nmap->tmpport.state = get_attr_value ("state", attrnames, attrval);
1510 }
1511 
1519 void
1520 xmltag_open_service (nmap_t * nmap, const gchar ** attrnames,
1521  const gchar ** attrval)
1522 {
1523  if (!nmap->parser.in_port || !nmap->tmpport.proto || !nmap->tmpport.portno)
1524  dbg ("Error: opening <service> tag out of port description\n");
1525  else
1526  {
1527  gchar *product, *version, *extrainfo;
1528 
1529  nmap->tmpport.service = get_attr_value ("name", attrnames, attrval);
1530 
1531  /* also store version detection results if available */
1532  product = get_attr_value ("product", attrnames, attrval);
1533  version = get_attr_value ("version", attrnames, attrval);
1534  extrainfo = get_attr_value ("extrainfo", attrnames, attrval);
1535 
1536  if (product || version || extrainfo)
1537 #define PRINT_NOT_NULL(x) ((x) ? (x) : "")
1538  nmap->tmpport.version = g_strdup_printf ("%s %s %s",
1539  PRINT_NOT_NULL(product),
1540  PRINT_NOT_NULL(version),
1541  PRINT_NOT_NULL(extrainfo));
1542 #undef PRINT_NOT_NULL
1543 
1544  /* g_free'ing NULLs is harmless */
1545  g_free (product);
1546  g_free (version);
1547  g_free (extrainfo);
1548  }
1549 }
1550 
1558 void
1559 xmltag_open_cpe (nmap_t * nmap, const gchar ** attrnames,
1560  const gchar ** attrval)
1561 {
1562  /* Safety check */
1563  if (nmap->parser.rbuff)
1564  {
1565  g_free (nmap->parser.rbuff);
1566  nmap->parser.rbuff = NULL;
1567  }
1568  nmap->parser.enable_read = TRUE;
1569 }
1570 
1578 void
1579 xmltag_open_hostscript (nmap_t * nmap, const gchar ** attrnames,
1580  const gchar ** attrval)
1581 {
1582  nmap->parser.in_hostscript = TRUE;
1583 }
1584 
1592 void
1593 xmltag_open_osmatch (nmap_t * nmap, const gchar ** attrnames,
1594  const gchar ** attrval)
1595 {
1596  gchar *confstr;
1597 
1598  confstr = get_attr_value ("accuracy", attrnames, attrval);
1599  if (confstr)
1600  {
1601  int confidence;
1602 
1603  confidence = atoi (confstr);
1604  if (confidence > nmap->tmphost.os_confidence)
1605  {
1606  g_free (nmap->tmphost.best_os);
1607  nmap->tmphost.best_os = get_attr_value ("name", attrnames, attrval);
1608  nmap->tmphost.os_confidence = confidence;
1609  }
1610 
1611  g_free (confstr);
1612  }
1613 }
1614 
1622 void
1623 xmltag_open_script (nmap_t * nmap, const gchar ** attrnames,
1624  const gchar ** attrval)
1625 {
1626  gchar *name, *output;
1627 
1628  if (!nmap->parser.in_host)
1629  return;
1630 
1631  name = get_attr_value ("id", attrnames, attrval);
1632  output = get_attr_value ("output", attrnames, attrval);
1633 
1634  if (nmap->parser.in_port)
1635  tmphost_add_nse_portscript (nmap, name, output);
1636  else
1637  tmphost_add_nse_hostscript (nmap, name, output);
1638 }
1639 
1647 void
1648 xmltag_open_tcpsequence (nmap_t * nmap, const gchar ** attrnames,
1649  const gchar ** attrval)
1650 {
1651  if (!nmap->parser.in_host)
1652  return;
1653 
1654  nmap->tmphost.tcpseq_index = get_attr_value ("index", attrnames, attrval);
1655  nmap->tmphost.tcpseq_difficulty =
1656  get_attr_value ("difficulty", attrnames, attrval);
1657 }
1658 
1666 void
1667 xmltag_open_ipidsequence (nmap_t * nmap, const gchar ** attrnames,
1668  const gchar ** attrval)
1669 {
1670  if (!nmap->parser.in_host)
1671  return;
1672 
1673  nmap->tmphost.ipidseq = get_attr_value ("class", attrnames, attrval);
1674 }
1675 
1683 void
1684 xmltag_open_distance (nmap_t * nmap, const gchar ** attrnames,
1685  const gchar ** attrval)
1686 {
1687  gchar *diststr;
1688 
1689  if (!nmap->parser.in_host)
1690  return;
1691 
1692  diststr = get_attr_value ("value", attrnames, attrval);
1693  if (diststr)
1694  {
1695  nmap->tmphost.distance = atoi (diststr);
1696  g_free (diststr);
1697  }
1698 }
1699 
1707 void
1708 xmltag_open_hop (nmap_t * nmap, const gchar ** attrnames,
1709  const gchar ** attrval)
1710 {
1711  int ttl;
1712  gchar *ttl_str;
1713 
1714  if (!nmap->parser.in_host)
1715  return;
1716 
1717  ttl_str = get_attr_value ("ttl", attrnames, attrval);
1718  ttl = atoi (ttl_str) - 1; /* decrease ttl by one to use it as index */
1719  g_free (ttl_str);
1720 
1721  if (ttl < MAX_TRACE_HOPS)
1722  {
1723  if (!nmap->tmphost.trace[ttl].addr && !nmap->tmphost.trace[ttl].host
1724  && !nmap->tmphost.trace[ttl].rtt)
1725  {
1726  nmap->tmphost.trace[ttl].addr = get_attr_value ("ipaddr", attrnames,
1727  attrval);
1728  nmap->tmphost.trace[ttl].host = get_attr_value ("host", attrnames,
1729  attrval);
1730  nmap->tmphost.trace[ttl].rtt = get_attr_value ("rtt", attrnames,
1731  attrval);
1732  }
1733  else
1734  dbg ("Inconsistent results: duplicate traceroute information!");
1735  }
1736  else
1737  dbg ("Trace TTL out of bounds: %d (max=%d)", ttl, MAX_TRACE_HOPS);
1738 }
1739 
1745 void
1746 xmltag_close_host (nmap_t * nmap)
1747 {
1748  nmap->parser.in_host = FALSE;
1749  current_host_saveall (nmap);
1750  current_host_reset (nmap);
1751 }
1752 
1758 void
1759 xmltag_close_ports (nmap_t * nmap)
1760 {
1761  nmap->parser.in_ports = FALSE;
1762 }
1763 
1769 void
1770 xmltag_close_port (nmap_t * nmap)
1771 {
1772  nmap->parser.in_port = FALSE;
1773  tmphost_add_port (nmap);
1774  memset (&nmap->tmpport, 0x00, sizeof (struct nmap_port));
1775 }
1776 
1782 void
1783 xmltag_close_cpe (nmap_t * nmap)
1784 {
1785  if (nmap->parser.rbuff)
1786  {
1787  if (nmap->parser.in_port)
1788  nmap->tmpport.version_cpes = g_slist_prepend (nmap->tmpport.version_cpes,
1789  nmap->parser.rbuff);
1790  else
1791  nmap->tmphost.os_cpes = g_slist_prepend (nmap->tmphost.os_cpes,
1792  nmap->parser.rbuff);
1793  }
1794 
1795  /* Don't free rbuff here, as we need it in the CPE list. */
1796  nmap->parser.rbuff = NULL;
1797  nmap->parser.enable_read = FALSE;
1798 }
1799 
1805 void
1806 xmltag_close_hostscript (nmap_t * nmap)
1807 {
1808  nmap->parser.in_hostscript = FALSE;
1809 }
1810 
1821 gchar *
1822 get_attr_value (const gchar * name, const gchar **
1823  attribute_names, const gchar ** attribute_values)
1824 {
1825  int i;
1826 
1827  for (i = 0; attribute_names[i]; i++)
1828  if (g_strcmp0 (attribute_names[i], name) == 0)
1829  return g_strdup (attribute_values[i]);
1830  return NULL;
1831 }
1832 
1838 void
1839 current_host_saveall (nmap_t * nmap)
1840 {
1841  /* Host state: dead or alive */
1842  save_host_state (nmap);
1843 
1844  /* Open ports and services (all protocols included) */
1845  save_open_ports (nmap);
1846 
1847  /* OS fingerprinting results */
1848  save_detected_os (nmap);
1849 
1850  /* TCP/IP sensitive fields details */
1851  save_tcpseq_details (nmap);
1852  save_ipidseq_details (nmap);
1853 
1854  /* Traceroute */
1855  save_traceroute_details (nmap);
1856 
1857  /* NSE results */
1858  save_hostscripts (nmap);
1859  save_portscripts (nmap);
1860 }
1861 
1867 void
1868 save_host_state (nmap_t * nmap)
1869 {
1870  gchar key[32];
1871 
1872  if (!nmap->tmphost.state)
1873  return;
1874 
1875  g_snprintf (key, sizeof (key), "%s/Host/State", nmap->tmphost.addr);
1876  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.state);
1877 }
1878 
1885 void
1886 save_open_ports (nmap_t * nmap)
1887 {
1888  GSList *pport;
1889 
1890  for (pport = nmap->tmphost.ports; pport; pport = g_slist_next (pport))
1891  {
1892  struct nmap_port *p;
1893 
1894  p = (struct nmap_port *) pport->data;
1895  if (strncmp (p->state, "open", 4) == 0)
1896  {
1897  gchar key[64];
1898 
1899  g_snprintf (key, sizeof (key), "%s/Ports/%s/%s", nmap->tmphost.addr,
1900  p->proto, p->portno);
1901  plug_set_key (nmap->env, key, ARG_INT, (void *) 1);
1902 
1903  /* Register detected service */
1904  register_service (nmap, p);
1905  }
1906  }
1907 }
1908 
1916 void
1917 register_service (nmap_t * nmap, struct nmap_port *p)
1918 {
1919  gchar key[64];
1920 
1921  if (!p->portno || !p->proto || !p->service)
1922  return;
1923 
1924  /* TCP services aren't stored with the same syntax than the other layer 4
1925  * protocols. */
1926  if (g_strcmp0 (p->proto, "tcp") == 0)
1927  g_snprintf (key, sizeof (key), "%s/Services/%s", nmap->tmphost.addr,
1928  p->service);
1929  else
1930  g_snprintf (key, sizeof (key), "%s/Services/%s/%s", nmap->tmphost.addr,
1931  p->proto, p->service);
1932  plug_set_key (nmap->env, key, ARG_INT, GINT_TO_POINTER (atoi (p->portno)));
1933 
1934  /* The service detection system requires discovered services to be
1935  * registered under the "Known" label too */
1936  g_snprintf (key, sizeof (key), "%s/Known/%s/%s", nmap->tmphost.addr,
1937  p->proto, p->portno);
1938  plug_set_key (nmap->env, key, ARG_STRING, p->service);
1939 
1940  if (p->version)
1941  {
1942  /* Store version detection results if available */
1943  g_snprintf (key, sizeof (key), "%s/Version/%s/%s", nmap->tmphost.addr,
1944  p->proto, p->portno);
1945  plug_set_key (nmap->env, key, ARG_STRING, p->version);
1946  }
1947 
1948  if (p->version_cpes)
1949  {
1950  GSList *pcpe;
1951 
1952  g_snprintf (key, sizeof (key), "%s/App/%s/%s", nmap->tmphost.addr,
1953  p->proto, p->portno);
1954 
1955  for (pcpe = p->version_cpes; pcpe; pcpe = g_slist_next (pcpe))
1956  plug_set_key (nmap->env, key, ARG_STRING, (gchar *) pcpe->data);
1957  }
1958 }
1959 
1966 void
1967 save_detected_os (nmap_t * nmap)
1968 {
1969  gchar key[32];
1970 
1971  if (nmap->tmphost.best_os)
1972  {
1973  g_snprintf (key, sizeof (key), "%s/Host/OS", nmap->tmphost.addr);
1974  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.best_os);
1975  }
1976 
1977  if (nmap->tmphost.os_cpes)
1978  {
1979  GSList *pcpe;
1980 
1981  /* Use a different key to ensure that Host/OS remains unique. */
1982  g_snprintf (key, sizeof (key), "%s/Host/CPE", nmap->tmphost.addr);
1983 
1984  for (pcpe = nmap->tmphost.os_cpes; pcpe; pcpe = g_slist_next (pcpe))
1985  plug_set_key (nmap->env, key, ARG_STRING, (gchar *) pcpe->data);
1986  }
1987 }
1988 
1995 void
1996 save_tcpseq_details (nmap_t * nmap)
1997 {
1998  gchar key[64];
1999 
2000  if (!nmap->tmphost.tcpseq_index || !nmap->tmphost.tcpseq_difficulty)
2001  return;
2002 
2003  g_snprintf (key, sizeof (key), "%s/Host/tcp_seq_index", nmap->tmphost.addr);
2004  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.tcpseq_index);
2005 
2006  g_snprintf (key, sizeof (key), "%s/Host/tcp_seq_difficulty",
2007  nmap->tmphost.addr);
2008  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.tcpseq_difficulty);
2009 }
2010 
2016 void
2017 save_ipidseq_details (nmap_t * nmap)
2018 {
2019  gchar key[32];
2020 
2021  if (!nmap->tmphost.ipidseq)
2022  return;
2023 
2024  g_snprintf (key, sizeof (key), "%s/Host/ipidseq", nmap->tmphost.addr);
2025  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.ipidseq);
2026 }
2027 
2034 void
2035 save_traceroute_details (nmap_t * nmap)
2036 {
2037  int i;
2038  gchar key[64];
2039 
2040  if (!nmap->tmphost.distance || nmap->tmphost.distance >= MAX_TRACE_HOPS)
2041  return;
2042 
2043  g_snprintf (key, sizeof (key), "%s/Host/distance", nmap->tmphost.addr);
2044  plug_set_key (nmap->env, key, ARG_INT,
2045  GINT_TO_POINTER (nmap->tmphost.distance));
2046 
2047  for (i = 0; i < nmap->tmphost.distance; i++)
2048  {
2049  g_snprintf (key, sizeof (key), "%s/Host/traceroute/hops/%d",
2050  nmap->tmphost.addr, i + 1);
2051  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.trace[i].addr);
2052 
2053  g_snprintf (key, sizeof (key), "%s/Host/traceroute/hops/%d/rtt",
2054  nmap->tmphost.addr, i + 1);
2055  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.trace[i].rtt);
2056 
2057  g_snprintf (key, sizeof (key), "%s/Host/traceroute/hops/%d/host",
2058  nmap->tmphost.addr, i + 1);
2059  plug_set_key (nmap->env, key, ARG_STRING, nmap->tmphost.trace[i].host);
2060  }
2061 }
2062 
2068 void
2069 save_portscripts (nmap_t * nmap)
2070 {
2071  GSList *pport;
2072 
2073  for (pport = nmap->tmphost.ports; pport; pport = g_slist_next (pport))
2074  {
2075  GSList *pscript;
2076  struct nmap_port *port;
2077 
2078  port = (struct nmap_port *) pport->data;
2079 
2080  for (pscript = port->port_scripts; pscript;
2081  pscript = g_slist_next (pscript))
2082  {
2083  struct nse_script *script;
2084  gchar key[128], portspec[16];
2085 
2086  script = (struct nse_script *) pscript->data;
2087 
2088  g_snprintf (key, sizeof (key), "%s/NmapNSE/results/%s",
2089  nmap->tmphost.addr, script->name);
2090 
2091  g_snprintf (portspec, sizeof (portspec), "%s/%s", port->proto,
2092  port->portno);
2093  plug_set_key (nmap->env, key, ARG_STRING, portspec);
2094 
2095  g_strlcat (key, "/", sizeof (key));
2096  g_strlcat (key, portspec, sizeof (key));
2097  plug_set_key (nmap->env, key, ARG_STRING, script->output);
2098  }
2099  }
2100 }
2101 
2107 void
2108 save_hostscripts (nmap_t * nmap)
2109 {
2110  GSList *pscript;
2111 
2112  for (pscript = nmap->tmphost.host_scripts; pscript;
2113  pscript = g_slist_next (pscript))
2114  {
2115  struct nse_script *script;
2116  gchar key[128];
2117 
2118  script = (struct nse_script *) pscript->data;
2119  g_snprintf (key, sizeof (key), "%s/NmapNSE/results/hostscripts/%s",
2120  nmap->tmphost.addr, script->name);
2121  plug_set_key (nmap->env, key, ARG_STRING, script->output);
2122  }
2123 }
2124 
Handle states for XML parsing.
#define PREF_TREAT_ALL_HOST_ONLINE
Plugin parameter description: skip alive hosts discovery phase.
FILE * openvas_popen4(const char *cmd, char *const args[], pid_t *ppid, int inice)
Definition: popen.c:36
#define FAKE_CELL
Definition: nasl_tree.h:120
#define ARG_INT
Definition: arglists.h:40
#define err(x)
gboolean in_hostscript
#define PREF_MAX_RTT_TIMEOUT
Plugin parameter description: probe round trip time hint (maximal value).
#define NMAP_CMD
Nmap command to call.
void kb_item_free(struct kb_item *)
Release a KB item (or a list).
Definition: kb_redis.c:501
GSList * version_cpes
#define PREF_RPC_PORT_SCAN
Plugin parameter description: perform RPC port scan.
const char * oid
#define PREF_INTERPROBE_DELAY
Plugin parameter description: set idle interval between probes.
void plug_set_key(struct arglist *args, char *name, int type, const void *value)
Definition: plugutils.c:658
GSList * ports
struct traceroute_hop trace[MAX_TRACE_HOPS]
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition: kb.h:81
gchar * tcpseq_index
struct kb_item * next
Definition: kb.h:91
#define PREF_EXCLUDE_HOSTS
Plugin parameter description: comma-separated list of hosts to exclude from the scan.
#define PREF_MIN_PARALLELISM
Plugin parameter description: force minimum number of parallel active probes.
#define PREF_AGGRESSIVE_OS_DETECT
Plugin parameter description: guess OS from closest match if necessary.
#define PREF_TIMING_POLICY
Plugin parameter description: select timing template.
#define PREF_TCP_SCANNING_TECHNIQUE
Plugin parameter description: TCP port scanning technique to use.
gboolean argument_required
gchar * tcpseq_difficulty
#define OPT_SET
Checkbox value (when set).
Store port information.
Describe a detected hop on the route.
GHashTable * closetag
#define PREF_TRACEROUTE
Plugin parameter description: perform traceroute.
#define PREF_HOST_TIMEOUT
Plugin parameter description: give up on host after this time elapsed.
#define PREF_MAX_HOSTGROUP
Plugin parameter description: force maximum number of hosts to scan in parallel.
struct arglist * env
#define PREF_SOURCE_PORT
Plugin parameter description: set source port.
gchar ** args
Describe an nmap command line option.
const gchar * prefs_get(const gchar *key)
Get a string preference value via a key.
Definition: prefs.c:86
struct nmap_port tmpport
const char * get_plugin_preference_fname(struct arglist *desc, const char *filename)
Get the file name of a plugins preference that is of type "file".
Definition: plugutils.c:551
#define PREF_MIN_RTT_TIMEOUT
Plugin parameter description: probe round trip time hint (minimal value)
kb_t plug_get_kb(struct arglist *args)
Definition: plugutils.c:710
GHashTable * opentag
struct nmap_host tmphost
#define PRINT_NOT_NULL(x)
#define PREF_IDENTIFY_REMOTE_OS
Plugin parameter description: perform remote OS fingerprinting.
#define PREF_IMPORT_XML_FILE
Plugin parameter description: import XML file.
GSList * port_scripts
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:102
Definition: nasl_tree.h:105
int openvas_pclose(FILE *fp, pid_t pid)
Definition: popen.c:136
static void(*)(*) old_sig_i()
Definition: nasl_cmd_exec.c:48
#define PREF_INITIAL_RTT_TIMEOUT
Plugin parameter description: probe round trip time hint (initial value).
tree_cell * plugin_run_nmap(lex_ctxt *lexic)
Run the nmap_net subsystem.
#define PREF_NO_DNS
Plugin parameter description: don't perform reverse resolution on discovered IP addresses.
const char * name
Definition: nasl_init.c:524
#define list_free(list, dtor, udata)
#define CHUNK_LEN
Input chunks size for the XML parser.
#define PREF_SERVICE_SCAN
Plugin parameter description: perform service/version detection scan.
struct nmap_parser parser
#define PREF_MAX_PARALLELISM
Plugin parameter description: force maximum number of parallel active probes.
#define MAX_TRACE_HOPS
Maximum number of hops to the target.
static void(*)(*) old_sig_c
Definition: nasl_cmd_exec.c:48
#define dbg(...)
#define ARG_STRING
Definition: arglists.h:38
#define PREF_FRAGMENT_IP
Plugin parameter description: try to evade defense by fragmenting IP packets.
Handle the results of a NSE script.
GSList * host_scripts
const char * oid
Definition: nasl_lex_ctxt.h:40
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39
#define PREF_MIN_HOSTGROUP
Plugin parameter description: force minimum number of hosts to scan in parallel.
GSList * os_cpes
Store host information.
void * arg_get_value(struct arglist *args, const char *name)
Definition: arglists.c:252
Main nmap execution handler.
gboolean enable_read
char * v_str
Definition: kb.h:87
char * get_plugin_preference(const char *oid, const char *name)
Definition: plugutils.c:476
const gchar * filename