Skip to content

Commit 21fb0ec

Browse files
committed
merge of report and objects, deprecated removed, docstring added
1 parent 345f234 commit 21fb0ec

16 files changed

Lines changed: 282 additions & 220 deletions

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,44 @@ libnmap is a python toolkit for manipulating nmap. It currently offers the follo
2323

2424
## How
2525

26+
### Launch a simple scan with event callback
27+
Below a simple example on how to run a nmap scan using a callback function.
28+
No advanced data manipulations with our parser. The callback will simply
29+
printout the percentage done and the etc. The event callback is triggered
30+
each time nmap outputs data. It is to note that a fixed options forces
31+
nmap to send its progress to the lib every two seconds. Consequently, at least
32+
every two seconds, the callback function is triggered even if nmap is not
33+
printing out stuff.
34+
35+
```python
36+
#!/usr/bin/env python
37+
from libnmap import NmapProcess
38+
39+
def main(argv):
40+
def mycallback(nmapscan=None, data=""):
41+
if nmapscan.is_running():
42+
print "Progress: %s %% - ETC: %s" % (nmapscan.progress,
43+
nmapscan.etc)
44+
45+
nm = NmapProcess("scanme.nmap.org", options="-sV", event_callback=mycallback)
46+
rc = nm.run()
47+
48+
if rc == 0:
49+
print "Scan started at {0} nmap version: {1}".format(nm.starttime,
50+
nm.version)
51+
print "state: {0} (rc: {1})".format(nm.state, nm.rc)
52+
print "results size: {0}".format(len(nm.stdout))
53+
print "Scan ended {0}: {1}".format(nm.endtime, nm.summary)
54+
else:
55+
print "state: {0} (rc: {1})".format(nm.state, nm.rc)
56+
print "Error: {stderr}".format(stderr=nm.stderr)
57+
print "Result: {0}".format(nm.stdout)
58+
59+
60+
if __name__ == '__main__':
61+
main(sys.argv[1:])
62+
```
63+
2664
### Launch a nmap scan
2765
Here a consequent example on how to use libnmap:
2866
```python

libnmap/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,4 @@
33
__maintainer__ = 'Ronald Bister'
44
__email__ = 'mini.pelle@gmail.com'
55
__license__ = 'CC-BY'
6-
__version__ = '0.1'
7-
__all__ = ["NmapHost", "NmapService", "NmapParser", "NmapParserException",
8-
"NmapReport", "NmapProcess", "DictDiffer", "NmapDiff",
9-
"NmapDiffException", "ReportDecoder", "ReportEncoder"]
6+
__version__ = '0.2'
Lines changed: 115 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -112,54 +112,29 @@ def starttime(self):
112112
def endtime(self):
113113
return self._endtime
114114

115-
def add_hostname(self, hostname):
116-
"""
117-
DEPRECATED must be done in constructor
118-
(or send to private and called by the constructor
119-
may be better for param validation)
120-
:param hostname: string
121-
"""
122-
self._hostnames.append(hostname)
123-
124-
def add_service(self, nmapservice):
125-
"""
126-
DEPRECATED must be done in constructor
127-
(or send to private and called by the constructor
128-
may be better for param validation)
129-
Add a NmapService to the servicse table of NmapHost object
130-
:param nmapservice: NmapService
131-
:return boolean:
132-
:raise Exception: if wrong param
133-
"""
134-
v = False
135-
if isinstance(nmapservice, NmapService):
136-
self._services.append(nmapservice)
137-
v = True
138-
else:
139-
raise Exception("Object type should be NmapService \
140-
for add_service")
141-
return v
142-
143115
def get_ports(self):
144116
"""
145-
Retieve a list of the port used by each service of the NmapHost
146-
:return list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')]
117+
Retrieve a list of the port used by each service of the NmapHost
118+
119+
:return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')]
147120
"""
148121
return [(p.port, p.protocol) for p in self._services]
149122

150123
def get_open_ports(self):
151124
"""
152125
Same as get_ports() but only for open ports
153-
:return list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')]
126+
127+
:return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')]
154128
"""
155129
return ([(p.port, p.protocol)
156130
for p in self._services if p.state == 'open'])
157131

158132
def get_service(self, portno, protocol='tcp'):
159133
"""
160-
:param portno: int the portnumber
161-
:param protocol='tcp': string ('tcp','udp')
162-
:return NmapService or None
134+
:param portno: int the portnumber
135+
:param protocol='tcp': string ('tcp','udp')
136+
137+
:return: NmapService or None
163138
"""
164139
plist = [p for p in self._services if
165140
p.port == portno and p.protocol == protocol]
@@ -283,3 +258,109 @@ def get_dict(self):
283258

284259
def diff(self, other):
285260
return NmapDiff(self, other)
261+
262+
263+
264+
class NmapReport(object):
265+
def __init__(self, name='', raw_data=None):
266+
self._name = name
267+
self._nmaprun = {}
268+
self._scaninfo = {}
269+
self._hosts = []
270+
self._runstats = {}
271+
if raw_data is not None:
272+
self.set_raw_data(raw_data)
273+
274+
def save(self, backend):
275+
"""this fct get an NmapBackendPlugin representing the backend
276+
"""
277+
if backend is not None:
278+
#do stuff
279+
id = backend.insert(self)
280+
else:
281+
raise RuntimeError
282+
return id
283+
284+
def diff(self, other):
285+
if self.__is_consistent() and other.__is_consistent():
286+
r = NmapDiff(self, other)
287+
else:
288+
r = set()
289+
return r
290+
291+
def set_raw_data(self, raw_data):
292+
self._nmaprun = raw_data['_nmaprun']
293+
self._scaninfo = raw_data['_scaninfo']
294+
self._hosts = raw_data['_hosts']
295+
self._runstats = raw_data['_runstats']
296+
297+
@property
298+
def name(self):
299+
return self._name
300+
301+
### implement with iterators
302+
@property
303+
def scanned_hosts(self):
304+
return self._hosts
305+
306+
@property
307+
def endtime(self):
308+
return self._runstats['finished']['time']
309+
310+
@property
311+
def summary(self):
312+
return self._runstats['finished']['summary']
313+
314+
@property
315+
def elapsed(self):
316+
return self._runstats['finished']['elapsed']
317+
318+
@property
319+
def hosts_up(self):
320+
return (self._runstats['hosts']['up']
321+
if 'hosts' in self._runstats
322+
else '')
323+
324+
@property
325+
def hosts_down(self):
326+
return (self._runstats['hosts']['down']
327+
if 'hosts' in self._runstats
328+
else '')
329+
330+
@property
331+
def hosts_total(self):
332+
return (self._runstats['hosts']['total']
333+
if 'hosts' in self._runstats
334+
else '')
335+
336+
def get_raw_data(self):
337+
raw_data = {'_nmaprun': self._nmaprun,
338+
'_scaninfo': self._scaninfo,
339+
'_hosts': self._hosts,
340+
'_runstats': self._runstats}
341+
return raw_data
342+
343+
def __is_consistent(self):
344+
r = False
345+
rd = self.get_raw_data()
346+
_consistent_keys = ['_nmaprun', '_scaninfo', '_hosts', '_runstats']
347+
if (set(_consistent_keys) == set(rd.keys()) and
348+
len([k for k in rd.keys() if rd[k] is not None]) == 4):
349+
r = True
350+
return r
351+
352+
def __repr__(self):
353+
return "{0} {1} hosts: {2} {3}".format(self._nmaprun, self._scaninfo,
354+
len(self._hosts),
355+
self._runstats)
356+
357+
def get_dict(self):
358+
d = dict([("%s.%s" % (h.__class__.__name__, str(h.id)), hash(h))
359+
for h in self.scanned_hosts])
360+
d.update({'hosts_up': self.hosts_up, 'hosts_down': self.hosts_down,
361+
'hosts_total': self.hosts_total})
362+
return d
363+
364+
@property
365+
def id(self):
366+
return hash(1)

libnmap/parser.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/usr/bin/env python
22
import xml.etree.ElementTree as ET
3-
from libnmap.common import NmapHost, NmapService
4-
from libnmap.report import NmapReport
3+
from libnmap.objects import NmapHost, NmapService, NmapReport
54

65

76
class NmapParser(object):

libnmap/plugins/sqlite.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
import sqlite3
33

4-
#from libnmap.report import NmapReport
4+
#from libnmap.objects import NmapReport
55
from libnmap.plugins.backendplugin import NmapBackendPlugin
66

77

0 commit comments

Comments
 (0)