def test_stop_scan_with_error(self, mock_check_call: MagicMock, mock_logger: MagicMock): mock_check_call.side_effect = subprocess.SubprocessError('foo') success = Openvas.stop_scan('scan_1') mock_check_call.assert_called_with( ['openvas', '--scan-stop', 'scan_1']) self.assertFalse(success) self.assertEqual(mock_logger.warning.call_count, 1) mock_check_call.reset_mock() mock_logger.reset_mock() mock_check_call.side_effect = OSError('foo') success = Openvas.stop_scan('scan_1') mock_check_call.assert_called_with( ['openvas', '--scan-stop', 'scan_1']) self.assertFalse(success) self.assertEqual(mock_logger.warning.call_count, 1)
def stop_scan_cleanup( self, kbdb: BaseDB, scan_id: str, ovas_process: psutil.Popen, # pylint: disable=arguments-differ ): """Set a key in redis to indicate the wrapper is stopped. It is done through redis because it is a new multiprocess instance and it is not possible to reach the variables of the grandchild process. Indirectly sends SIGUSR1 to the running openvas scan process via an invocation of openvas with the --scan-stop option to stop it.""" if kbdb: # Set stop flag in redis kbdb.stop_scan(scan_id) # Check if openvas is running if ovas_process.is_running(): # Cleaning in case of Zombie Process if ovas_process.status() == psutil.STATUS_ZOMBIE: logger.debug( '%s: Process with PID %s is a Zombie process.' ' Cleaning up...', scan_id, ovas_process.pid, ) ovas_process.wait() # Stop openvas process and wait until it stopped else: can_stop_scan = Openvas.stop_scan( scan_id, not self.is_running_as_root and self.sudo_available, ) if not can_stop_scan: logger.debug( 'Not possible to stop scan process: %s.', ovas_process, ) return logger.debug('Stopping process: %s', ovas_process) while ovas_process.is_running(): if ovas_process.status() == psutil.STATUS_ZOMBIE: ovas_process.wait() else: time.sleep(0.1) else: logger.debug( "%s: Process with PID %s already stopped", scan_id, ovas_process.pid, ) # Clean redis db for scan_db in kbdb.get_scan_databases(): self.main_db.release_database(scan_db)
def test_stop_scan_with_sudo(self, mock_check_call: MagicMock, _mock_logger: MagicMock): success = Openvas.stop_scan('scan_1', sudo=True) mock_check_call.assert_called_with( ['sudo', '-n', 'openvas', '--scan-stop', 'scan_1']) self.assertTrue(success)
def stop_scan_cleanup( # pylint: disable=arguments-differ self, global_scan_id: str): """Set a key in redis to indicate the wrapper is stopped. It is done through redis because it is a new multiprocess instance and it is not possible to reach the variables of the grandchild process. Indirectly sends SIGUSR1 to the running openvas scan process via an invocation of openvas with the --scan-stop option to stop it.""" openvas_scan_id, kbdb = self.main_db.find_kb_database_by_scan_id( global_scan_id) if kbdb: kbdb.stop_scan(openvas_scan_id) ovas_pid = kbdb.get_scan_process_id() parent = None try: parent = psutil.Process(int(ovas_pid)) except psutil.NoSuchProcess: logger.debug('Process with pid %s already stopped', ovas_pid) except TypeError: logger.debug( 'Scan with ID %s never started and stopped unexpectedly', openvas_scan_id, ) if parent: can_stop_scan = Openvas.stop_scan( openvas_scan_id, not self.is_running_as_root and self.sudo_available, ) if not can_stop_scan: logger.debug( 'Not possible to stop scan process: %s.', parent, ) return False logger.debug('Stopping process: %s', parent) while parent: if parent.is_running(): time.sleep(0.1) else: parent = None for scan_db in kbdb.get_scan_databases(): self.main_db.release_database(scan_db)