Skip to content

Commit 349a029

Browse files
committed
check path duringing class init, some editions
1 parent e2b901d commit 349a029

File tree

2 files changed

+64
-48
lines changed

2 files changed

+64
-48
lines changed

nmap3/nmap3.py

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,16 @@
1919
#
2020
#
2121

22-
import os
2322
import shlex
2423
import subprocess
2524
import sys
26-
import simplejson as json
2725
import argparse
2826
import asyncio
2927
from xml.etree import ElementTree as ET
3028
from xml.etree.ElementTree import ParseError
3129
from nmap3.nmapparser import NmapCommandParser
3230
from nmap3.utils import get_nmap_path, user_is_root
33-
from nmap3.exceptions import NmapNotInstalledError, NmapXMLParserError, NmapExecutionError
34-
import xml
31+
from nmap3.exceptions import NmapXMLParserError, NmapExecutionError
3532
import re
3633

3734
__author__ = 'Wangolo Joel (inquiry@nmapper.com)'
@@ -46,14 +43,14 @@ class Nmap(object):
4643
by calling nmap3.Nmap()
4744
"""
4845

49-
def __init__(self, path=None):
46+
def __init__(self, path:str=''):
5047
"""
5148
Module initialization
5249
5350
:param path: Path where nmap is installed on a user system. On linux system it's typically on /usr/bin/nmap.
5451
"""
5552

56-
self.nmaptool = path if path else get_nmap_path()
53+
self.nmaptool = get_nmap_path(path) # check path, search or raise error
5754
self.default_args = "{nmap} {outarg} - "
5855
self.maxport = 65535
5956
self.target = ""
@@ -114,7 +111,7 @@ def nmap_version(self):
114111

115112
# Unique method for repetitive tasks - Use of 'target' variable instead of 'host' or 'subnet' - no need to make difference between 2 strings that are used for the same purpose
116113
def scan_command(self, target, arg, args=None, timeout=None):
117-
self.target == target
114+
self.target = target
118115

119116
command_args = "{target} {default}".format(target=target, default=arg)
120117
scancommand = self.default_command() + command_args
@@ -216,7 +213,7 @@ def nmap_detect_firewall(self, target, arg="-sA", args=None): # requires root
216213
nmap -oX - nmmapper.com -sA
217214
@ TODO
218215
"""
219-
xml_root = self.scan_command(target=target, arg=arg, args=args)
216+
return self.scan_command(target=target, arg=arg, args=args)
220217
# TODO
221218

222219
@user_is_root
@@ -257,22 +254,26 @@ def run_command(self, cmd, timeout=None):
257254
@param: cmd--> the command we want run eg /usr/bin/nmap -oX - nmmapper.com --top-ports 10
258255
@param: timeout--> command subprocess timeout in seconds.
259256
"""
260-
if (os.path.exists(self.nmaptool)):
261-
sub_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
262-
try:
263-
output, errs = sub_proc.communicate(timeout=timeout)
264-
except Exception as e:
265-
sub_proc.kill()
266-
raise (e)
267-
else:
268-
if 0 != sub_proc.returncode:
269-
raise NmapExecutionError('Error during command: "' + ' '.join(cmd) + '"\n\n' + errs.decode('utf8'))
270-
271-
# Response is bytes so decode the output and return
272-
return output.decode('utf8').strip()
257+
sub_proc = subprocess.Popen(
258+
cmd,
259+
stdout=subprocess.PIPE,
260+
stderr=subprocess.PIPE
261+
)
262+
try:
263+
output, errs = sub_proc.communicate(timeout=timeout)
264+
except Exception as e:
265+
sub_proc.kill()
266+
raise (e)
273267
else:
274-
raise NmapNotInstalledError()
268+
if 0 != sub_proc.returncode:
269+
raise NmapExecutionError(
270+
'Error during command: "' + ' '.join(cmd) + '"\n\n' \
271+
+ errs.decode('utf8')
272+
)
273+
# Response is bytes so decode the output and return
274+
return output.decode('utf8').strip()
275275

276+
276277
def get_xml_et(self, command_output):
277278
"""
278279
@ return xml ET
@@ -309,7 +310,7 @@ class NmapScanTechniques(Nmap):
309310
7) IP Scan (-sO)
310311
"""
311312

312-
def __init__(self, path=None):
313+
def __init__(self, path:str=''):
313314
super(NmapScanTechniques, self).__init__(path=path)
314315

315316
self.sync_scan = "-sS"
@@ -350,7 +351,9 @@ def tpl(i):
350351
output = self.run_command(scan_shlex, timeout=timeout)
351352
xml_root = self.get_xml_et(output)
352353

353-
return xml_root
354+
return xml_root
355+
raise Exception("Something went wrong")
356+
354357

355358
@user_is_root
356359
def nmap_fin_scan(self, target, args=None):
@@ -442,7 +445,7 @@ class NmapHostDiscovery(Nmap):
442445
4) Disable DNS resolution (-n)
443446
"""
444447

445-
def __init__(self, path=None):
448+
def __init__(self, path:str=''):
446449
super(NmapHostDiscovery, self).__init__(path=path)
447450

448451
self.port_scan_only = "-Pn"
@@ -476,7 +479,8 @@ def tpl(i):
476479
output = self.run_command(scan_shlex, timeout=timeout)
477480
xml_root = self.get_xml_et(output)
478481

479-
return xml_root
482+
return xml_root
483+
raise Exception("Something went wrong")
480484

481485
def nmap_portscan_only(self, target, args=None):
482486
"""
@@ -523,30 +527,34 @@ def nmap_disable_dns(self, target, args=None):
523527
return results
524528

525529
class NmapAsync(Nmap):
526-
def __init__(self, path=None):
530+
def __init__(self, path:str=''):
527531
super(NmapAsync, self).__init__(path=path)
528532
self.stdout = asyncio.subprocess.PIPE
529533
self.stderr = asyncio.subprocess.PIPE
530534

531535
async def run_command(self, cmd, timeout=None):
532-
if (os.path.exists(self.nmaptool)):
533-
process = await asyncio.create_subprocess_shell(cmd,stdout=self.stdout,stderr=self.stderr)
536+
process = await asyncio.create_subprocess_shell(
537+
cmd,
538+
stdout=self.stdout,
539+
stderr=self.stderr
540+
)
534541

535-
try:
536-
data, stderr = await process.communicate()
537-
except Exception as e:
538-
raise (e)
539-
else:
540-
if 0 != process.returncode:
541-
raise NmapExecutionError('Error during command: "' + ' '.join(cmd) + '"\n\n' + stderr.decode('utf8'))
542-
543-
# Response is bytes so decode the output and return
544-
return data.decode('utf8').strip()
542+
try:
543+
data, stderr = await process.communicate()
544+
except Exception as e:
545+
raise (e)
545546
else:
546-
raise NmapNotInstalledError()
547+
if 0 != process.returncode:
548+
raise NmapExecutionError(
549+
'Error during command: "' + ' '.join(cmd) + '"\n\n' + \
550+
stderr.decode('utf8')
551+
)
552+
553+
# Response is bytes so decode the output and return
554+
return data.decode('utf8').strip()
547555

548556
async def scan_command(self, target, arg, args=None, timeout=None):
549-
self.target == target
557+
self.target = target
550558

551559
command_args = "{target} {default}".format(target=target, default=arg)
552560
scancommand = self.default_command() + command_args
@@ -611,7 +619,7 @@ async def nmap_list_scan(self, target, arg="-sL", args=None): # requires root
611619
return results
612620

613621
class NmapScanTechniquesAsync(NmapAsync,NmapScanTechniques):
614-
def __init__(self, path=None):
622+
def __init__(self, path:str=''):
615623
super(NmapScanTechniquesAsync, self).__init__(path=path)
616624
self.udp_scan = "-sU"
617625

@@ -640,7 +648,8 @@ def tpl(i):
640648
output = await self.run_command(scan_type_command, timeout=timeout)
641649
xml_root = self.get_xml_et(output)
642650

643-
return xml_root
651+
return xml_root
652+
raise Exception("Something went wrong")
644653

645654
async def nmap_udp_scan(self, target, args=None):
646655
if (args):

nmap3/utils.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,26 @@
2121
import shlex
2222
import subprocess
2323
import sys
24-
import re
2524
import os
2625
import ctypes
2726
import functools
2827

28+
from nmap3.exceptions import NmapNotInstalledError
29+
2930
__author__ = 'Wangolo Joel (inquiry@nmapper.com)'
3031
__version__ = '1.6.0'
3132
__last_modification__ = 'Sep/15/2024'
3233

33-
def get_nmap_path():
34+
def get_nmap_path(path:str='') -> str:
3435
"""
36+
Accepts path, validate it. If not valide, search nmap path
3537
Returns the location path where nmap is installed
3638
by calling which nmap
39+
If not found raises NmapNotInstalledError
3740
"""
41+
if (os.path.exists(path)):
42+
return path
43+
3844
os_type = sys.platform
3945
if os_type == 'win32':
4046
cmd = "where nmap"
@@ -44,10 +50,11 @@ def get_nmap_path():
4450
sub_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
4551

4652
try:
47-
output, errs = sub_proc.communicate(timeout=15)
53+
output, _ = sub_proc.communicate(timeout=15)
4854
except Exception as e:
4955
print(e)
5056
sub_proc.kill()
57+
raise NmapNotInstalledError()
5158
else:
5259
if os_type == 'win32':
5360
return output.decode('utf8').strip().replace("\\", "/")
@@ -62,7 +69,7 @@ def get_nmap_version():
6269
sub_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
6370

6471
try:
65-
output, errs = sub_proc.communicate(timeout=15)
72+
output, _ = sub_proc.communicate(timeout=15)
6673
except Exception as e:
6774
print(e)
6875
sub_proc.kill()
@@ -73,7 +80,7 @@ def user_is_root(func):
7380
def wrapper(*args, **kwargs):
7481
try:
7582
is_root_or_admin = (os.getuid() == 0)
76-
except AttributeError as e:
83+
except AttributeError:
7784
is_root_or_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
7885

7986
if(is_root_or_admin):

0 commit comments

Comments
 (0)