Attack a whole network. return 0 on successes, -1 if there was a critical error.
1171{
1172 int max_hosts = 0, max_checks;
1173 const char *hostlist;
1176 int fork_retries = 0;
1179 const gchar *port_range;
1180 int allow_simultaneous_ips;
1182 GSList *unresolved;
1183 char buf[96];
1184 int error = 0;
1185
1187
1188 gboolean test_alive_hosts_only = prefs_get_bool ("test_alive_hosts_only");
1189 gvm_hosts_t *alive_hosts_list = NULL;
1190 kb_t alive_hosts_kb = NULL;
1191 if (test_alive_hosts_only)
1193
1194 gettimeofday (&then, NULL);
1195
1197 {
1198 error = -1;
1199 return error;
1200 }
1201
1202 hostlist = prefs_get ("TARGET");
1203 if (hostlist == NULL)
1204 {
1205 error = -1;
1206 return error;
1207 }
1208
1209
1210 port_range = prefs_get ("port_range");
1211 if (validate_port_range (port_range))
1212 {
1215 main_kb,
"Invalid port list. Ports must be in the range [1-65535]",
1216 NULL, NULL, "ERRMSG");
1218 g_warning ("Invalid port list. Ports must be in the range [1-65535]. "
1219 "Scan terminated.");
1221
1222 error = -1;
1223 return error;
1224 }
1225
1226
1227 int plugins_init_error = 0;
1229 prefs_get_bool ("auto_enable_dependencies"),
1230 &plugins_init_error);
1231 if (!sched)
1232 {
1233 g_message ("Couldn't initialize the plugin scheduler");
1234
1235 error = -1;
1236 return error;
1237 }
1238
1239 if (plugins_init_error > 0)
1240 {
1241 sprintf (buf,
1242 "%d errors were found during the plugin scheduling. "
1243 "Some plugins have not been launched.",
1244 plugins_init_error);
1245
1249 }
1250
1253
1254 hosts = gvm_hosts_new (hostlist);
1256 {
1257 char *buffer;
1258 buffer = g_strdup_printf ("Invalid target list: %s.", hostlist);
1261 g_free (buffer);
1262
1263
1265 "HOSTS_COUNT");
1267 g_warning ("Invalid target list. Scan terminated.");
1268
1269 error = -1;
1270 goto stop;
1271 }
1272
1273 unresolved = gvm_hosts_resolve (
hosts);
1274 while (unresolved)
1275 {
1276 g_warning ("Couldn't resolve hostname '%s'", (char *) unresolved->data);
1277 unresolved = unresolved->next;
1278 }
1279 g_slist_free_full (unresolved, g_free);
1280
1281
1283
1284 int already_excluded = 0;
1286
1287#ifdef FEATURE_HOSTS_ALLOWED_ONLY
1288
1289
1290
1291 apply_hosts_allow_deny (
hosts);
1292#endif
1293
1294
1296
1297
1298
1299 sprintf (buf, "%d", exc + already_excluded);
1303
1304
1305
1306 sprintf (buf,
"%d", gvm_hosts_count (
hosts));
1310
1313 goto stop;
1314
1316
1317 g_message ("Vulnerability scan %s started: Target has %d hosts: "
1318 "%s, with max_hosts = %d and max_checks = %d",
1319 globals->
scan_id, gvm_hosts_count (
hosts), hostlist, max_hosts,
1320 max_checks);
1321
1322 if (test_alive_hosts_only)
1323 {
1324
1325 gboolean ad_finished = FALSE;
1326 int err;
1327 pthread_t tid;
1328 struct in6_addr tmpaddr;
1329
1330
1332 err = pthread_create (&tid, NULL, start_alive_detection, (
void *)
hosts);
1333 if (err == EAGAIN)
1334 g_warning (
1335 "%s: pthread_create() returned EAGAIN: Insufficient resources "
1336 "to create thread.",
1337 __func__);
1339 g_debug ("%s: started alive detection.", __func__);
1340
1341 for (
host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1343 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1344 {
1346 }
1347
1348 if (gvm_host_get_addr6 (
host, &tmpaddr) == 0)
1351 {
1352 g_debug (
1353 "%s: Get first host to test from Queue. This host is used for "
1354 "initialising the alive_hosts_list.",
1355 __func__);
1356 }
1357 alive_hosts_list = gvm_hosts_new (gvm_host_value_str (
host));
1358 }
1359
1360 if (prefs_get ("report_scripts"))
1361 {
1362 char *path = g_strdup_printf (
1363 "%s/%s-stats.json", prefs_get (
"report_scripts"), globals->
scan_id);
1365 g_free (path);
1366 }
1367
1368
1369
1370 allow_simultaneous_ips = prefs_get_bool ("allow_simultaneous_ips");
1373 {
1376 char *host_str;
1377
1378 if (!test_alive_hosts_only
1380 {
1381 sleep (1);
1382
1383 gvm_hosts_move_current_host_to_end (
hosts);
1385 continue;
1386 }
1387
1388 do
1389 {
1390 rc = kb_new (&arg_host_kb, prefs_get ("db_address"));
1391 if (rc < 0 && rc != -2)
1392 {
1394 goto stop;
1395 }
1396 else if (rc == -2)
1397 {
1399 continue;
1400 }
1401 break;
1402 }
1403 while (1);
1404
1405 host_str = gvm_host_value_str (
host);
1408 {
1409 kb_delete (arg_host_kb);
1410 g_free (host_str);
1411 goto stop;
1412 }
1413
1415 {
1416 kb_delete (arg_host_kb);
1417 g_free (host_str);
1418 continue;
1419 }
1420
1424 args.host_kb = arg_host_kb;
1425
1426 forkagain:
1428
1430 {
1431 fork_retries++;
1433 {
1434
1435 g_warning ("fork() failed - %s. %s won't be tested",
1436 strerror (errno), host_str);
1437 g_free (host_str);
1438 goto stop;
1439 }
1440
1441 g_debug ("fork() failed - "
1442 "sleeping %d seconds and trying again...",
1443 fork_retries);
1445 goto forkagain;
1446 }
1448
1449 if (test_alive_hosts_only)
1450 {
1451 struct in6_addr tmpaddr;
1452 gvm_host_t *alive_buf;
1453
1454 while (1)
1455 {
1456
1457 gboolean ad_finished = FALSE;
1458 for (
host = get_host_from_queue (alive_hosts_kb, &ad_finished);
1460 host = get_host_from_queue (alive_hosts_kb, &ad_finished))
1461 {
1463 }
1464
1465 if (
host && !allow_simultaneous_ips
1467 {
1468 struct in6_addr hostip;
1469 char ip_str[INET6_ADDRSTRLEN];
1470 int flag_set;
1471
1472 gvm_host_get_addr6 (
host, &hostip);
1473 addr6_to_str (&hostip, ip_str);
1474
1475
1476
1477 flag_set = finish_signal_on_queue (alive_hosts_kb);
1478
1479 put_host_on_queue (alive_hosts_kb, ip_str);
1480 g_debug ("Reallocating the host %s at the end of the queue",
1481 ip_str);
1482
1483 gvm_host_free (
host);
1485
1486 if (flag_set)
1487 {
1488 g_debug ("Reallocating finish signal in the host queue");
1489 realloc_finish_signal_on_queue (alive_hosts_kb);
1490 }
1491 }
1492 else
1493 break;
1494 }
1495
1496 if (
host && gvm_host_get_addr6 (
host, &tmpaddr) == 0)
1497 {
1500 gvm_host_free (alive_buf);
1501 alive_buf = NULL;
1502 }
1503
1505 gvm_hosts_add (alive_hosts_list, gvm_duplicate_host (
host));
1506 else
1507 g_debug ("%s: got NULL host, stop/finish scan", __func__);
1508 }
1509 else
1510 {
1512 }
1513 g_free (host_str);
1514 }
1515
1516
1517
1520 killpg (getpid (), SIGUSR1);
1521
1522 g_debug ("Test complete");
1523
1524stop:
1525
1526 if (test_alive_hosts_only)
1527 {
1528 int err;
1529 void *retval;
1530
1531 kb_lnk_reset (alive_hosts_kb);
1532 g_debug ("%s: free alive detection data ", __func__);
1533
1534
1535 g_debug ("%s: waiting for alive detection thread to be finished...",
1536 __func__);
1537
1539 if (err == EDEADLK)
1540 g_debug ("%s: pthread_join() returned EDEADLK.", __func__);
1541 if (err == EINVAL)
1542 g_debug ("%s: pthread_join() returned EINVAL.", __func__);
1543 if (err == ESRCH)
1544 g_debug ("%s: pthread_join() returned ESRCH.", __func__);
1545 if (retval == PTHREAD_CANCELED)
1546 g_debug ("%s: pthread_join() returned PTHREAD_CANCELED.", __func__);
1547
1548 if (err == 0)
1550 g_debug ("%s: Finished waiting for alive detection thread.", __func__);
1551 }
1552
1554
1555 gettimeofday (&now, NULL);
1556 if (test_alive_hosts_only)
1557 {
1558 g_message ("Vulnerability scan %s finished in %ld seconds: "
1559 "%d alive hosts of %d",
1560 globals->
scan_id, now.tv_sec - then.tv_sec,
1561 gvm_hosts_count (alive_hosts_list), gvm_hosts_count (
hosts));
1562 }
1563 else
1564 g_message ("Vulnerability scan %s finished in %ld seconds: %d hosts",
1565 globals->
scan_id, now.tv_sec - then.tv_sec,
1566 gvm_hosts_count (
hosts));
1567
1568 if (prefs_get ("report_scripts"))
1569 {
1570 char *buff =
1571 g_strdup_printf ("},\"scan_time\": {\"start\": %ld, \"stop\": %ld}}",
1572 then.tv_sec, now.tv_sec);
1573 char *path = g_strdup_printf (
1574 "%s/%s-stats.json", prefs_get (
"report_scripts"), globals->
scan_id);
1575
1577
1578 g_free (buff);
1579 g_free (path);
1580 }
1581
1582 gvm_hosts_free (
hosts);
1583 if (alive_hosts_list)
1584 gvm_hosts_free (alive_hosts_list);
1585
1587
1588 return error;
1589}
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)