Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify handling of dead hosts. #252

Merged
merged 8 commits into from
May 11, 2020
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
a bit different then `pipenv install`. It installs dev packages by default and
also ospd in editable mode. This means after running poetry install ospd will
directly be importable in the virtual python environment. [#235](https://github.com/greenbone/ospd-openvas/pull/235)
- Don't send host details and log messages to the client when Boreas is enabled. [#252](https://github.com/greenbone/ospd-openvas/pull/252)
- Progress bar calculation do not takes in accound dead hosts. [#252](https://github.com/greenbone/ospd-openvas/pull/252)

### Fixed
- Check vt_aux for None before trying to access it. [#177](https://github.com/greenbone/ospd-openvas/pull/177)
Expand All @@ -43,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### Removed
- Remove use_mac_addr, vhost_ip and vhost scan preferences. [#184](https://github.com/greenbone/ospd-openvas/pull/184)
- Handling of finished host for resume task. [#252](https://github.com/greenbone/ospd-openvas/pull/252)

## [1.0.1] (unreleased)

Expand Down
67 changes: 25 additions & 42 deletions ospd_openvas/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

import psutil

from ospd.ospd import OSPDaemon
from ospd.ospd import OSPDaemon, PROGRESS_DEAD_HOST
from ospd.server import BaseServer
from ospd.main import main as daemon_main
from ospd.cvss import CVSS
Expand Down Expand Up @@ -809,12 +809,17 @@ def update_progress(self, scan_id: str, current_host: str, msg: str):
launched, total = msg.split('/')
except ValueError:
return
if float(total) == 0:

try:
if float(total) == 0:
return
elif float(total) == PROGRESS_DEAD_HOST:
host_prog = PROGRESS_DEAD_HOST
else:
host_prog = (float(launched) / float(total)) * 100
except TypeError:
return
elif float(total) == -1:
host_prog = 100
else:
host_prog = (float(launched) / float(total)) * 100

self.set_scan_host_progress(
scan_id, host=current_host, progress=host_prog
)
Expand Down Expand Up @@ -859,8 +864,7 @@ def report_openvas_results(

res = db.get_result()
res_list = ResultList()
host_progress_batch = dict()
finished_host_batch = list()
total_dead = 0
while res:
msg = res.split('|||')
roid = msg[3].strip()
Expand Down Expand Up @@ -927,45 +931,22 @@ def report_openvas_results(
qod=rqod,
)

# To process non scanned dead hosts when
# To process non-scanned dead hosts when
# test_alive_host_only in openvas is enable
if msg[0] == 'DEADHOST':
hosts = msg[3].split(',')
for _host in hosts:
if _host:
host_progress_batch[_host] = 100
finished_host_batch.append(_host)
res_list.add_scan_log_to_list(
host=_host,
hostname=rhostname,
name=rname,
value=msg[4],
port=msg[2],
qod=rqod,
test_id='',
)
timestamp = time.ctime(time.time())
res_list.add_scan_log_to_list(
host=_host, name='HOST_START', value=timestamp,
)
res_list.add_scan_log_to_list(
host=_host, name='HOST_END', value=timestamp,
)

try:
total_dead = int(msg[4])
except TypeError:
logger.debug('Error processing dead host count')
res = db.get_result()

# Insert result batch into the scan collection table.
if len(res_list):
self.scan_collection.add_result_list(scan_id, res_list)

if host_progress_batch:
self.set_scan_progress_batch(
scan_id, host_progress=host_progress_batch
)

if finished_host_batch:
self.set_scan_host_finished(
scan_id, finished_hosts=finished_host_batch
if total_dead:
self.scan_collection.set_amount_dead_hosts(
scan_id, total_dead=total_dead
)

def report_openvas_timestamp_scan_host(
Expand Down Expand Up @@ -1185,16 +1166,18 @@ def exec_scan(self, scan_id: str):
)

if scan_db.host_is_finished(openvas_scan_id):
self.set_scan_host_finished(
scan_id, finished_hosts=current_host
)
self.report_openvas_scan_status(
scan_db, scan_id, current_host
)

self.report_openvas_timestamp_scan_host(
scan_db, scan_id, current_host
)

self.sort_host_finished(
scan_id, finished_hosts=current_host
)

kbdb.remove_scan_database(scan_db)
self.main_db.release_database(scan_db)

Expand Down
11 changes: 0 additions & 11 deletions ospd_openvas/preferencehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,17 +451,6 @@ def prepare_host_options_for_openvas(self):
stores the list of hosts that must not be scanned in the kb. """
exclude_hosts = self.scan_collection.get_exclude_hosts(self.scan_id)

# Get unfinished hosts, in case it is a resumed scan. And added
# into exclude_hosts scan preference. Set progress for the finished ones
# to 100%.
finished_hosts = self.scan_collection.get_hosts_finished(self.scan_id)
if finished_hosts:
if exclude_hosts:
finished_hosts_str = ','.join(finished_hosts)
exclude_hosts = exclude_hosts + ',' + finished_hosts_str
else:
exclude_hosts = ','.join(finished_hosts)

if exclude_hosts:
pref_val = "exclude_hosts|||" + exclude_hosts
self.kbdb.add_scan_preferences(self._openvas_scan_id, [pref_val])
Expand Down
20 changes: 19 additions & 1 deletion tests/test_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,24 @@ def test_get_openvas_result(self, mock_add_scan_log_to_list, MockDBClass):
value='Host dead',
)

@patch('ospd_openvas.daemon.ScanDB')
def test_get_openvas_result_dead_hosts(self, MockDBClass):
w = DummyDaemon()

target_element = w.create_xml_target()
targets = OspRequest.process_target_element(target_element)
w.create_scan('123-456', targets, None, [])

results = ["DEADHOST||| ||| ||| |||4", None]
mock_db = MockDBClass.return_value
mock_db.get_result.side_effect = results
w.scan_collection.set_amount_dead_hosts = MagicMock()

w.report_openvas_results(mock_db, '123-456', 'localhost')
w.scan_collection.set_amount_dead_hosts.assert_called_with(
'123-456', total_dead=4,
)

@patch('ospd_openvas.db.KbDB')
def test_openvas_is_alive_already_stopped(self, mock_db):
w = DummyDaemon()
Expand Down Expand Up @@ -647,7 +665,7 @@ def test_update_progress(self, mock_set_scan_host_progress):
w.update_progress('123-456', 'localhost', msg)

mock_set_scan_host_progress.assert_called_with(
'123-456', host='localhost', progress=100
'123-456', host='localhost', progress=-1
)


Expand Down
42 changes: 0 additions & 42 deletions tests/test_preferencehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,48 +349,8 @@ def test_set_host_options(self, mock_kb):
w = DummyDaemon()

exc = '192.168.0.1'
fin = ['192.168.0.2']

w.scan_collection.get_exclude_hosts = MagicMock(return_value=exc)
w.scan_collection.get_hosts_finished = MagicMock(return_value=fin)

p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None)
p._openvas_scan_id = '456-789'
p.kbdb.add_scan_preferences = MagicMock()
p.prepare_host_options_for_openvas()

p.kbdb.add_scan_preferences.assert_called_with(
p._openvas_scan_id, ['exclude_hosts|||192.168.0.1,192.168.0.2'],
)

@patch('ospd_openvas.db.KbDB')
def test_set_host_options_no_exclude(self, mock_kb):
w = DummyDaemon()

exc = ''
fin = ['192.168.0.2']

w.scan_collection.get_exclude_hosts = MagicMock(return_value=exc)
w.scan_collection.get_hosts_finished = MagicMock(return_value=fin)

p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None)
p._openvas_scan_id = '456-789'
p.kbdb.add_scan_preferences = MagicMock()
p.prepare_host_options_for_openvas()

p.kbdb.add_scan_preferences.assert_called_with(
p._openvas_scan_id, ['exclude_hosts|||192.168.0.2'],
)

@patch('ospd_openvas.db.KbDB')
def test_set_host_options_no_finished(self, mock_kb):
w = DummyDaemon()

exc = '192.168.0.1'
fin = []

w.scan_collection.get_exclude_hosts = MagicMock(return_value=exc)
w.scan_collection.get_hosts_finished = MagicMock(return_value=fin)

p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None)
p._openvas_scan_id = '456-789'
Expand All @@ -406,10 +366,8 @@ def test_set_host_options_none(self, mock_kb):
w = DummyDaemon()

exc = ''
fin = []

w.scan_collection.get_exclude_hosts = MagicMock(return_value=exc)
w.scan_collection.get_hosts_finished = MagicMock(return_value=fin)

p = PreferenceHandler('1234-1234', mock_kb, w.scan_collection, None)
p._openvas_scan_id = '456-789'
Expand Down