static void update_progress_bar() { #ifdef FAKE_PROGRESS_BAR int total = 100000; int remaining = total - progress_bar_level; int addme = 0; addme = (5*100*remaining)/total; progress_bar_level += addme; comm_send_status(Globals, arg_get_value(Hostinfos, "NAME"), "portscan", progress_bar_level, total); signal(SIGALRM, update_progress_bar); /* * Update the alarm time */ alarm((progress_bar_level/(total))+4); #else fprintf(stderr, "T =%d/%d\tU=%d/%d\n", scanned_tcp_ports, total_tcp_ports, scanned_udp_ports, total_udp_ports); comm_send_status(Globals, arg_get_value(Hostinfos, "NAME"), "portscan", scanned_tcp_ports + scanned_udp_ports, total_tcp_ports + total_udp_ports); #endif }
tree_cell * nasl_scanner_status(lex_ctxt * lexic) { int current = get_int_local_var_by_name(lexic, "current", -1); int total = get_int_local_var_by_name(lexic, "total", -1); struct arglist * script_infos = lexic->script_infos; struct arglist * hostdata = arg_get_value(script_infos, "HOSTNAME"); if(current != -1 && total != -1) { struct arglist * globs = arg_get_value(script_infos, "globals"); if (globs == NULL) return NULL; comm_send_status(globs, arg_get_value(hostdata, "NAME"), "portscan", current, total); } return FAKE_CELL; }
/** * @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); }
/** * @brief Launches a nvt. Respects safe check preference (i.e. does not try * @brief destructive nvt if save_checks is yes). * * Does not launch a plugin twice if !save_kb_replay. * * @param new_kb If TRUE, kb is new and shall be saved. * * @return ERR_HOST_DEAD if host died, ERR_CANT_FORK if forking failed, * 0 otherwise. */ static int launch_plugin (struct arglist *globals, plugins_scheduler_t * sched, struct scheduler_plugin *plugin, char *hostname, int *cur_plug, int num_plugs, struct arglist *hostinfos, kb_t kb, gboolean new_kb) { struct arglist *preferences = arg_get_value (globals, "preferences"); struct arglist *args = plugin->arglist->value; nvticache_t *nvticache = (nvticache_t *)arg_get_value ( arg_get_value (args, "preferences"), "nvticache"); char name[1024], oid_[100], *oid, *src; int optimize = preferences_optimize_test (preferences); int category = plugin->category; gchar *network_scan_status; gboolean network_scan = FALSE; oid = arg_get_value (args, "OID"); if (oid) src = nvticache_get_src_by_oid (nvticache, oid); else return 0; strncpy (name, src, sizeof (name) - 1); name[sizeof (name) - 1] = '\0'; g_free (src); // we need the oid later on and have many exits, so better // store it locally without need to free it. strncpy (oid_, oid, sizeof (oid_) - 1); oid_[sizeof (oid_) - 1] = '\0'; network_scan_status = arg_get_value (globals, "network_scan_status"); if (network_scan_status != NULL) if (g_ascii_strcasecmp (network_scan_status, "busy") == 0) network_scan = TRUE; if (plug_get_launch (args) != LAUNCH_DISABLED || category == ACT_SETTINGS) /* can we launch it ? */ { char *error; static int last_status = 0; if (preferences_safe_checks_enabled (preferences) && (category == ACT_DESTRUCTIVE_ATTACK || category == ACT_KILL_HOST || category == ACT_FLOOD || category == ACT_DENIAL)) { if (preferences_log_whole_attack (preferences)) log_write ("Not launching %s against %s %s (this is not an error)\n", plugin->arglist->name, hostname, "because safe checks are enabled"); plugin_set_running_state (plugin, PLUGIN_STATUS_DONE); return 0; } (*cur_plug)++; if ((*cur_plug * 100) / num_plugs >= last_status) { last_status = (*cur_plug * 100) / num_plugs + 2; if (comm_send_status (globals, hostname, "attack", *cur_plug, num_plugs) < 0) { /* Could not send our status back to our father -> exit */ pluginlaunch_stop (); return ERR_HOST_DEAD; } } if (network_scan) { char asc_id[100]; snprintf (asc_id, sizeof (asc_id), "Launched/%s", oid); if (kb_item_get_int (kb, asc_id) > 0) { if (preferences_log_whole_attack (preferences)) log_write ("Not launching %s against %s %s (this is not an error)\n", plugin->arglist->name, hostname, "because it has already been launched in the past"); plugin_set_running_state (plugin, PLUGIN_STATUS_DONE); return 0; } else { kb_item_add_int (kb, asc_id, 1); save_kb_write_int (globals, "network", asc_id, 1); } } /* Do not launch NVT if mandatory key is missing (e.g. an important tool * was not found). This is ignored during network wide scanning phases. */ if (network_scan || mandatory_requirements_met (kb, plugin)) error = NULL; else error = "because a mandatory key is missing"; if (!error && (!optimize || !(error = requirements_plugin (kb, plugin, preferences)))) { int pid; /* Start the plugin */ pid = plugin_launch (globals, sched, plugin, hostinfos, preferences, kb, name); if (pid < 0) { plugin_set_running_state (plugin, PLUGIN_STATUS_UNRUN); return ERR_CANT_FORK; } if (preferences_log_whole_attack (preferences)) log_write ("Launching %s against %s [%d]\n", plugin->arglist->name, hostname, pid); /* Stop the test if the host is 'dead' */ if (kb_item_get_int (kb, "Host/dead") > 0 || kb_item_get_int (kb, "Host/ping_failed") > 0) { log_write ("The remote host (%s) is dead\n", hostname); pluginlaunch_stop (); if (new_kb == TRUE) save_kb_close (globals, hostname); if (kb_item_get_int (kb, "Host/ping_failed") > 0) save_kb_restore_backup (hostname); plugin_set_running_state (plugin, PLUGIN_STATUS_DONE); return ERR_HOST_DEAD; } } else /* requirements_plugin() failed */ { plugin_set_running_state (plugin, PLUGIN_STATUS_DONE); if (preferences_log_whole_attack (preferences)) log_write ("Not launching %s against %s %s (this is not an error)\n", plugin->arglist->name, hostname, error); } } /* if(plugins->launch) */ else plugin_set_running_state (plugin, PLUGIN_STATUS_DONE); return 0; }