Skip to content

Commit d45b1d3

Browse files
authored
Merge pull request #35 from f-froehlich/master
Resolve #34
2 parents c3ed5cd + 3ea0b9b commit d45b1d3

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

nmap3/exceptions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ class NmapXMLParserError(Exception):
4141
def __init__(self, message="Unable to parse xml output"):
4242
self.message = message
4343
super().__init__(message)
44-
44+
45+
class NmapExecutionError(Exception):
46+
"""Exception raised when en error occurred during nmap call"""
47+

nmap3/nmap3.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from nmap3.nmapparser import NmapCommandParser
3232
from xml.etree import ElementTree as ET
3333
from xml.etree.ElementTree import ParseError
34-
from nmap3.exceptions import NmapNotInstalledError, NmapXMLParserError
34+
from nmap3.exceptions import NmapNotInstalledError, NmapXMLParserError, NmapExecutionError
3535
import xml
3636

3737
__author__ = 'Wangolo Joel ([email protected])'
@@ -58,13 +58,23 @@ def __init__(self, path=None):
5858
self.top_ports = dict()
5959
self.parser = NmapCommandParser(None)
6060
self.raw_ouput = None
61+
self.as_root = False
62+
63+
def require_root(self, required=True):
64+
"""
65+
Call this method to add "sudo" in front of nmap call
66+
"""
67+
self.as_root = required
6168

6269
def default_command(self):
6370
"""
6471
Returns the default nmap command
6572
that will be chained with all others
6673
eg nmap -oX -
6774
"""
75+
if self.as_root:
76+
return self.default_command_privileged()
77+
6878
return self.default_args.format(nmap=self.nmaptool, outarg="-oX")
6979

7080
def default_command_privileged(self):
@@ -244,19 +254,22 @@ def run_command(self, cmd):
244254
245255
@param: cmd--> the command we want run eg /usr/bin/nmap -oX - nmmapper.com --top-ports 10
246256
"""
247-
if(os.path.exists(self.nmaptool)):
248-
sub_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
257+
if (os.path.exists(self.nmaptool)):
258+
sub_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
249259
try:
250260
output, errs = sub_proc.communicate()
251261
except Exception as e:
252262
sub_proc.kill()
253-
raise(e)
263+
raise (e)
254264
else:
265+
if 0 != sub_proc.returncode:
266+
raise NmapExecutionError('Error during command: "' + ' '.join(cmd) + '"\n\n' + errs.decode('utf8'))
267+
255268
# Response is bytes so decode the output and return
256269
return output.decode('utf8').strip()
257270
else:
258271
raise NmapNotInstalledError()
259-
272+
260273
def get_xml_et(self, command_output):
261274
"""
262275
@ return xml ET
@@ -330,6 +343,8 @@ def nmap_fin_scan(self, target, args=None):
330343
@cmd nmap -sF 192.168.178.1
331344
332345
"""
346+
self.require_root()
347+
333348
xml_root = self.scan_command(self.fin_scan, target=target, args=args)
334349

335350
fin_results = self.parser.parse_nmap_idlescan(xml_root)
@@ -342,6 +357,7 @@ def nmap_syn_scan(self, target, args=None):
342357
343358
@cmd nmap -sS 192.168.178.1
344359
"""
360+
self.require_root()
345361
xml_root = self.scan_command(self.sync_scan, target=target, args=args)
346362

347363
# Use the top_port_parser
@@ -368,9 +384,11 @@ def nmap_udp_scan(self, target, args=None):
368384
369385
@cmd nmap -sU 192.168.178.1
370386
"""
387+
self.require_root()
388+
371389
if(args):
372390
assert(isinstance(args, str)), "Expected string got {0} instead".format(type(args))
373-
391+
374392
xml_root = self.scan_command(self.udp_scan, target=target, args=args)
375393

376394
tcp_results = self.parser.filter_top_ports(xml_root)

0 commit comments

Comments
 (0)