Exemple #1
0
struct arglist * str2arglist(char * str)
{
 struct arglist * ret;
 char * t = strchr(str, ',');


 if(!str || str[0] == '\0')
  {
   return NULL;
  }

 ret = emalloc ( sizeof(struct arglist) );
  
  
 while((t = strchr(str, ',')) != NULL)
 {
  t[0] = 0;
  while(str[0]==' ')str++;
  if(str[0] != '\0')
  {
   arg_add_value(ret, str, ARG_INT, 0, (void*)1);
  }
  str = t+1;
 }
 
 while(str[0]==' ')str++;
 if(str[0] != '\0')
   arg_add_value(ret, str, ARG_INT, 0, (void*)1);
  

  return ret;
}
Exemple #2
0
struct arglist * plug_get_oldstyle_kb(struct arglist * desc )
{
 struct kb_item ** kb = arg_get_value(desc, "key");
 struct arglist * ret;
 struct kb_item * k;
 int i;
 if ( kb == NULL )
	return NULL;

 ret = emalloc ( sizeof(struct arglist) );
 for ( i = 0 ; i < HASH_MAX ; i ++ )
 {
  k = kb[i];
  while ( k != NULL )
  {
  if ( k->type == KB_TYPE_INT )
	arg_add_value(ret, k->name, ARG_INT, -1, (void*)k->v.v_int);
  else if ( k->type == KB_TYPE_STR )
	arg_add_value(ret, k->name, ARG_STRING, strlen(k->v.v_str), estrdup(k->v.v_str));
   k = k->next;
  }
 }

 return ret;

}
static void
main_loop ()
{
  log_write ("openvassd %s started\n", OPENVASSD_VERSION);
  proctitle_set ("openvassd: Waiting for incoming connections");
  for (;;)
    {
      int soc;
      int family;
      unsigned int lg_address;
      struct sockaddr_in6 address6;
      struct sockaddr_in6 *p_addr;
      struct arglist *globals;
      struct addrinfo *ai;

      check_and_reload ();
      wait_for_children1 ();
      ai = arg_get_value (g_options, "addr");
      lg_address = sizeof (struct sockaddr_in6);
      soc = accept (global_iana_socket, (struct sockaddr *) (&address6),
                    &lg_address);
      if (soc == -1)
        continue;

      /*
       * MA: you cannot share an open SSL connection through fork/multithread
       * The SSL connection shall be open _after_ the fork */
      globals = emalloc (sizeof (struct arglist));
      arg_add_value (globals, "global_socket", ARG_INT, -1,
                     GSIZE_TO_POINTER (soc));

      arg_add_value (globals, "plugins", ARG_ARGLIST, -1, global_plugins);
      arg_add_value (globals, "preferences", ARG_ARGLIST, -1, global_preferences);

      p_addr = emalloc (sizeof (struct sockaddr_in6));
      family = ai->ai_family;
      memcpy (p_addr, &address6, sizeof (address6));
      arg_add_value (globals, "client_address", ARG_PTR, -1, p_addr);
      arg_add_value (globals, "family", ARG_INT, -1, GSIZE_TO_POINTER (family));

      /* we do not want to create an io thread, yet so the last argument is -1 */
      if (create_process ((process_func_t) scanner_thread, globals) < 0)
        {
          log_write ("Could not fork - client won't be served");
          sleep (2);
        }
      close (soc);
      arg_free (globals);
    }
}
static void
arg_replace_value (struct arglist *arglist, char *name, int type, int length,
                   void *value)
{
  if (arg_get_type (arglist, name) < 0)
    arg_add_value (arglist, name, type, length, value);
  else
    arg_set_value (arglist, name, length, value);
}
Exemple #5
0
void add_socket(struct arglist *script_infos, int socket)
{
    struct arglist *socket_list = NULL;
    struct arglist *temp_list = NULL;
    char line[10] = {0};

    if (socket <= 0) return;

    socket_list = (struct arglist *)arg_get_value(script_infos, "socket_list");
    if (!socket_list) {
        socket_list = emalloc(sizeof(struct arglist));
        if (!socket_list) return;
        arg_add_value(script_infos, "socket_list", ARG_PTR, -1, socket_list);
    }
    sprintf(line, "%d", socket);
    if (arg_get_value(socket_list, line) <= 0)
        arg_add_value(socket_list, line, ARG_INT, -1, (void *)socket);
}
void plugin_set_running_state(struct arglist * plugin, int state)
{
 if(plugin == NULL)
  return;
  
 if(arg_get_value(plugin, "RUNNING_STATE") != NULL)
  arg_set_value(plugin, "RUNNING_STATE", sizeof(state), (void*)state);
 else 
  arg_add_value(plugin, "RUNNING_STATE", ARG_INT, sizeof(state), (void*)state);
}
struct arglist * store_load_plugin(char * dir, char * file, char * md5, struct arglist * prefs)
{
 char desc_file[PATH_MAX+1];
 char plug_file[PATH_MAX+1];
 char * str;
 char store_dir[PATH_MAX+1];
 struct plugin p;
 struct pprefs pp[MAX_PREFS];
 
 struct arglist * ret;
 int i;
 
 bzero(pp, sizeof(pp));
 
 snprintf(desc_file, sizeof(desc_file), "%s/.desc/%s", dir, file);

 str = strrchr(desc_file, '.');
 if( str != NULL )
 {
  str[0] = '\0';
  if(	strlen(desc_file) + 6 < sizeof(desc_file) )
  	strcat(desc_file, ".desc");
 }
 snprintf(plug_file, sizeof(plug_file), "%s/%s", dir, file);
 snprintf(store_dir, sizeof(store_dir), "%s/.desc", dir);
 if(store_get_plugin_f(&p, pp, store_dir, file) < 0)
  return NULL;
  
 if(p.magic != MAGIC)
 	return NULL;
	
	
 if(p.id > 0)
 {
  if(md5 != NULL && strcmp(p.md5, md5) != 0)
   return NULL;
 }
 else return NULL;
    
 ret = emalloc(sizeof(struct arglist));   
 plug_set_id(ret, p.id);
 plug_set_category(ret, p.category);
 plug_set_fname(ret, file);
 arg_add_value(ret, "preferences", ARG_ARGLIST, -1, prefs);
 
 if(p.has_prefs)
 {
 for(i=0;pp[i].type[0] != '\0';i++)
  { 
   _add_plugin_preference(prefs, p.name, pp[i].name, pp[i].type, pp[i].dfl);
  }
 }

 return ret;
}
/**
 * @brief Inits an arglist which can be used by the plugins.
 *
 * The arglist will have following keys and (type, value):
 *  - NAME (string, The hostname parameter)
 *  - FQDN (string, Fully qualified domain name, e.g. host.domain.net)
 *  - MAC  (string, The mac parameter if non-NULL)
 *  - IP   (*in_adrr, The ip parameter)
 *  - VHOSTS (string, comma separated list of vhosts for this IP)
 *
 * @param mac      MAC- adress of host or NULL.
 * @param hostname Hostname to be set.
 * @param ip       in_adress struct to be set.
 * @param vhosts   vhosts list to be set
 *
 * @return A 'hostinfo' arglist.
 */
static struct arglist *
attack_init_hostinfos_vhosts (char *mac, char *hostname, struct in6_addr *ip,
                              char *vhosts, char *fqdn)
{
  struct arglist *hostinfos;

  hostinfos = emalloc (sizeof (struct arglist));
  if (mac)
    {
      arg_add_value (hostinfos, "NAME", ARG_STRING, strlen (mac), mac);
      arg_add_value (hostinfos, "MAC", ARG_STRING, strlen (mac), mac);
    }
  else
    arg_add_value (hostinfos, "NAME", ARG_STRING, strlen (hostname),
                   estrdup (hostname));

  if (fqdn)
    arg_add_value (hostinfos, "FQDN", ARG_STRING, strlen (fqdn),
                   estrdup (fqdn));
  arg_add_value (hostinfos, "IP", ARG_PTR, sizeof (struct in6_addr), ip);
  if (vhosts)
    arg_add_value (hostinfos, "VHOSTS", ARG_STRING, strlen (vhosts),
                   estrdup (vhosts));
  return (hostinfos);
}
Exemple #9
0
tree_cell * nasl_start_denial(lex_ctxt * lexic)
{
 struct arglist * script_infos = lexic->script_infos;
 int to = lexic->recv_timeout;
 int port = plug_get_host_open_port(script_infos);
 int soc;
 int alive = 0;
 tree_cell * p;
  
 if(port)
 {
  soc = open_stream_connection(script_infos, port, NESSUS_ENCAPS_IP, to);
  if(soc>=0)
  {
   if(arg_get_value(script_infos, "denial_port") != 0)
    arg_set_value(script_infos, "denial_port", sizeof(int), (void*)port);
   else
    arg_add_value(script_infos, "denial_port", ARG_INT, sizeof(int), (void*)port);
    
   close_stream_connection(soc);
  
   return FAKE_CELL;
  }
 }

 p = nasl_tcp_ping(lexic);
 if (p != NULL) alive = p->x.i_val;

 if(arg_get_value(script_infos, "tcp_ping_result") != 0)
  arg_set_value(script_infos, "tcp_ping_result", sizeof(int), (void*)alive);
 else
  arg_add_value(script_infos, "tcp_ping_result", ARG_INT, sizeof(int), (void*)alive);
 
 deref_cell(p);

 return FAKE_CELL;
}
Exemple #10
0
/* add udp data in our cache */
static int add_udp_data(struct arglist * script_infos, int soc, char * data, int len)
{
 harglst * udp_data = arg_get_value(script_infos, "udp_data");
 char name[12] = {0};
 if(udp_data == NULL)
 {
  udp_data = harg_create(123);
  arg_add_value(script_infos, "udp_data", ARG_PTR, -1, udp_data);
 }
 snprintf(name, sizeof(name)-1, "%d", soc);
 
 if(harg_get_blob(udp_data, name) != NULL)
  harg_set_blob(udp_data, name, len, data);
 else
  harg_add_blob( udp_data, name, len, data);
 return 0;
}
/* add udp data in our cache */
static int
add_udp_data (struct arglist *script_infos, int soc, char *data, int len)
{
  GHashTable * udp_data = arg_get_value (script_infos, "udp_data");
  struct udp_record * data_record = g_malloc0 (sizeof(struct udp_record));
  int * key = g_memdup (&soc, sizeof(int));

  data_record->len = len;
  data_record->data = g_memdup ((gconstpointer)data, (guint)len);

  if (udp_data == NULL)
    {
      udp_data = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free);
      arg_add_value (script_infos, "udp_data", ARG_PTR, -1, udp_data);
    }

  g_hash_table_replace (udp_data, (gpointer)key, (gpointer)data_record);

  return 0;
}
/**
 * @brief Returns \<port\> if the lists of the required ports between
 * @brief plugin 1 and plugin 2 have at least one port in common.
 */
struct arglist *
requirements_common_ports (struct scheduler_plugin *plugin1,
                           struct scheduler_plugin *plugin2)
{
  struct arglist *ret = NULL;
  struct arglist *req1;
  struct arglist *req2;

  if (!plugin1 || !plugin2)
    return 0;

  req1 = plugin1->required_ports;
  if (req1 == NULL)
    return 0;

  req2 = plugin2->required_ports;
  if (req2 == NULL)
    return 0;

  while (req1->next != NULL)
    {
      struct arglist *r = req2;
      if (r != NULL)
        while (r->next != NULL)
          {
            if (req1->type == r->type)
              {
                if (r->name && req1->name && !strcmp (r->name, req1->name))
                  {
                    if (!ret)
                      ret = emalloc (sizeof (struct arglist));
                    arg_add_value (ret, r->name, ARG_INT, 0, (void *) 1);
                  }
              }
            r = r->next;
          }
      req1 = req1->next;
    }
  return ret;
}
Exemple #13
0
int
execute_nasl_script(struct arglist * script_infos, const char* name, int mode)
{
  naslctxt	ctx;
  nasl_func	*pf;
  int		err = 0;
  tree_cell	*ret;
  lex_ctxt	*lexic;
  char 	 	old_dir[MAXPATHLEN+1];
  char		*newdir;
  char		*old;
  tree_cell	description;
  struct arglist*	prefs = arg_get_value(script_infos, "preferences");
  char		*str;
  int to;
  
  srand48(getpid() + getppid() + (long)time(NULL));

  old_dir[sizeof(old_dir) - 1] = '\0';
  getcwd(old_dir, sizeof(old_dir) - 1);
#if NASL_DEBUG > 2
  nasl_trace_fp = stderr;
#endif
 if((old = arg_get_value(script_infos, "script_name")) == NULL)
   arg_add_value(script_infos, "script_name", ARG_STRING, strlen(name), estrdup(name));
 else
   { 
   efree(&old);
   arg_set_value(script_infos, "script_name", strlen(name), estrdup(name));
  }
 
 newdir = strrchr(name, '/');
 if(newdir != NULL)
 {
	 char dir[MAXPATHLEN+1];
	 char *s;
	 dir[sizeof(dir) - 1] = '\0';
	 strncpy(dir, name, sizeof(dir) - 1);
	 s = strrchr(dir, '/');
	 s[0] = '\0';
	 chdir(dir);
 }

 if (init_nasl_ctx(&ctx, name) < 0)
 {
    chdir(old_dir);
    return -1;
 }

 if (naslparse(&ctx))
   {
     nasl_perror(NULL, "\nParse error at or near line %d\n", ctx.line_nb);
     nasl_clean_ctx(&ctx);
     chdir(old_dir);
     return -1;
   }
#if NASL_DEBUG > 4
 nasl_dump_tree(ctx.tree);
#endif
 lexic = init_empty_lex_ctxt();
 lexic->script_infos = script_infos;
 
 str = arg_get_value(prefs, "checks_read_timeout");
 if( str != NULL )
 	to = atoi(str);
 else
 	to = 5;
	
 if(to <= 0)to = 5;
 
 lexic->recv_timeout = to;
 init_nasl_library(lexic);

 if (! (mode & NASL_EXEC_PARSE_ONLY))
   {
     bzero(&description, sizeof(description));
     description.type = CONST_INT;
     description.x.i_val = (mode & NASL_EXEC_DESCR) != 0;
     add_named_var_to_ctxt(lexic, "description", &description);

     truc = (lex_ctxt*)ctx.tree;
     if ((ret = nasl_exec(lexic, ctx.tree)) == NULL)
       err = -1;
     else
       deref_cell(ret);

     if ((pf = get_func_ref_by_name(lexic, "on_exit")) != NULL)
       nasl_func_call(lexic, pf, NULL);
   }

#if NASL_DEBUG > 2
 {
   struct rusage	ru;

   if (getrusage(RUSAGE_SELF, &ru) < 0)
     perror("getrusage");
   else
     {
       nasl_perror(lexic, 
		   "rusage: utime=%d.%02d stime=%d.%02d minflt=%d majflt=%d\n",
		   ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000,
		   ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 10000,
		   ru.ru_minflt, ru.ru_majflt);
     }

 }
#endif

#if NASL_DEBUG > 3
 nasl_dump_tree(ctx.tree);
#endif
 nasl_clean_ctx(&ctx);
 free_lex_ctxt(lexic);
 chdir(old_dir);

 return err;
}
Exemple #14
0
/**
 * @brief Attack one host.
 */
static void
attack_host (struct arglist *globals, struct arglist *hostinfos, char *hostname,
             plugins_scheduler_t sched)
{
  /* Used for the status */
  int num_plugs = 0;
  int cur_plug = 1;

  kb_t kb;
  gboolean new_kb = FALSE;
  int forks_retry = 0;
  struct arglist *plugins = arg_get_value (globals, "plugins");
  struct arglist *tmp;

  proctitle_set ("openvassd: testing %s", arg_get_value (hostinfos, "NAME"));

  kb = init_host_kb (globals, hostname, hostinfos, &new_kb);

  num_plugs = get_active_plugins_number (plugins);

  tmp = emalloc (sizeof (struct arglist));
  arg_add_value (tmp, "HOSTNAME", ARG_ARGLIST, -1, hostinfos);

  /* launch the plugins */
  pluginlaunch_init (globals);

  for (;;)
    {
      struct scheduler_plugin *plugin;
      pid_t parent;

      /* Check that our father is still alive */
      parent = getppid ();
      if (parent <= 1 || process_alive (parent) == 0)
        {
          pluginlaunch_stop ();
          return;
        }

      /* Idle if the scan has been paused. */
      if (pause_whole_test)
        {
          /* Let the running NVTs complete. */
          pluginlaunch_wait ();

          /* Send the PAUSE status to the client. */
          if (comm_send_status (globals, hostname, "pause", cur_plug, num_plugs)
              < 0)
            {
              pluginlaunch_stop ();
              goto host_died;
            }

          /* Wait for resume. */
          while (pause_whole_test)
            sleep (1);

          /* Send the RESUME status to the client. */
          if (comm_send_status (globals, hostname, "resume", cur_plug,
                                num_plugs) < 0)
            {
              pluginlaunch_stop ();
              goto host_died;
            }
        }

      plugin = plugins_scheduler_next (sched);
      if (plugin != NULL && plugin != PLUG_RUNNING)
        {
          int e;

        again:
          e = launch_plugin (globals, sched, plugin, hostname, &cur_plug,
                             num_plugs, hostinfos, kb, new_kb);
          if (e < 0)
            {
              /*
               * Remote host died
               */
              if (e == ERR_HOST_DEAD)
                goto host_died;
              else if (e == ERR_CANT_FORK)
                {
                  if (forks_retry < MAX_FORK_RETRIES)
                    {
                      forks_retry++;
                      log_write ("fork() failed - sleeping %d seconds (%s)",
                                 forks_retry, strerror (errno));
                      fork_sleep (forks_retry);
                      goto again;
                    }
                  else
                    {
                      log_write ("fork() failed too many times - aborting");
                      goto host_died;
                    }
                }
            }
        }
      else if (plugin == NULL)
        break;
      else
        pluginlaunch_wait_for_free_process ();
    }

  pluginlaunch_wait ();

host_died:
  comm_send_status (globals, hostname, "attack", num_plugs, num_plugs);
  arg_free (tmp);
  pluginlaunch_stop ();
  plugins_scheduler_free (sched);

  gchar *network_scan_status = arg_get_value (globals, "network_scan_status");
  if (network_scan_status != NULL)
    {
      if (g_ascii_strcasecmp (network_scan_status, "busy") == 0)
        {
          save_kb_close (globals, "network");
        }
    }
  else
    if (new_kb == TRUE)
      save_kb_close (globals, hostname);

}
Exemple #15
0
struct arglist * store_plugin(struct arglist * plugin, char * file, char * md5)
{
 char desc_file[PATH_MAX+1];
 char path[PATH_MAX+1];
 struct plugin plug;
 struct pprefs pp[MAX_PREFS+1];
 char  * str;
 char * dir;
 struct arglist * arglist, * ret,  *prefs;
 int e;
 int fd;
 int num_plugin_prefs = 0;
 
 if( current_mode == MODE_SYS )
   dir = sys_store_dir;
  else
   dir = usr_store_dir;
   
  if(strlen(file) + 2 > sizeof(path))
  	return NULL;
 
 strncpy(path, dir, sizeof(path) - 2 - strlen(file));
 str = strrchr(path, '/');
 if(str != NULL)
 {
  str[0] = '\0';
 }
 strcat(path, "/");
 strcat(path, file);

 
 
 snprintf(desc_file, sizeof(desc_file), "%s/%s", dir, file);
 str = strrchr(desc_file, '.');
 if( str != NULL )
 {
  str[0] = '\0';
  if(strlen(desc_file) + 6 < sizeof(desc_file) )
  	strcat(desc_file, ".desc");
 }

 
 
 bzero(&plug, sizeof(plug));
 bzero(pp, sizeof(pp));
 
 plug.magic = MAGIC;
 plug.id = _plug_get_id(plugin);
 e = safe_copy(path, plug.path, sizeof(plug.path), path, "path"); 
 if(e < 0)return NULL;

 e = safe_copy(md5, plug.md5, sizeof(plug.md5), path, "md5");
 if(e < 0)return NULL;
 
 
 plug.timeout = _plug_get_timeout(plugin);
 plug.category = _plug_get_category(plugin);
 
 str = _plug_get_name(plugin);
 e = safe_copy(str, plug.name, sizeof(plug.name), path, "name");
 if(e < 0)return NULL;
 
 
 str = _plug_get_version(plugin);
 e = safe_copy(str, plug.version, sizeof(plug.version), path, "version");
 if(e < 0)return NULL;
 
 
 str = _plug_get_summary(plugin);
 e = safe_copy(str, plug.summary, sizeof(plug.summary), path, "summary");
 if(e < 0)return NULL;
 
 str = _plug_get_description(plugin);
 e = safe_copy(str, plug.description, sizeof(plug.description), path, "description");
 if(e < 0)return NULL;
 
 str = _plug_get_copyright(plugin);
 e = safe_copy(str, plug.copyright, sizeof(plug.copyright), path, "copyright");
 if(e < 0)return NULL;
 
 str = _plug_get_family(plugin);
 e = safe_copy(str, plug.family, sizeof(plug.family), path, "family");
 if(e < 0)return NULL;
 
 str = _plug_get_cve_id(plugin);
 e = safe_copy(str, plug.cve_id, sizeof(plug.cve_id), path, "cve_id");
 if(e < 0)return NULL;
 
 str = _plug_get_bugtraq_id(plugin);
 e = safe_copy(str, plug.bid, sizeof(plug.bid), path, "bugtraq id");
 if(e < 0)return NULL;
 
 str = _plug_get_xref(plugin);
 e = safe_copy(str, plug.xref, sizeof(plug.xref), path, "xref id");
 if(e < 0)return NULL;
 
 arglist = _plug_get_deps(plugin);
 str = arglist2str(arglist);
 e = safe_copy(str, plug.dependencies, sizeof(plug.dependencies), path, "dependencies");
 efree(&str);
 if(e < 0)return NULL;
 
 arglist = _plug_get_required_keys(plugin);
 str = arglist2str(arglist);
 e = safe_copy(str, plug.required_keys, sizeof(plug.required_keys), path, "required keys");
 efree(&str);
 if(e < 0)return NULL;
 
 arglist = _plug_get_excluded_keys(plugin);
 str = arglist2str(arglist);
 e = safe_copy(str, plug.excluded_keys, sizeof(plug.excluded_keys), path, "excluded_keys");
 efree(&str);
 if(e < 0)return NULL;
 
 arglist = _plug_get_required_ports(plugin);
 str = arglist2str(arglist);
 e = safe_copy(str, plug.required_ports, sizeof(plug.required_ports), path, "required ports");
 efree(&str);
 if(e < 0)return NULL;
 
 arglist = _plug_get_required_udp_ports(plugin);
 str = arglist2str(arglist);
 e = safe_copy(str, plug.required_udp_ports, sizeof(plug.required_udp_ports), path, "required udp ports");
 efree(&str);
 if(e < 0)return NULL;
 
 
 prefs = arg_get_value(plugin, "preferences");
 
 
 arglist = arg_get_value(plugin, "PLUGIN_PREFS");
 if( arglist != NULL )
 {
  char * p_name = _plug_get_name(plugin);
  
  while(arglist->next != NULL)
  {
   char * name = arglist->name;
   char * dfl = arglist->value;
   char * type, * str;
   
   type = arglist->name;
   str = strchr(type, '/');
   str[0] = '\0';
   name = str + 1;
   e = safe_copy(type, pp[num_plugin_prefs].type, sizeof(pp[num_plugin_prefs].type), path, "preference-type");
   if(e < 0)return NULL;
   e = safe_copy(name, pp[num_plugin_prefs].name, sizeof(pp[num_plugin_prefs].name), path, "preference-name");
   if(e < 0)return NULL;
   e = safe_copy(dfl, pp[num_plugin_prefs].dfl, sizeof(pp[num_plugin_prefs].dfl), path, "preference-default");
   if(e < 0)return NULL;
   num_plugin_prefs ++;
  
   
   if(num_plugin_prefs >= MAX_PREFS)
   {
    fprintf(stderr, "%s: too many preferences\n", path);
    return NULL;
   }
   _add_plugin_preference(prefs, p_name, name, type, dfl);
   str[0] = '/';
   arglist = arglist->next;
  }
 }
 
 if(num_plugin_prefs > 0)
  plug.has_prefs = 1;
 
 fd = open(desc_file, O_RDWR|O_CREAT|O_TRUNC, 0644);
 if(fd < 0)
 { 
  return NULL;
 }
 
 if(write(fd, &plug, sizeof(plug)) < 0)
 {
  perror("write ");
 }
 
 if(num_plugin_prefs > 0)
 {
  write(fd, pp, sizeof(pp));
 }
 close(fd); 
 
 
 ret = emalloc(sizeof(struct arglist));
 plug_set_id(ret, _plug_get_id(plugin));
 plug_set_category(ret, _plug_get_category(plugin));
 plug_set_fname(ret, file);
 arg_add_value(ret, "preferences", ARG_ARGLIST, -1, arg_get_value(plugin, "preferences"));
 arg_set_value(plugin, "preferences", -1, NULL);
 arg_free_all(plugin);
 return ret;
}
Exemple #16
0
/**
 * @brief Set up some data and jump into attack_host()
 */
static void
attack_start (struct attack_start_args *args)
{
  struct arglist *globals = args->globals;
  char host_str[1024];
  char *mac = args->host_mac_addr;
  struct arglist *plugs = arg_get_value (globals, "plugins");
  struct in6_addr *hostip = &(args->hostip);
  struct arglist *hostinfos;

  struct arglist *preferences = arg_get_value (globals, "preferences");
  char *non_simult = arg_get_value (preferences, "non_simult_ports");
  char *vhosts = arg_get_value (preferences, "vhosts");
  char *vhosts_ip = arg_get_value (preferences, "vhosts_ip");
  int thread_socket = args->thread_socket;
  int soc;
  struct timeval then, now;
  plugins_scheduler_t sched = args->sched;
  int i;

  /* Stringify the IP address. */
  if (IN6_IS_ADDR_V4MAPPED (&args->hostip))
    inet_ntop (AF_INET, ((char *)(&args->hostip))+12, host_str,
               sizeof (host_str));
  else
    inet_ntop (AF_INET6, &args->hostip, host_str,
               sizeof (host_str));


  openvas_signal (SIGUSR1, attack_handle_sigusr1);
  openvas_signal (SIGUSR2, attack_handle_sigusr2);

  thread_socket = dup2 (thread_socket, 4);

  /* Close all file descriptors >= 6 */
  for (i = 6; i < getdtablesize (); i++)
    close (i);

  gettimeofday (&then, NULL);

  if (non_simult == NULL)
    {
      non_simult = estrdup ("139, 445");
      arg_add_value (preferences, "non_simult_ports", ARG_STRING,
                     strlen (non_simult), non_simult);
    }
  arg_add_value (preferences, "non_simult_ports_list", ARG_ARGLIST, -1,
                 (void *) list2arglist (non_simult));

  /* Options regarding the communication with our parent */
  openvas_deregister_connection (GPOINTER_TO_SIZE
                                 (arg_get_value (globals, "global_socket")));
  arg_set_value (globals, "global_socket", -1,
                 GSIZE_TO_POINTER (thread_socket));

  /* Wait for the server to confirm it read our data (prevents client desynch) */
  arg_add_value (globals, "confirm", ARG_INT, sizeof (int), (void *) 1);

  soc = thread_socket;
  if (vhosts == NULL || vhosts_ip == NULL)
    hostinfos = attack_init_hostinfos (mac, host_str, hostip, args->fqdn);
  else
    {
      char *txt_ip;
      struct in_addr inaddr;
      inaddr.s_addr = hostip->s6_addr32[3];

      if (IN6_IS_ADDR_V4MAPPED (hostip))
        txt_ip = estrdup (inet_ntoa (inaddr));
      else
        {
          char name[512];
          txt_ip = estrdup (inet_ntop (AF_INET6, hostip, name, sizeof (name)));
        }
      if (strcmp (vhosts_ip, txt_ip) != 0)
        vhosts = NULL;
      hostinfos = attack_init_hostinfos_vhosts (mac, host_str, hostip, vhosts,
                                                args->fqdn);
    }

  if (mac)
    strcpy (host_str, mac);

  plugins_set_socket (plugs, soc);
  ntp_timestamp_host_scan_starts (globals, host_str);

  // Start scan
  attack_host (globals, hostinfos, host_str, sched);

  // Calculate duration, clean up
  ntp_timestamp_host_scan_ends (globals, host_str);
  gettimeofday (&now, NULL);
  if (now.tv_usec < then.tv_usec)
    {
      then.tv_sec++;
      now.tv_usec += 1000000;
    }

  log_write ("Finished testing %s. Time : %ld.%.2ld secs\n", host_str,
             (long) (now.tv_sec - then.tv_sec),
             (long) ((now.tv_usec - then.tv_usec) / 10000));
  shutdown (soc, 2);
  close (soc);
}
Exemple #17
0
/**
 * @brief Attack a whole network.
 */
void
attack_network (struct arglist *globals)
{
  int max_hosts = 0, max_checks;
  int num_tested = 0;
  char *hostlist;
  openvas_hosts_t *hosts, *hosts_allow, *hosts_deny;
  openvas_hosts_t *sys_hosts_allow, *sys_hosts_deny;
  openvas_host_t *host;
  int global_socket = -1;
  struct arglist *preferences = NULL;
  struct arglist *plugins = NULL;
  plugins_scheduler_t sched;
  int fork_retries = 0;
  GHashTable *files;
  struct timeval then, now;
  char buffer[INET6_ADDRSTRLEN];

  int network_phase = 0;
  gchar *network_targets, *port_range;
  int do_network_scan = 0;
  int scan_stopped;

  gettimeofday (&then, NULL);

  preferences = arg_get_value (globals, "preferences");

  if ((do_network_scan = preferences_get_bool (preferences, "network_scan")) == -1)
    do_network_scan = 0;
  network_targets = arg_get_value (preferences, "network_targets");
  if (network_targets != NULL)
    arg_add_value (globals, "network_targets", ARG_STRING,
                   strlen (network_targets), network_targets);
  if (do_network_scan)
    {
      gchar *network_scan_status = arg_get_value (globals, "network_scan_status");
      if (network_scan_status != NULL)
        if (g_ascii_strcasecmp (network_scan_status, "done") == 0)
          network_phase = 0;
        else
          network_phase = 1;
      else
        {
          arg_add_value (globals, "network_scan_status", ARG_STRING,
                         strlen ("busy"), "busy");
          network_phase = 1;
        }
    }

  num_tested = 0;

  global_socket = GPOINTER_TO_SIZE (arg_get_value (globals, "global_socket"));

  plugins = arg_get_value (globals, "plugins");

  /* Init and check Target List */
  hostlist = arg_get_value (preferences, "TARGET");
  if (hostlist == NULL)
    {
      error_message_to_client (globals, "Missing target hosts", NULL, NULL);
      return;
    }

  /* Verify the port range is a valid one */
  port_range = arg_get_value (preferences, "port_range");
  if (validate_port_range (port_range))
    {
      error_message_to_client (globals, "Invalid port range", NULL, port_range);
      return;
    }

  /* Initialize the attack. */
  sched = plugins_scheduler_init (plugins,
    preferences_get_bool (preferences, "auto_enable_dependencies") == 1 ? 1 : 0,
    network_phase);

  max_hosts = get_max_hosts_number (preferences);
  max_checks = get_max_checks_number (preferences);

  if (network_phase)
    {
      network_targets = arg_get_value (preferences, "network_targets");
      if (network_targets == NULL)
        {
          log_write ("WARNING: In network phase, but without targets! Stopping.\n");
          host = NULL;
        }
      else
        {
          log_write
            ("Start a new scan. Target(s) : %s, in network phase with target %s\n",
             hostlist, network_targets);
        }
    }
  else
    {
      log_write ("Starts a new scan. Target(s) : %s, with max_hosts = %d and"
                 " max_checks = %d\n", hostlist, max_hosts, max_checks);
    }

  hosts = openvas_hosts_new (hostlist);
  /* Apply Hosts preferences. */
  apply_hosts_preferences (hosts, preferences);

  /* Don't start if the provided interface is unauthorized. */
  if (apply_source_iface_preference (globals, preferences) != 0)
    {
      openvas_hosts_free (hosts);
      error_message_to_client (globals, "Interface not authorized for scanning", NULL, NULL);
      return;
    }
  /* hosts_allow/deny lists. */
  hosts_allow = openvas_hosts_new (preferences_get_string
                                    (preferences, "hosts_allow"));
  hosts_deny = openvas_hosts_new (preferences_get_string
                                   (preferences, "hosts_deny"));
  /* sys_* preferences, which can't be overriden by the client. */
  sys_hosts_allow = openvas_hosts_new (preferences_get_string
                                        (preferences, "sys_hosts_allow"));
  sys_hosts_deny = openvas_hosts_new (preferences_get_string
                                       (preferences, "sys_hosts_deny"));
  host = openvas_hosts_next (hosts);
  if (host == NULL)
    goto stop;
  hosts_init (global_socket, max_hosts);
  /*
   * Start the attack !
   */
  while (host)
    {
      int pid;
      char *hostname;
      struct in6_addr host_ip;

      hostname = openvas_host_value_str (host);
      if (openvas_host_get_addr6 (host, &host_ip) == -1)
        {
          log_write ("Couldn't resolve target %s\n", hostname);
          error_message_to_client (globals, "Couldn't resolve hostname.",
                                   hostname, NULL);
          g_free (hostname);
          host = openvas_hosts_next (hosts);
          continue;
        }

      /* Do we have the right to test this host ? */
      if (!host_authorized (host, &host_ip, hosts_allow, hosts_deny))
        {
          error_message_to_client (globals, "Host access denied.",
                                   hostname, NULL);
          log_write ("Host %s access denied.", hostname);
        }
      else if (!host_authorized (host, &host_ip, sys_hosts_allow,
                                 sys_hosts_deny))
        {
          error_message_to_client (globals, "Host access denied"
                                            " (system-wide restriction.)",
                                   hostname, NULL);
          log_write ("Host %s access denied (sys_* preference restriction.)",
                     hostname);
        }
      else
        {
          struct attack_start_args args;
          int s;
          char *MAC = NULL;
          int mac_err = -1;
          gchar *name;

          if (preferences_get_bool (preferences, "use_mac_addr") > 0
              && v6_is_local_ip (&host_ip))
            {
              mac_err = v6_get_mac_addr (&host_ip, &MAC);
              if (mac_err > 0)
                {
                  /* remote host is down */
                  g_free (hostname);
                  host = openvas_hosts_next (hosts);
                  continue;
                }
            }

          s = hosts_new (globals, hostname);
          if (s < 0)
            goto scan_stop;

          args.globals = globals;
          memcpy (&args.hostip, &host_ip, sizeof (struct in6_addr));
          name = openvas_host_value_str (host);
          strncpy (args.fqdn, name, sizeof (args.fqdn));
          g_free (name);
          args.host_mac_addr = MAC;
          args.sched = sched;
          args.thread_socket = s;

        forkagain:
          pid = create_process ((process_func_t) attack_start, &args);
          if (pid < 0)
            {
              fork_retries++;
              if (fork_retries > MAX_FORK_RETRIES)
                {
                  /* Forking failed - we go to the wait queue. */
                  log_write ("fork() failed - %s. %s won't be tested\n",
                             strerror (errno), hostname);
                  efree (&MAC);
                  goto stop;
                }

              log_write
                ("fork() failed - sleeping %d seconds and trying again...\n",
                 fork_retries);
              fork_sleep (fork_retries);
              goto forkagain;
            }

          hosts_set_pid (hostname, pid);
          if (network_phase)
            log_write ("Testing %s (network level) [%d]\n",
                       network_targets, pid);
          else
            log_write ("Testing %s (%s) [%d]\n",
                       hostname, inet_ntop (AF_INET6,
                                            &args.hostip,
                                            buffer,
                                            sizeof (buffer)),
                       pid);
          if (MAC != NULL)
            efree (&MAC);
        }

      num_tested++;

      if (network_phase)
        {
          host = NULL;
          arg_set_value (globals, "network_scan_status", strlen ("done"), "done");
        }
      else
        {
          g_free (hostname);
          host = openvas_hosts_next (hosts);
        }
    }

  /* Every host is being tested... We have to wait for the processes
   * to terminate. */
  while (hosts_read (globals) == 0)
    ;

  log_write ("Test complete");

scan_stop:
  /* Free the memory used by the files uploaded by the user, if any. */
  files = arg_get_value (globals, "files_translation");
  if (files)
    g_hash_table_foreach_remove (files, (GHRFunc) free_uploaded_file, NULL);

stop:
  scan_stopped = GPOINTER_TO_SIZE(arg_get_value (globals, "stop_required"));

  openvas_hosts_free (hosts);
  openvas_hosts_free (hosts_allow);
  openvas_hosts_free (hosts_deny);
  openvas_hosts_free (sys_hosts_allow);
  openvas_hosts_free (sys_hosts_deny);

  plugins_scheduler_free (sched);

  gettimeofday (&now, NULL);
  log_write ("Total time to scan all hosts : %ld seconds\n",
             now.tv_sec - then.tv_sec);

  if (do_network_scan && network_phase && !scan_stopped)
    attack_network (globals);

  return;
}
/**
 * @brief openvassd.
 * @param argc Argument count.
 * @param argv Argument vector.
 */
int
main (int argc, char *argv[])
{
  int exit_early = 0, scanner_port = 9391;
  pid_t handler_pid;
  char *myself;
  struct arglist *options = emalloc (sizeof (struct arglist));
  struct addrinfo *mysaddr;
  struct addrinfo hints;
  struct addrinfo ai;
  struct sockaddr_in saddr;
  struct sockaddr_in6 s6addr;

  proctitle_init (argc, argv);
  gcrypt_init ();

  if ((myself = strrchr (*argv, '/')) == 0)
    myself = *argv;
  else
    myself++;

  static gboolean display_version = FALSE;
  static gboolean dont_fork = FALSE;
  static gchar *address = NULL;
  static gchar *port = NULL;
  static gchar *config_file = NULL;
  static gchar *gnutls_priorities = "NORMAL";
  static gchar *dh_params = NULL;
  static gboolean print_specs = FALSE;
  static gboolean print_sysconfdir = FALSE;
  static gboolean only_cache = FALSE;
  GError *error = NULL;
  GOptionContext *option_context;
  static GOptionEntry entries[] = {
    {"version", 'V', 0, G_OPTION_ARG_NONE, &display_version,
     "Display version information", NULL},
    {"foreground", 'f', 0, G_OPTION_ARG_NONE, &dont_fork,
     "Do not run in daemon mode but stay in foreground", NULL},
    {"listen", 'a', 0, G_OPTION_ARG_STRING, &address,
     "Listen on <address>", "<address>"},
    {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
     "Use port number <number>", "<number>"},
    {"config-file", 'c', 0, G_OPTION_ARG_FILENAME, &config_file,
     "Configuration file", "<.rcfile>"},
    {"cfg-specs", 's', 0, G_OPTION_ARG_NONE, &print_specs,
     "Print configuration settings", NULL},
    {"sysconfdir", 'y', 0, G_OPTION_ARG_NONE, &print_sysconfdir,
     "Print system configuration directory (set at compile time)", NULL},
    {"only-cache", 'C', 0, G_OPTION_ARG_NONE, &only_cache,
     "Exit once the NVT cache has been initialized or updated", NULL},
    {"gnutls-priorities", '\0', 0, G_OPTION_ARG_STRING, &gnutls_priorities,
     "GnuTLS priorities string", "<string>"},
    {"dh-params", '\0', 0, G_OPTION_ARG_STRING, &dh_params,
     "Diffie-Hellman parameters file", "<string>"},
    {NULL}
  };

  option_context =
    g_option_context_new ("- Scanner of the Open Vulnerability Assessment System");
  g_option_context_add_main_entries (option_context, entries, NULL);
  if (!g_option_context_parse (option_context, &argc, &argv, &error))
    {
      g_print ("%s\n\n", error->message);
      exit (0);
    }
  g_option_context_free (option_context);

  if (print_sysconfdir)
    {
      g_print ("%s\n", SYSCONFDIR);
      exit (0);
    }

  /* Switch to UTC so that OTP times are always in UTC. */
  if (setenv ("TZ", "utc 0", 1) == -1)
    {
      g_print ("%s\n\n", strerror (errno));
      exit (0);
    }
  tzset ();

  if (print_specs)
    exit_early = 2;           /* no cipher initialization */

  if (address != NULL)
    {
      memset (&hints, 0, sizeof (hints));
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
      hints.ai_flags = AI_NUMERICHOST;
      if (getaddrinfo (address, NULL, &hints, &mysaddr))
        {
          printf ("Invalid IP address.\n");
          printf ("Please use %s --help for more information.\n", myself);
          exit (0);
        }
      /* deep copy */
      ai.ai_family = mysaddr->ai_family;
      if (ai.ai_family == AF_INET)
        {
          memcpy (&saddr, mysaddr->ai_addr, mysaddr->ai_addrlen);
          ai.ai_addr = (struct sockaddr *) &saddr;
        }
      else
        {
          memcpy (&s6addr, mysaddr->ai_addr, mysaddr->ai_addrlen);
          ai.ai_addr = (struct sockaddr *) &s6addr;
        }
      ai.ai_family = mysaddr->ai_family;
      ai.ai_protocol = mysaddr->ai_protocol;
      ai.ai_socktype = mysaddr->ai_socktype;
      ai.ai_addrlen = mysaddr->ai_addrlen;
      freeaddrinfo (mysaddr);
    }
  else
    {
      /* Default to IPv4 */
      /*Warning: Not filling all the fields */
      saddr.sin_addr.s_addr = INADDR_ANY;
      saddr.sin_family = ai.ai_family = AF_INET;
      ai.ai_addrlen = sizeof (saddr);
      ai.ai_addr = (struct sockaddr *) &saddr;
    }

  if (port != NULL)
    {
      scanner_port = atoi (port);
      if ((scanner_port <= 0) || (scanner_port >= 65536))
        {
          printf ("Invalid port specification.\n");
          printf ("Please use %s --help for more information.\n", myself);
          exit (1);
        }
    }

  if (display_version)
    {
      printf ("OpenVAS Scanner %s\n", OPENVASSD_VERSION);
      printf
        ("Nessus origin: (C) 2004 Renaud Deraison <*****@*****.**>\n");
      printf
        ("Most new code since OpenVAS: (C) 2013 Greenbone Networks GmbH\n");
      printf ("License GPLv2: GNU GPL version 2\n");
      printf
        ("This is free software: you are free to change and redistribute it.\n"
         "There is NO WARRANTY, to the extent permitted by law.\n\n");
      exit (0);
    }

  if (config_file != NULL)
    arg_add_value (options, "acc_hint", ARG_INT, sizeof (int), (void *) 1);

  if (!config_file)
    {
      config_file = emalloc (strlen (OPENVASSD_CONF) + 1);
      strncpy (config_file, OPENVASSD_CONF, strlen (OPENVASSD_CONF));
    }

  arg_add_value (options, "scanner_port", ARG_INT, sizeof (gpointer),
                 GSIZE_TO_POINTER (scanner_port));
  arg_add_value (options, "config_file", ARG_STRING, strlen (config_file),
                 config_file);
  arg_add_value (options, "addr", ARG_PTR, -1, &ai);

  if (only_cache)
    {
      init_openvassd (options, 0, 1, dont_fork);
      init_plugins (options);
      exit (0);
    }

  init_openvassd (options, 1, exit_early, dont_fork);
  g_options = options;
  global_iana_socket = GPOINTER_TO_SIZE (arg_get_value (options, "isck"));
  global_plugins = arg_get_value (options, "plugins");

  /* special treatment */
  if (print_specs)
    dump_cfg_specs (global_preferences);
  if (exit_early)
    exit (0);

  init_ssl_ctx (gnutls_priorities, dh_params);
  // Daemon mode:
  if (dont_fork == FALSE)
    set_daemon_mode ();
  pidfile_create ("openvassd");
  handler_pid = loading_handler_start ();
  init_plugins (options);
  loading_handler_stop (handler_pid);
  main_loop ();
  exit (0);
}
Exemple #19
0
struct arglist * store_load_plugin(char * dir, char * file,  struct arglist * prefs)
{
 char desc_file[PATH_MAX+1];
 char plug_file[PATH_MAX+1];
 char * str;
 char store_dir[PATH_MAX+1];
 struct plugin p;
 struct pprefs pp[MAX_PREFS];
 
 struct arglist * ret;
 int i;
 struct stat st1, st2;
 struct arglist * al;
 
 bzero(pp, sizeof(pp));
 
 snprintf(desc_file, sizeof(desc_file), "%s/.desc/%s", dir, file);
 str = strrchr(desc_file, '.');
 if( str != NULL )
 {
  str[0] = '\0';
  if(	strlen(desc_file) + 6 < sizeof(desc_file) )
  	strcat(desc_file, ".desc");

 }
 snprintf(plug_file, sizeof(plug_file), "%s/%s", dir, file);

 if (  stat(plug_file, &st1) < 0 || 
       stat(desc_file, &st2) < 0 ) 
		return NULL;

 /* 
  * Look if the plugin is newer, and if that's the case also make sure that
  * the plugin mtime is not in the future...
  */
 if ( st1.st_mtime > st2.st_mtime && st1.st_mtime <= time(NULL) )
	return NULL;
	
 snprintf(store_dir, sizeof(store_dir), "%s/.desc", dir);
 if(store_get_plugin_f(&p, pp, store_dir, file) < 0)
  return NULL;
  
 if(p.magic != MAGIC)
 	return NULL;
	
	
 if(p.id <= 0) return NULL;
    
 ret = emalloc(sizeof(struct arglist));   
 plug_set_id(ret, p.id);
 plug_set_category(ret, p.category);
 plug_set_fname(ret, file);
 plug_set_path(ret, p.path);
 plug_set_family(ret, p.family, NULL);

  al = str2arglist(p.required_ports);
 if ( al != NULL ) arg_add_value(ret, "required_ports", ARG_ARGLIST, -1, al);

 al = str2arglist(p.required_keys);
 if ( al != NULL ) arg_add_value(ret, "required_keys", ARG_ARGLIST, -1, al);

 al = str2arglist(p.required_udp_ports);
 if ( al != NULL ) arg_add_value(ret, "required_udp_ports", ARG_ARGLIST, -1, al)
;

 al = str2arglist(p.excluded_keys);
 if ( al != NULL ) arg_add_value(ret, "excluded_keys", ARG_ARGLIST, -1, al);

 al = str2arglist(p.dependencies);
 if ( al != NULL ) arg_add_value(ret, "DEPENDENCIES", ARG_ARGLIST, -1, al);

 
 if ( p.timeout != 0 ) arg_add_value(ret, "TIMEOUT", ARG_INT, -1, (void*)p.timeout);

 arg_add_value(ret, "NAME", ARG_STRING, strlen(p.name), estrdup(p.name));


 arg_add_value(ret, "preferences", ARG_ARGLIST, -1, prefs);
 
 if(p.has_prefs)
 {
 for(i=0;pp[i].type[0] != '\0';i++)
  { 
   _add_plugin_preference(prefs, p.name, pp[i].name, pp[i].type, pp[i].dfl);
  }
 }

 return ret;
}
Exemple #20
0
/**
 * @brief Inits or loads the knowledge base for a single host.
 *
 * Fills the knowledge base with host-specific login information for local
 * checks if defined.
 *
 * @param globals     Global preference arglist.
 * @param hostname    Name of the host.
 * @param new_kb[out] TRUE if the kb is new and shall be saved.
 *
 * @return A knowledge base.
 *
 * @see fill_host_kb_ssh_credentials
 */
static kb_t
init_host_kb (struct arglist *globals, char *hostname,
              struct arglist *hostinfos, gboolean * new_kb)
{
  kb_t kb, network_kb;
  (*new_kb) = FALSE;
  gchar *vhosts;
  struct kb_item *host_network_results = NULL;
  struct kb_item *result_iter;

  gchar *network_scan_status = (gchar *) arg_get_value (globals, "network_scan_status");
  if (network_scan_status != NULL)
    {
      if (g_ascii_strcasecmp (network_scan_status, "done") == 0)
        {
          gchar *hostname_pattern = g_strdup_printf ("%s/*", hostname);
          network_kb = save_kb_load_kb (globals, "network");
          host_network_results = kb_item_get_pattern (network_kb, hostname_pattern);
        }
      if (g_ascii_strcasecmp (network_scan_status, "busy") == 0)
        {
          arg_add_value (globals, "CURRENTLY_TESTED_HOST", ARG_STRING,
                         strlen ("network"), "network");
          save_kb_new (globals, "network");
          kb = kb_new ();
          (*new_kb) = TRUE;
          return kb;
        }
    }

  // Check if kb should be saved.
  if (save_kb (globals))
    {
      // Check if a saved kb exists and we shall restore it.
      if (save_kb_exists (hostname) != 0)
        {
          save_kb_backup (hostname);
          kb = save_kb_load_kb (globals, hostname);
        }
      else
        {
          // We shall not or cannot restore.
          save_kb_new (globals, hostname);
          kb = kb_new ();
          (*new_kb) = TRUE;
        }
 
      arg_add_value (globals, "CURRENTLY_TESTED_HOST", ARG_STRING,
                     strlen (hostname), hostname);
    }
  else                          /* save_kb(globals) */
    {
      kb = kb_new ();
    }

  /* Add local check (SSH)- related knowledge base items. */
  fill_host_kb_ssh_credentials (kb, globals, hostname);

  /* If vhosts is set, split it and put it in the KB. */
  vhosts = (gchar *)arg_get_value (hostinfos, "VHOSTS");
  if (vhosts)
    {
      gchar **vhosts_array = g_strsplit (vhosts, ",", 0);
      guint i = 0;
      while (vhosts_array[i] != NULL)
        {
          kb_item_add_str (kb, "hostinfos/vhosts", vhosts_array[i]);
          save_kb_write_str (globals, hostname, "hostinfos/vhosts", vhosts_array[i]);
          i++;
        }
      g_strfreev (vhosts_array);
    }

  result_iter = host_network_results;
  while (result_iter != NULL)
    {
      char *newname = strstr (result_iter->name, "/") + 1;
      if (result_iter->type == KB_TYPE_STR)
        {
          kb_item_add_str (kb, newname, result_iter->v.v_str);
          save_kb_write_str (globals, hostname, newname, result_iter->v.v_str);
        }
      else if (result_iter->type == KB_TYPE_INT)
        {
          kb_item_add_int (kb, newname, result_iter->v.v_int);
          save_kb_write_int (globals, hostname, newname, result_iter->v.v_int);
        }
      result_iter = result_iter->next;
    }

  return kb;
}
Exemple #21
0
int
execute_nasl_script(struct arglist * script_infos, const char* name, const char * cache_dir, int mode)
{
  naslctxt	ctx;
  nasl_func	*pf;
  int		err = 0;
  tree_cell	*ret;
  lex_ctxt	*lexic;
  char 	 	old_dir[MAXPATHLEN+1];
  char		*newdir;
  char		*old;
  tree_cell	tc;
  struct arglist*	prefs = arg_get_value(script_infos, "preferences");
  char		*str;
  int		to;
  char * basename;

#ifdef ENABLE_PLUGIN_SERVER
  char * cached_script = NULL;
  unsigned int cached_script_len = 0;
#endif
  
  srand48(getpid() + getppid() + (long)time(NULL));

  old_dir[sizeof(old_dir) - 1] = '\0';
  getcwd(old_dir, sizeof(old_dir) - 1);
#if NASL_DEBUG > 2
  nasl_trace_fp = stderr;
#endif
 if((old = arg_get_value(script_infos, "script_name")) == NULL)
   arg_add_value(script_infos, "script_name", ARG_STRING, strlen(name), estrdup(name));
 else
   { 
   efree(&old);
   arg_set_value(script_infos, "script_name", strlen(name), estrdup(name));
  }
 
 newdir = strrchr(name, '/');
 if(newdir != NULL)
 {
	 char dir[MAXPATHLEN+1];
	 char *s;
	 dir[sizeof(dir) - 1] = '\0';
	 strncpy(dir, name, sizeof(dir) - 1);
	 s = strrchr(dir, '/');
	 s[0] = '\0';
	 chdir(dir);
	 basename = newdir + 1;
 }
 else basename = (char*)name;

 bzero(&ctx, sizeof(ctx));
 if ( mode & NASL_ALWAYS_SIGNED )
	ctx.always_authenticated = 1;

 
#ifdef ENABLE_PLUGIN_SERVER
 if (  nasl_index_fetch(basename, &cached_script, &cached_script_len) >= 0 )
 {
  if ( nasl_load_parsed_tree_buf(&ctx, cached_script, cached_script_len, basename) < 0 )  
  {
   printf("Could not load plugin\n");
   efree(&cached_script);
   chdir(old_dir);
   return -1;
  }
  efree(&cached_script);
 }
 else
#endif
 {
 if (nasl_load_or_parse(&ctx, name, basename, cache_dir) < 0 )
  {
    chdir(old_dir);
    return -1;
  }
 }


#if NASL_DEBUG > 4
 nasl_dump_tree(ctx.tree);
#endif
 lexic = init_empty_lex_ctxt();
 lexic->script_infos = script_infos;

 if ( mode & NASL_ALWAYS_SIGNED )
 	lexic->authenticated = 1;
 else
 	lexic->authenticated = ctx.authenticated;
 
 str = arg_get_value(prefs, "checks_read_timeout");
 if( str != NULL )
 	to = atoi(str);
 else
 	to = 5;
	
 if(to <= 0)to = 5;
 
 lexic->recv_timeout = to;

 init_nasl_library(lexic);

 if (mode & NASL_LINT)
   {
     if (nasl_lint(lexic, ctx.tree) == NULL)
       err --;
   }
 else
 if (! (mode & NASL_EXEC_PARSE_ONLY))
   {
     char	*p;

     bzero(&tc, sizeof(tc));
     tc.type = CONST_INT;
     tc.x.i_val = (mode & NASL_COMMAND_LINE) != 0;
     add_named_var_to_ctxt(lexic, "COMMAND_LINE", &tc);

     bzero(&tc, sizeof(tc));
     tc.type = CONST_INT;
     tc.x.i_val = (mode & NASL_EXEC_DESCR) != 0;
     add_named_var_to_ctxt(lexic, "description", &tc);

     tc.type = CONST_DATA;
     p = strrchr(name, '/');
     if (p == NULL) p = (char*)name; else p ++;
     tc.x.str_val = p;
     tc.size = strlen(p);
     add_named_var_to_ctxt(lexic, "SCRIPT_NAME", &tc);

     truc = (lex_ctxt*)ctx.tree;
     if ((ret = nasl_exec(lexic, ctx.tree)) == NULL)
       err = -1;
     else
       deref_cell(ret);

     if ((pf = get_func_ref_by_name(lexic, "on_exit")) != NULL)
       nasl_func_call(lexic, pf, NULL);
   }

#if NASL_DEBUG > 2
 {
   struct rusage	ru;

   if (getrusage(RUSAGE_SELF, &ru) < 0)
     perror("getrusage");
   else
     {
       nasl_perror(lexic, 
		   "rusage: utime=%d.%03d stime=%d.%03d minflt=%d majflt=%d nswap=%d\n",
		   ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 1000,
		   ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 1000,
		   ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
     }
 }
#endif

#if NASL_DEBUG > 3
 nasl_dump_tree(ctx.tree);
#endif

 chdir(old_dir);
 if ( mode & NASL_EXEC_DONT_CLEANUP ) return err;

 nasl_clean_ctx(&ctx);
 free_lex_ctxt(lexic);


 return err;
}