Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Add OSP command get_vts. #12

Merged
merged 2 commits into from
Jun 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 93 additions & 2 deletions doc/OSP.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ Description: OSP schema with embedded documentation, in OSP.

Authors:
Hani Benhabiles <hani.benhabiles@greenbone.net>
Jan-Oliver Wagner <jan-oliver.wagner@greenbone.net>

Copyright:
Copyright (C) 2014, 2015 Greenbone Networks GmbH
Copyright (C) 2014, 2015, 2018 Greenbone Networks GmbH

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Expand All @@ -28,7 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
<name>Open Scanner Protocol</name>
<abbreviation>OSP</abbreviation>
<summary>The Open Scanner Protocol</summary>
<version>1.1</version>
<version>1.2</version>
<type>
<name>integer</name>
<summary>An integer</summary>
Expand Down Expand Up @@ -473,6 +474,86 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
</response>
</example>
</command>

<command>
<name>get_vts</name>
<summary>Return information about vulnerability tests, if offered by scanner</summary>
<pattern>
<attrib>
<name>vt_id</name>
<summary>Identifier for vulnerability test</summary>
<type>string</type>
</attrib>
</pattern>
<response>
<pattern>
<attrib>
<name>status</name>
<type>integer</type>
<required>1</required>
</attrib>
<attrib>
<name>status_text</name>
<type>text</type>
<required>1</required>
</attrib>
<e>vts</e>
</pattern>
<ele>
<name>vts</name>
<pattern>
<any><e>vt</e></any>
</pattern>
<ele>
<name>vt</name>
<pattern>
<attrib>
<name>id</name>
<type>string</type>
</attrib>
<e>name</e>
</pattern>
<ele>
<name>name</name>
</ele>
</ele>
</ele>
</response>
<example>
<summary>Get information for all available vulnerability tests</summary>
<request>
<get_vts/>
</request>
<response>
<get_vts_response status_text="OK" status="200">
<vts>
<vt id="1.2.3.4.5">
<name>Check for presence of vulnerabilty X</name>
</vt>
<vt id="ad45h67">
<name>Check for presence of vulnerabilty Y</name>
</vt>
</vts>
</get_vts_response>
</response>
</example>
<example>
<summary>Get information for a single vulnerability test</summary>
<request>
<get_vts id='1.2.3.4.5'/>
</request>
<response>
<get_vts_response status_text="OK" status="200">
<vts>
<vt id="1.2.3.4.5">
<name>Check for presence of vulnerabilty X</name>
</vt>
</vts>
</get_vts_response>
</response>
</example>
</command>

<command>
<name>start_scan</name>
<summary>Start a new scan</summary>
Expand Down Expand Up @@ -599,6 +680,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
<name>ovaldef_file</name>
<summary>An ovaldef file's content that is base64 encoded</summary>
</parameter_type>

<change>
<command>GET_VTS</command>
<summary>command added</summary>
<description>
Added new command to retrieve information about vulnerability tests a scanner might offer.
</description>
<version>1.2</version>
</change>

<change>
<command>STOP_SCAN</command>
<summary>command added</summary>
Expand Down
92 changes: 89 additions & 3 deletions ospd/ospd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
# Authors:
# Hani Benhabiles <hani.benhabiles@greenbone.net>
# Benoît Allard <benoit.allard@greenbone.net>
# Jan-Oliver Wahmer <jan-oliver.wagner@greenbone.net>
#
# Copyright:
# Copyright (C) 2014, 2015 Greenbone Networks GmbH
# Copyright (C) 2014, 2015, 2018 Greenbone Networks GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -44,7 +45,7 @@

logger = logging.getLogger(__name__)

PROTOCOL_VERSION = "1.1"
PROTOCOL_VERSION = "1.2"

BASE_SCANNER_PARAMS = {
'debug_mode': {
Expand Down Expand Up @@ -95,6 +96,13 @@
},
'elements': None
},
'get_vts': {
'description': 'List of available vulnerability tests.',
'attributes': {
'vt_id': 'ID of a specific vulnerability test to get.'
},
'elements': None
},
'delete_scan': {
'description': 'Delete a finished scan.',
'attributes': {
Expand Down Expand Up @@ -267,6 +275,7 @@ def __init__(self, certfile, keyfile, cafile):
self.protocol_version = PROTOCOL_VERSION
self.commands = COMMANDS_TABLE
self.scanner_params = dict()
self.vts = dict()
for name, param in BASE_SCANNER_PARAMS.items():
self.add_scanner_param(name, param)

Expand All @@ -287,6 +296,22 @@ def add_scanner_param(self, name, scanner_param):
'scanner_params':
{k: v['name'] for k, v in self.scanner_params.items()}}

def add_vt(self, vt_id, name=''):
""" Add a vulnerability test information.

Returns: The new number of stored VTs.
-1 in case the VT ID was already present and thus the
new VT was not considered.
-2 in case the vt_id was invalid.
"""

if vt_id and vt_id in self.vts:
return -1 # The VT was already in the list.
elif vt_id:
self.vts[vt_id] = { 'name': name }
return len(self.vts)
return -2 # no valid vt_id

def command_exists(self, name):
""" Checks if a commands exists. """
return name in self.commands.keys()
Expand Down Expand Up @@ -626,6 +651,29 @@ def handle_get_scans_command(self, scan_et):
responses.append(scan)
return simple_response_str('get_scans', 200, 'OK', responses)

def handle_get_vts_command(self, vt_et):
""" Handles <get_vts> command.

@return: Response string for <get_vts> command.
"""

vt_id = vt_et.attrib.get('vt_id')

if vt_id and vt_id not in self.vts:
text = "Failed to find vulnerability test '{0}'".format(vt_id)
return simple_response_str('get_vts', 404, text)

responses = []

if vt_id:
vts_xml = self.get_vts_xml(vt_id)
else:
vts_xml = self.get_vts_xml()

responses.append(vts_xml)

return simple_response_str('get_vts', 200, 'OK', responses)

def handle_help_command(self, scan_et):
""" Handles <help> command.

Expand Down Expand Up @@ -741,7 +789,7 @@ def get_xml_str(self, data):
def get_scan_xml(self, scan_id, detailed=True):
""" Gets scan in XML format.

@return: String of scan in xml format.
@return: String of scan in XML format.
"""
if not scan_id:
return ET.Element('scan')
Expand All @@ -761,6 +809,42 @@ def get_scan_xml(self, scan_id, detailed=True):
response.append(self.get_scan_results_xml(scan_id))
return response

def get_vt_xml(self, vt_id):
""" Gets a single vulnerability test information in XML format.

@return: String of single vulnerability test information in XML format.
"""
if not vt_id:
return ET.Element('vt')

vt = self.vts.get(vt_id)

name = vt.get('name')
vt_xml = ET.Element('vt')
vt_xml.set('id', vt_id)
for name, value in [('name', name)]:
elem = ET.SubElement(vt_xml, name)
elem.text = str(value)
return vt_xml

def get_vts_xml(self, vt_id=''):
""" Gets collection of vulnerability test information in XML format.
If vt_id is specified, the collection will contain only this vt, of found.
If no vt_id is specified, the collection will contain all vts.

@return: String of collection of vulnerability test information in XML format.
"""

vts_xml = ET.Element('vts')

if vt_id != '':
vts_xml.append(self.get_vt_xml(vt_id))
else:
for vt_id in self.vts:
vts_xml.append(self.get_vt_xml(vt_id))

return vts_xml

def handle_get_scanner_details(self):
""" Handles <get_scanner_details> command.

Expand Down Expand Up @@ -818,6 +902,8 @@ def handle_command(self, command):
return self.handle_stop_scan_command(tree)
elif tree.tag == "get_scans":
return self.handle_get_scans_command(tree)
elif tree.tag == "get_vts":
return self.handle_get_vts_command(tree)
elif tree.tag == "delete_scan":
return self.handle_delete_scan_command(tree)
elif tree.tag == "help":
Expand Down
19 changes: 19 additions & 0 deletions tests/testScanAndResult.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ def testGetDefaultScannerVersion(self):
response = ET.fromstring(daemon.handle_command('<get_version />'))
print(ET.tostring(response))

def testGetVTs_no_VT(self):
daemon = DummyWrapper([])
response = ET.fromstring(daemon.handle_command('<get_vts />'))
print(ET.tostring(response))

def testGetVTs_single_VT(self):
daemon = DummyWrapper([])
daemon.add_vt('1.2.3.4', 'A vulnerability test')
response = ET.fromstring(daemon.handle_command('<get_vts />'))
print(ET.tostring(response))

def testGetVTs_multiple_VTs(self):
daemon = DummyWrapper([])
daemon.add_vt('1.2.3.4', 'A vulnerability test')
daemon.add_vt('some id', 'Another vulnerability test')
daemon.add_vt('123456789', 'Yet another vulnerability test')
response = ET.fromstring(daemon.handle_command('<get_vts />'))
print(ET.tostring(response))

def testiScanWithError(self):
daemon = DummyWrapper([
Result('error', value='something went wrong'),
Expand Down