Skip to content

Commit

Permalink
added some unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
savon-noir committed Nov 27, 2020
1 parent 24fcc2e commit 881474d
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 69 deletions.
134 changes: 67 additions & 67 deletions libnmap/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,28 @@ class NmapParser(object):
@classmethod
def parse(cls, nmap_data=None, data_type="XML", incomplete=False):
"""
Generic class method of NmapParser class.
Generic class method of NmapParser class.
The data to be parsed does not need to be a complete nmap
scan report. You can possibly give <hosts>...</hosts>
or <port> XML tags.
The data to be parsed does not need to be a complete nmap
scan report. You can possibly give <hosts>...</hosts>
or <port> XML tags.
:param nmap_data: any portion of nmap scan result. \
nmap_data should always be a string representing a part \
or a complete nmap scan report.
:type nmap_data: string
:param nmap_data: any portion of nmap scan result. \
nmap_data should always be a string representing a part \
or a complete nmap scan report.
:type nmap_data: string
:param data_type: specifies the type of data to be parsed.
:type data_type: string ("XML"|"JSON"|"YAML").
:param data_type: specifies the type of data to be parsed.
:type data_type: string ("XML"|"JSON"|"YAML").
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
As of today, only XML parsing is supported.
As of today, only XML parsing is supported.
:return: NmapObject (NmapHost, NmapService or NmapReport)
:return: NmapObject (NmapHost, NmapService or NmapReport)
"""

nmapobj = None
Expand All @@ -56,32 +56,32 @@ def parse(cls, nmap_data=None, data_type="XML", incomplete=False):
@classmethod
def _parse_xml(cls, nmap_data=None, incomplete=False):
"""
Protected class method used to process a specific data type.
In this case: XML. This method is called by cls.parse class
method and receives nmap scan results data (in XML).
Protected class method used to process a specific data type.
In this case: XML. This method is called by cls.parse class
method and receives nmap scan results data (in XML).
:param nmap_data: any portion of nmap scan result can be given \
as argument. nmap_data should always be a string representing \
a part or a complete nmap scan report.
:type nmap_data: string
:param nmap_data: any portion of nmap scan result can be given \
as argument. nmap_data should always be a string representing \
a part or a complete nmap scan report.
:type nmap_data: string
This method checks which portion of a nmap scan is given \
as argument.
It could be:
This method checks which portion of a nmap scan is given \
as argument.
It could be:
1. a full nmap scan report;
2. a scanned host: <host> tag in a nmap scan report
3. a scanned service: <port> tag
4. a list of hosts: <hosts/> tag (TODO)
5. a list of ports: <ports/> tag
1. a full nmap scan report;
2. a scanned host: <host> tag in a nmap scan report
3. a scanned service: <port> tag
4. a list of hosts: <hosts/> tag (TODO)
5. a list of ports: <ports/> tag
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:return: NmapObject (NmapHost, NmapService or NmapReport) \
or a list of NmapObject
:return: NmapObject (NmapHost, NmapService or NmapReport) \
or a list of NmapObject
"""

if not nmap_data:
Expand Down Expand Up @@ -159,22 +159,22 @@ def _parse_xml_report(cls, root=None):
@classmethod
def parse_fromstring(cls, nmap_data, data_type="XML", incomplete=False):
"""
Call generic cls.parse() method and ensure that a string is \
passed on as argument. If not, an exception is raised.
Call generic cls.parse() method and ensure that a string is \
passed on as argument. If not, an exception is raised.
:param nmap_data: Same as for parse(), any portion of nmap scan. \
Reports could be passed as argument. Data type _must_ be a string.
:param nmap_data: Same as for parse(), any portion of nmap scan. \
Reports could be passed as argument. Data type _must_ be a string.
:type nmap_data: string
:type nmap_data: string
:param data_type: Specifies the type of data passed on as argument.
:param data_type: Specifies the type of data passed on as argument.
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:return: NmapObject
:return: NmapObject
"""

if not isinstance(nmap_data, str):
Expand All @@ -189,22 +189,22 @@ def parse_fromfile(
cls, nmap_report_path, data_type="XML", incomplete=False
):
"""
Call generic cls.parse() method and ensure that a correct file \
path is given as argument. If not, an exception is raised.
Call generic cls.parse() method and ensure that a correct file \
path is given as argument. If not, an exception is raised.
:param nmap_data: Same as for parse(). \
Any portion of nmap scan reports could be passed as argument. \
Data type _must be a valid path to a file containing \
nmap scan results.
:param nmap_data: Same as for parse(). \
Any portion of nmap scan reports could be passed as argument. \
Data type _must be a valid path to a file containing \
nmap scan results.
:param data_type: Specifies the type of serialization in the file.
:param data_type: Specifies the type of serialization in the file.
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:param incomplete: enable you to parse interrupted nmap scans \
and/or incomplete nmap xml blocks by adding a </nmaprun> at \
the end of the scan.
:type incomplete: boolean
:return: NmapObject
:return: NmapObject
"""

try:
Expand All @@ -218,15 +218,15 @@ def parse_fromfile(
@classmethod
def parse_fromdict(cls, rdict):
"""
Strange method which transforms a python dict \
representation of a NmapReport and turns it into an \
NmapReport object. \
Needs to be reviewed and possibly removed.
Strange method which transforms a python dict \
representation of a NmapReport and turns it into an \
NmapReport object. \
Needs to be reviewed and possibly removed.
:param rdict: python dict representation of an NmapReport
:type rdict: dict
:param rdict: python dict representation of an NmapReport
:type rdict: dict
:return: NmapReport
:return: NmapReport
"""

nreport = {}
Expand Down
15 changes: 15 additions & 0 deletions libnmap/reportjson.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@


class ReportEncoder(json.JSONEncoder):
"""
ReportEncoder is a internal class used mostly by plugins to convert
NmapReport objects in json format.
e.g.:
nmapreport_obj = NmapParser.parse_fromfile(
"libnmap/test/files/1_hosts.xml"
)
nmapreport_json = json.dumps(nmapreport_obj, cls=ReportEncoder)
"""
def default(self, obj):
otype = {
"NmapHost": NmapHost,
Expand All @@ -33,6 +42,12 @@ def default(self, obj):


class ReportDecoder(json.JSONDecoder):
"""
ReportDecoder is a internal class used mostly by plugins to convert
json nmap report in to NmapReport objects.
e.g.:
nmap_report_obj = json.loads(nmap_report_json, cls=ReportDecoder)
"""
def decode(self, json_str):
r = NmapParser.parse_fromdict(json.loads(json_str))
return r
1 change: 1 addition & 0 deletions libnmap/test/files/2_hosts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"__NmapReport__": {"_nmaprun": {"scanner": "nmap", "args": "nmap -sS -vv -oX 2_hosts.xml localhost scanme.nmap.org", "start": "1361737906", "startstr": "Sun Feb 24 21:31:46 2013", "version": "5.51", "xmloutputversion": "1.03"}, "_scaninfo": {"type": "syn", "protocol": "tcp", "numservices": "1000", "services": "1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389"}, "_hosts": [{"__NmapHost__": {"_starttime": "1361737906", "_endtime": "1361737906", "_hostnames": ["localhost", "localhost"], "_status": {"state": "up", "reason": "localhost-response"}, "_services": [{"__NmapService__": {"_portid": 22, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "64"}, "_service": {"name": "ssh", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "64", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 25, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "64"}, "_service": {"name": "smtp", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "64", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 111, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "64"}, "_service": {"name": "rpcbind", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "64", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 631, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "64"}, "_service": {"name": "ipp", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "64", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 3306, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "64"}, "_service": {"name": "mysql", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "64", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}], "_extras": {"extraports": {"state": {"state": "closed", "count": "995"}, "count": {"state": "closed", "count": "995"}, "reasons": [{"reason": "resets", "count": "995"}]}, "times": {"srtt": "7", "rttvar": "0", "to": "100000"}}, "_osfingerprinted": false, "os": {"__NmapOSFingerprint__": {"_NmapOSFingerprint__osmatches": [], "_NmapOSFingerprint__ports_used": [], "_NmapOSFingerprint__fingerprints": []}}, "_ipv4_addr": "127.0.0.1", "_ipv6_addr": null, "_mac_addr": null, "_vendor": null, "_main_address": "127.0.0.1", "_address": [{"addr": "127.0.0.1", "addrtype": "ipv4"}]}}, {"__NmapHost__": {"_starttime": "1361737906", "_endtime": "1361738040", "_hostnames": ["scanme.nmap.org", "scanme.nmap.org"], "_status": {"state": "up", "reason": "echo-reply"}, "_services": [{"__NmapService__": {"_portid": 22, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "53"}, "_service": {"name": "ssh", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "53", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 25, "_protocol": "tcp", "_state": {"state": "filtered", "reason": "admin-prohibited", "reason_ttl": "253", "reason_ip": "109.133.192.1"}, "_service": {"name": "smtp", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "admin-prohibited", "_reason_ip": "109.133.192.1", "_reason_ttl": "253", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 80, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "51"}, "_service": {"name": "http", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "51", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}, {"__NmapService__": {"_portid": 9929, "_protocol": "tcp", "_state": {"state": "open", "reason": "syn-ack", "reason_ttl": "53"}, "_service": {"name": "nping-echo", "method": "table", "conf": "3", "cpelist": []}, "_cpelist": [], "_owner": "", "_reason": "syn-ack", "_reason_ip": "", "_reason_ttl": "53", "_servicefp": "", "_tunnel": "", "_service_extras": {"scripts": []}}}], "_extras": {"extraports": {"state": {"state": "closed", "count": "996"}, "count": {"state": "closed", "count": "996"}, "reasons": [{"reason": "resets", "count": "996"}]}, "times": {"srtt": "177425", "rttvar": "1981", "to": "185349"}}, "_osfingerprinted": false, "os": {"__NmapOSFingerprint__": {"_NmapOSFingerprint__osmatches": [], "_NmapOSFingerprint__ports_used": [], "_NmapOSFingerprint__fingerprints": []}}, "_ipv4_addr": "74.207.244.221", "_ipv6_addr": null, "_mac_addr": null, "_vendor": null, "_main_address": "74.207.244.221", "_address": [{"addr": "74.207.244.221", "addrtype": "ipv4"}]}}], "_runstats": {"finished": {"time": "1361738040", "timestr": "Sun Feb 24 21:34:00 2013", "elapsed": "134.36", "summary": "Nmap done at Sun Feb 24 21:34:00 2013; 2 IP addresses (2 hosts up) scanned in 134.36 seconds", "exit": "success"}, "hosts": {"up": "2", "down": "0", "total": "2"}}}}
3 changes: 2 additions & 1 deletion libnmap/test/test_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ def test_full_cpe(self):
"edition": ocpe.get_edition(),
}
self.assertEqual(objdict, resdict)

# self.assertEqual(ocpe.cpedict, resdict)
self.assertEqual(str(ocpe), cpestr)

if __name__ == "__main__":
test_suite = ["test_cpe", "test_full_cpe"]
Expand Down

0 comments on commit 881474d

Please sign in to comment.