Attack a whole network. return 0 on successes, -1 if there was a critical error.
1169{
1170 int max_hosts = 0, max_checks;
1171 const char *hostlist;
1174 int fork_retries = 0;
1177 const gchar *port_range;
1178 int allow_simultaneous_ips;
1180 GSList *unresolved;
1181 char buf[96];
1182 int error = 0;
1183
1185
1186 gboolean test_alive_hosts_only = prefs_get_bool ("test_alive_hosts_only");
1187 gvm_hosts_t *alive_hosts_list = NULL;
1188 kb_t alive_hosts_kb = NULL;
1189 if (test_alive_hosts_only)
1191
1192 gettimeofday (&then, NULL);
1193
1195 {
1196 error = -1;
1197 return error;
1198 }
1199
1200 hostlist = prefs_get ("TARGET");
1201 if (hostlist == NULL)
1202 {
1203 error = -1;
1204 return error;
1205 }
1206
1207
1208 port_range = prefs_get ("port_range");
1209 if (validate_port_range (port_range))
1210 {
1213 main_kb,
"Invalid port list. Ports must be in the range [1-65535]",
1214 NULL, NULL, "ERRMSG");
1216 g_warning ("Invalid port list. Ports must be in the range [1-65535]. "
1217 "Scan terminated.");
1219
1220 error = -1;
1221 return error;
1222 }
1223
1224
1225 int plugins_init_error = 0;
1227 prefs_get_bool ("auto_enable_dependencies"),
1228 &plugins_init_error);
1229 if (!sched)
1230 {
1231 g_message ("Couldn't initialize the plugin scheduler");
1232
1233 error = -1;
1234 return error;
1235 }
1236
1237 if (plugins_init_error > 0)
1238 {
1239 sprintf (buf,
1240 "%d errors were found during the plugin scheduling. "
1241 "Some plugins have not been launched.",
1242 plugins_init_error);
1243
1247 }
1248
1251
1252 hosts = gvm_hosts_new (hostlist);
1254 {
1255 char *buffer;
1256 buffer = g_strdup_printf ("Invalid target list: %s.", hostlist);
1259 g_free (buffer);
1260
1261
1263 "HOSTS_COUNT");
1265 g_warning ("Invalid target list. Scan terminated.");
1266
1267 error = -1;
1268 goto stop;
1269 }
1270
1271 unresolved = gvm_hosts_resolve (
hosts);
1272 while (unresolved)
1273 {
1274 g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
1275 unresolved = unresolved->next;
1276 }
1277 g_slist_free_full (unresolved, g_free);
1278
1279
1281
1282 int already_excluded = 0;
1284
1285#ifdef FEATURE_HOSTS_ALLOWED_ONLY
1286
1287
1288
1289 apply_hosts_allow_deny (
hosts);
1290#endif
1291
1292
1294
1295
1296
1297 sprintf (buf, "%d", exc + already_excluded);
1301
1302
1303
1304 sprintf (buf,
"%d", gvm_hosts_count (
hosts));
1308
1311 goto stop;
1312
1314
1315 g_message ("Vulnerability scan %s started: Target has %d hosts: "
1316 "%s, with max_hosts = %d and max_checks = %d",
1317 globals->
scan_id, gvm_hosts_count (
hosts), hostlist, max_hosts,
1318 max_checks);
1319
1320 if (test_alive_hosts_only)
1321 {
1322
1323 gboolean ad_finished = FALSE;
1324 int err;
1325 pthread_t tid;
1326 struct in6_addr tmpaddr;
1327
1328
1330 err = pthread_create (&tid, NULL, start_alive_detection, (
void *)
hosts);
1331 if (err == EAGAIN)
1332 g_warning (
1333 "%s: pthread_create() returned EAGAIN: Insufficient resources "
1334 "to create thread.",
1335 __func__);
1337 g_debug ("%s: started alive detection.", __func__);
1338
1339 for (
host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1341 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1342 {
1344 }
1345
1346 if (gvm_host_get_addr6 (
host, &tmpaddr) == 0)
1349 {
1350 g_debug (
1351 "%s: Get first host to test from Queue. This host is used for "
1352 "initialising the alive_hosts_list.",
1353 __func__);
1354 }
1355 alive_hosts_list = gvm_hosts_new (gvm_host_value_str (
host));
1356 }
1357
1358 if (prefs_get ("report_scripts"))
1359 {
1360 char *path = g_strdup_printf (
1361 "%s/%s-stats.json", prefs_get (
"report_scripts"), globals->
scan_id);
1363 g_free (path);
1364 }
1365
1366
1367
1368 allow_simultaneous_ips = prefs_get_bool ("allow_simultaneous_ips");
1371 {
1374 char *host_str;
1375
1376 if (!test_alive_hosts_only
1378 {
1379 sleep (1);
1380
1381 gvm_hosts_move_current_host_to_end (
hosts);
1383 continue;
1384 }
1385
1386 do
1387 {
1388 rc = kb_new (&arg_host_kb, prefs_get ("db_address"));
1389 if (rc < 0 && rc != -2)
1390 {
1392 goto stop;
1393 }
1394 else if (rc == -2)
1395 {
1397 continue;
1398 }
1399 break;
1400 }
1401 while (1);
1402
1403 host_str = gvm_host_value_str (
host);
1406 {
1407 kb_delete (arg_host_kb);
1408 g_free (host_str);
1409 goto stop;
1410 }
1411
1413 {
1414 kb_delete (arg_host_kb);
1415 g_free (host_str);
1416 continue;
1417 }
1418
1422 args.host_kb = arg_host_kb;
1423
1424 forkagain:
1426
1428 {
1429 fork_retries++;
1431 {
1432
1433 g_warning ("fork() failed - %s. %s won't be tested",
1434 strerror (errno), host_str);
1435 g_free (host_str);
1436 goto stop;
1437 }
1438
1439 g_debug ("fork() failed - "
1440 "sleeping %d seconds and trying again...",
1441 fork_retries);
1443 goto forkagain;
1444 }
1446
1447 if (test_alive_hosts_only)
1448 {
1449 struct in6_addr tmpaddr;
1450 gvm_host_t *alive_buf;
1451
1452 while (1)
1453 {
1454
1455 gboolean ad_finished = FALSE;
1456 for (
host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1458 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1459 {
1461 }
1462
1463 if (
host && !allow_simultaneous_ips
1465 {
1466 struct in6_addr hostip;
1467 char ip_str[INET6_ADDRSTRLEN];
1468 int flag_set;
1469
1470 gvm_host_get_addr6 (
host, &hostip);
1471 addr6_to_str (&hostip, ip_str);
1472
1473
1474
1475 flag_set = finish_signal_on_queue (alive_hosts_kb);
1476
1477 put_host_on_queue (alive_hosts_kb, ip_str);
1478 g_debug ("Reallocating the host %s at the end of the queue",
1479 ip_str);
1480
1481 gvm_host_free (
host);
1483
1484 if (flag_set)
1485 {
1486 g_debug ("Reallocating finish signal in the host queue");
1487 realloc_finish_signal_on_queue (alive_hosts_kb);
1488 }
1489 }
1490 else
1491 break;
1492 }
1493
1494 if (
host && gvm_host_get_addr6 (
host, &tmpaddr) == 0)
1495 {
1498 gvm_host_free (alive_buf);
1499 alive_buf = NULL;
1500 }
1501
1503 gvm_hosts_add (alive_hosts_list, gvm_duplicate_host (
host));
1504 else
1505 g_debug ("%s: got NULL host, stop/finish scan", __func__);
1506 }
1507 else
1508 {
1510 }
1511 g_free (host_str);
1512 }
1513
1514
1515
1518 killpg (getpid (), SIGUSR1);
1519
1520 g_debug ("Test complete");
1521
1522stop:
1523
1524 if (test_alive_hosts_only)
1525 {
1526 int err;
1527 void *retval;
1528
1529 kb_lnk_reset (alive_hosts_kb);
1530 g_debug ("%s: free alive detection data ", __func__);
1531
1532
1533 g_debug ("%s: waiting for alive detection thread to be finished...",
1534 __func__);
1535
1537 if (err == EDEADLK)
1538 g_debug ("%s: pthread_join() returned EDEADLK.", __func__);
1539 if (err == EINVAL)
1540 g_debug ("%s: pthread_join() returned EINVAL.", __func__);
1541 if (err == ESRCH)
1542 g_debug ("%s: pthread_join() returned ESRCH.", __func__);
1543 if (retval == PTHREAD_CANCELED)
1544 g_debug ("%s: pthread_join() returned PTHREAD_CANCELED.", __func__);
1545
1546 if (err == 0)
1548 g_debug ("%s: Finished waiting for alive detection thread.", __func__);
1549 }
1550
1552
1553 gettimeofday (&now, NULL);
1554 if (test_alive_hosts_only)
1555 {
1556 g_message ("Vulnerability scan %s finished in %ld seconds: "
1557 "%d alive hosts of %d",
1558 globals->
scan_id, now.tv_sec - then.tv_sec,
1559 gvm_hosts_count (alive_hosts_list), gvm_hosts_count (
hosts));
1560 }
1561 else
1562 g_message ("Vulnerability scan %s finished in %ld seconds: %d hosts",
1563 globals->
scan_id, now.tv_sec - then.tv_sec,
1564 gvm_hosts_count (
hosts));
1565
1566 if (prefs_get ("report_scripts"))
1567 {
1568 char *buff =
1569 g_strdup_printf ("},\"scan_time\": {\"start\": %ld, \"stop\": %ld}}",
1570 then.tv_sec, now.tv_sec);
1571 char *path = g_strdup_printf (
1572 "%s/%s-stats.json", prefs_get (
"report_scripts"), globals->
scan_id);
1573
1575
1576 g_free (buff);
1577 g_free (path);
1578 }
1579
1580 gvm_hosts_free (
hosts);
1581 if (alive_hosts_list)
1582 gvm_hosts_free (alive_hosts_list);
1583
1585
1586 return error;
1587}
static int scan_is_stopped(void)
static void attack_start(struct ipc_context *ipcc, struct attack_start_args *args)
Set up some data and jump into attack_host().
static int apply_hosts_reverse_lookup_preferences(gvm_hosts_t *hosts)
static int apply_hosts_excluded(gvm_hosts_t *hosts)
static void handle_scan_stop_signal()
static void set_alive_detection_tid(pthread_t tid)
static void fork_sleep(int n)
static void check_deprecated_prefs(void)
Check if any deprecated prefs are in pref table and print warning.
static int connect_main_kb(kb_t *main_kb)
Connect to the main kb. Must be released with kb_lnk_reset() after use.
static void report_kb_failure(int errcode)
static int check_kb_access(void)
static void apply_hosts_preferences_ordering(gvm_hosts_t *hosts)
#define INVALID_TARGET_LIST
static void message_to_client(kb_t kb, const char *msg, const char *ip_str, const char *port, const char *type)
static gboolean ad_thread_joined(gboolean joined)
Set and get if alive detection thread was already joined by main thread.
static pthread_t get_alive_detection_tid()
static void set_scan_status(char *status)
Set scan status. This helps ospd-openvas to identify if a scan crashed or finished cleanly.
static struct host * hosts
int host_is_currently_scanned(gvm_host_t *host_to_check)
Returns 1 if the host is being scanned. 0 otherwise.
int hosts_set_pid(char *name, pid_t pid)
int hosts_read(void)
Returns -1 if client asked to stop all tests or connection was lost or error. 0 otherwise.
int hosts_init(int max_hosts)
int hosts_new(char *name, kb_t kb, kb_t main_kb)
void(* ipc_process_func)(struct ipc_context *, void *)
static struct timeval timeval(unsigned long val)
void plugins_scheduler_free(plugins_scheduler_t sched)
plugins_scheduler_t plugins_scheduler_init(const char *plugins_list, int autoload, int *error)
struct plugins_scheduler * plugins_scheduler_t
pid_t create_ipc_process(ipc_process_func func, void *args)
initializes a communication channels and calls a function with a new process
void(*)(int) openvas_signal(int signum, void(*handler)(int))
struct scan_globals * globals
plugins_scheduler_t sched
Host information, implemented as doubly linked list.
void write_script_stats(const char *buf, const char *path, int mode)
Writes scripts stats into a file.
int get_max_hosts_number(void)
int get_max_checks_number(void)