Skip to content

Commit 1042db1

Browse files
committed
fixed issue savon-noir#28
1 parent 01096b4 commit 1042db1

3 files changed

Lines changed: 39 additions & 3 deletions

File tree

libnmap/objects/service.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python
22
from libnmap.diff import NmapDiff
3+
from libnmap.objects.os import CPE
34

45

56
class NmapService(object):
@@ -37,6 +38,11 @@ def __init__(self, portid, protocol='tcp', state=None,
3738
self._state = state if state is not None else {}
3839
self._service = service if service is not None else {}
3940

41+
self._cpelist = []
42+
for _cpe in service['cpelist']:
43+
_cpeobj = CPE(_cpe)
44+
self._cpelist.append(_cpeobj)
45+
4046
self._owner = ''
4147
if owner is not None and 'name' in owner:
4248
self._owner = owner['name']
@@ -199,14 +205,21 @@ def banner(self):
199205
200206
:return: string
201207
"""
202-
notrelevant = ['name', 'method', 'conf']
208+
notrelevant = ['name', 'method', 'conf', 'cpelist']
203209
b = ''
204210
if 'method' in self._service and self._service['method'] == "probed":
205211
b = " ".join([k + ": " + self._service[k]
206212
for k in self._service.keys()
207213
if k not in notrelevant])
208214
return b
209215

216+
@property
217+
def cpelist(self):
218+
"""
219+
Accessor for list of CPE for this particular service
220+
"""
221+
return self._cpelist
222+
210223
@property
211224
def scripts_results(self):
212225
"""

libnmap/parser.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ def _parse_xml_port(cls, scanport_data):
394394
if xport.tag == 'state':
395395
_state = cls.__format_attributes(xport)
396396
elif xport.tag == 'service':
397-
_service = cls.__format_attributes(xport)
397+
_service = cls.__parse_service(xport)
398398
elif xport.tag == 'owner':
399399
_owner = cls.__format_attributes(xport)
400400
elif xport.tag == 'script':
@@ -415,6 +415,20 @@ def _parse_xml_port(cls, scanport_data):
415415
_service_extras)
416416
return nport
417417

418+
@classmethod
419+
def __parse_service(cls, xserv):
420+
"""
421+
Parse <service> tag to manage CPE object
422+
"""
423+
_service = cls.__format_attributes(xserv)
424+
_cpelist = []
425+
for _servnode in xserv:
426+
if _servnode.tag == 'cpe':
427+
_cpe_string = _servnode.text
428+
_cpelist.append(_cpe_string)
429+
_service['cpelist'] = _cpelist
430+
return _service
431+
418432
@classmethod
419433
def __parse_extraports(cls, extraports_data):
420434
"""

libnmap/test/test_fp.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def setUp(self):
1515
{ 'file': "%s/%s" % (fdir, 'files/1_hosts_down.xml'), 'os': 0}]
1616
self.flist = self.flist_full
1717
self.flist_os = {'nv6': {'file': "%s/%s" % (fdir, 'files/full_sudo6.xml'), 'os': 0},
18+
'fullscan': { 'file': "%s/%s" % (fdir, 'files/fullscan.xml'), 'os': 0},
1819
'nv5': { 'file': "%s/%s" % (fdir, 'files/os_scan5.xml'), 'os': 0}}
1920

2021
def test_fp(self):
@@ -114,9 +115,17 @@ def test_fpv5(self):
114115
self.assertEqual(h1.os.fingerprint, fpval)
115116
self.assertEqual(h1.os.fingerprints, fparray)
116117

118+
def test_cpeservice(self):
119+
cpelist = ['cpe:/a:openbsd:openssh:5.9p1','cpe:/o:linux:linux_kernel']
120+
rep = NmapParser.parse_fromfile(self.flist_os['fullscan']['file'])
121+
h1 = rep.hosts.pop()
122+
s = h1.services[0]
123+
self.assertEqual(s.cpelist[0].cpestring, cpelist[0])
124+
self.assertEqual(s.cpelist[1].cpestring, cpelist[1])
125+
117126

118127
if __name__ == '__main__':
119128
test_suite = ['test_fp', 'test_fpv6', 'test_osmatches_new', 'test_osclasses_new',
120-
'test_fpv5', 'test_osmatches_old']
129+
'test_fpv5', 'test_osmatches_old', 'test_cpeservice']
121130
suite = unittest.TestSuite(map(TestNmapFP, test_suite))
122131
test_result = unittest.TextTestRunner(verbosity=2).run(suite)

0 commit comments

Comments
 (0)