Skip to content

Commit

Permalink
Merge pull request #27 from savon-noir/issue25
Browse files Browse the repository at this point in the history
fix issue25 and added NmapService.owner
  • Loading branch information
savon-noir committed May 3, 2014
2 parents 371e847 + 3b6144d commit bcd8063
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v0.4.7, 03/05/2014 -- minor fix for issue25
- fixed exception when optional service tag is not present
in <port> tag
- added support for <owner> if present in <port>:
accessible via NmapService.owner
v0.4.6, 06/04/2014 -- minor fix
- corrected missing incomplete parameter on parse_fromfile
and parse_fromstring
Expand Down
15 changes: 13 additions & 2 deletions libnmap/objects/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class NmapService(object):
available or not. Like banner or extra datas from NSE (nmap scripts).
"""
def __init__(self, portid, protocol='tcp', state=None,
service=None, service_extras=None):
service=None, owner=None, service_extras=None):
"""
Constructor
Expand All @@ -37,6 +37,10 @@ def __init__(self, portid, protocol='tcp', state=None,
self._state = state if state is not None else {}
self._service = service if service is not None else {}

self._owner = ''
if owner is not None and 'name' in owner:
self._owner = owner['name']

self._reason = ''
self._reason_ip = ''
self._reason_ttl = ''
Expand Down Expand Up @@ -170,7 +174,7 @@ def service(self):
:return: dict or None
"""
return self._service['name'] if 'name' in self._service else None
return self._service['name'] if 'name' in self._service else ''

def open(self):
"""
Expand All @@ -180,6 +184,13 @@ def open(self):
"""
return 'state' in self._state and self._state['state'] == 'open'

@property
def owner(self):
"""
Accessor for service owner if available
"""
return self._owner

@property
def banner(self):
"""
Expand Down
9 changes: 6 additions & 3 deletions libnmap/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,28 +386,31 @@ def _parse_xml_port(cls, scanport_data):

_state = None
_service = None
_owner = None
_service_scripts = []
_service_extras = {}
for xport in xelement:
if xport.tag == 'state':
_state = cls.__format_attributes(xport)
elif xport.tag == 'service':
_service = cls.__format_attributes(xport)
elif xport.tag == 'owner':
_owner = cls.__format_attributes(xport)
elif xport.tag == 'script':
_script_dict = cls.__parse_script(xport)
_service_scripts.append(_script_dict)
_service_extras['scripts'] = _service_scripts

if(_portid is None or _protocol is None
or _state is None or _service is None):
if(_portid is None or _protocol is None or _state is None):
raise NmapParserException("XML <port> tag is incomplete. One "
"of the following tags is missing: "
"portid, protocol state or service.")
"portid, protocol or state or tag.")

nport = NmapService(_portid,
_protocol,
_state,
_service,
_owner,
_service_extras)
return nport

Expand Down
22 changes: 22 additions & 0 deletions libnmap/test/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@
<service name="smtp" method="table" conf="3"/>
</port>"""

port_noservice = """
<port protocol="udp" portid="3306">
<state state="closed" reason="port-unreach" reason_ttl="64" />
</port>"""

port_owner = """
<port protocol="tcp" portid="25">
<state state="open" reason="syn-ack" reason_ttl="64"/>
<service name="smtp" product="Postfix smtpd"
hostname=" jambon.localdomain" method="probed" conf="10"/>
<owner name="edwige"/>
</port>"""


class TestNmapService(unittest.TestCase):
def setUp(self):
Expand Down Expand Up @@ -221,6 +234,15 @@ def test_diff_reason(self):
ddict = nservice12.diff(nservice13)
self.assertEqual(ddict.changed(), set(['reason']))

def test_noservice(self):
noservice = NmapParser.parse(port_noservice)
self.assertEqual(noservice.service, "")

def test_owner(self):
serviceowner = NmapParser.parse(port_owner)
self.assertEqual(serviceowner.owner, "edwige")


if __name__ == '__main__':
test_suite = ['test_port_state_changed', 'test_port_state_unchanged',
'test_port_service_changed', 'test_eq_service',
Expand Down

0 comments on commit bcd8063

Please sign in to comment.