Ejemplo n.º 1
0
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);
}
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);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: store.c Proyecto: OPSF/uClinux
struct arglist * store_plugin(struct arglist * plugin, char * file)
{
 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;

 
 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);
#ifdef DEBUG_STORE
 if ( str != NULL && strlen(str) > OLD_CVE_SZ )
	fprintf(stderr, "WARNING! CVE size will be too long for older versions of Nessus!\n");
#endif
	
 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);
#ifdef DEBUG_STORE
 if ( str != NULL && strlen(str) > OLD_BID_SZ)
	fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n");
#endif
 e = safe_copy(str, plug.bid, sizeof(plug.bid), path, "bugtraq id");
 if(e < 0)return NULL;
 
 str = _plug_get_xref(plugin);
#ifdef DEBUG_STORE
 if ( str != NULL && strlen(str) > OLD_XREF_SZ)
	fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n");
#endif
 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); 
 
 

 arg_set_value(plugin, "preferences", -1, NULL);
 arg_free_all(plugin);
 return NULL;
}
Ejemplo n.º 5
0
Archivo: exec.c Proyecto: OPSF/uClinux
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
static void
scanner_thread (struct arglist *globals)
{
  struct arglist *prefs = arg_get_value (globals, "preferences");
  char asciiaddr[INET6_ADDRSTRLEN], x509_dname[512] = { '\0' };
  int opt = 1, soc2 = -1, nice_retval, family, soc;
  void *addr = arg_get_value (globals, "client_address");
  struct sockaddr_in *saddr = NULL;
  struct sockaddr_in6 *s6addr = NULL;

  family = GPOINTER_TO_SIZE (arg_get_value (globals, "family"));
  soc = GPOINTER_TO_SIZE (arg_get_value (globals, "global_socket"));
  if (family == AF_INET)
    {
      saddr = (struct sockaddr_in *) addr;
      inet_ntop (AF_INET,  &saddr->sin_addr, asciiaddr, sizeof(asciiaddr));
    }
  else
    {
      s6addr = (struct sockaddr_in6 *) addr;
      inet_ntop (AF_INET6, &s6addr->sin6_addr, asciiaddr, sizeof (asciiaddr));
    }
  proctitle_set ("openvassd: Serving %s", asciiaddr);

  /* Everyone runs with a nicelevel of 10 */
  if (preferences_benice (prefs))
    {
      errno = 0;
      nice_retval = nice (10);
      if (nice_retval == -1 && errno != 0)
        {
          log_write ("Unable to renice process: %d", errno);
        }
    }

  /* Close the scanner thread - it is useless for us now */
  close (global_iana_socket);

  soc2 = ovas_scanner_context_attach (ovas_scanner_ctx, soc);
  if (soc2 < 0)
    goto shutdown_and_exit;

  /* FIXME: The pre-gnutls code optionally printed information about
   * the peer's certificate at this point.
   */

  setsockopt (soc, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof (opt));
  /* arg_set_value *replaces* an existing value, but it shouldn't fail here */
  (void) arg_set_value (globals, "global_socket", -1, GSIZE_TO_POINTER (soc2));

  if (comm_init (soc2) < 0)
    {
      close_stream_connection (soc);
      exit (0);
    }

  /* Get X.509 cert subject name */
  if (get_x509_dname (soc2, x509_dname, sizeof (x509_dname)) != 0)
    goto shutdown_and_exit;

  if (!check_client (x509_dname))
    {
      auth_printf (globals, "Bad login attempt !\n");
      log_write ("bad login attempt from %s\n", asciiaddr);
      goto shutdown_and_exit;
    }
  handle_client (globals);

shutdown_and_exit:
  if (soc2 >= 0)
    close_stream_connection (soc2);
  else
    {
      shutdown (soc, 2);
      close (soc);
    }

  /* Kill left overs */
  end_daemon_mode ();
  exit (0);
}