Skip to content

Commit f856d30

Browse files
committed
AutoArgparse: support bytes, better naming
1 parent 03c0c14 commit f856d30

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

scapy/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ class ExtsManager(importlib.abc.MetaPathFinder):
599599
def __init__(self):
600600
self.exts: List[ScapyExt] = []
601601
self.all_specs: Dict[str, ScapyExt.ScapyExtSpec] = {}
602+
self._loaded: List[str] = []
602603
# Add to meta_path as we are an import provider
603604
if self not in sys.meta_path:
604605
sys.meta_path.append(self)
@@ -628,6 +629,9 @@ def load(self, extension: str):
628629
629630
:param extension: the name of the extension, as installed.
630631
"""
632+
if extension in self._loaded:
633+
return
634+
631635
try:
632636
import importlib.metadata
633637
except ImportError:
@@ -686,6 +690,7 @@ def load(self, extension: str):
686690

687691
# Add to the extension list
688692
self.exts.append(ext)
693+
self._loaded.append(extension)
689694

690695
# If there are bash autocompletions, add them
691696
if ext.bash_completions:

scapy/layers/smbclient.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,18 +1088,18 @@ def close(self):
10881088
@conf.commands.register
10891089
class smbclient(CLIUtil):
10901090
r"""
1091-
A simple smbclient CLI
1091+
A simple SMB client CLI powered by Scapy
10921092
10931093
:param target: can be a hostname, the IPv4 or the IPv6 to connect to
10941094
:param UPN: the upn to use (DOMAIN/USER, DOMAIN\USER, USER@DOMAIN or USER)
10951095
:param guest: use guest mode (over NTLM)
10961096
:param ssp: if provided, use this SSP for auth.
10971097
:param kerberos_required: require kerberos
10981098
:param port: the TCP port. default 445
1099-
:param password: (string) if provided, used for auth
1100-
:param HashNt: (bytes) if provided, used for auth (NTLM)
1101-
:param HashAes256Sha96: (bytes) if provided, used for auth (Kerberos)
1102-
:param HashAes128Sha96: (bytes) if provided, used for auth (Kerberos)
1099+
:param password: if provided, used for auth
1100+
:param HashNt: if provided, used for auth (NTLM)
1101+
:param HashAes256Sha96: if provided, used for auth (Kerberos)
1102+
:param HashAes128Sha96: if provided, used for auth (Kerberos)
11031103
:param ST: if provided, the service ticket to use (Kerberos)
11041104
:param KEY: if provided, the session key associated to the ticket (Kerberos)
11051105
:param cli: CLI mode (default True). False to use for scripting
@@ -1169,6 +1169,8 @@ def __init__(
11691169
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10)
11701170
# Timeout & connect
11711171
sock.settimeout(timeout)
1172+
if debug:
1173+
print("Connecting to %s:%s" % (target, port))
11721174
sock.connect((target, port))
11731175
self.extra_create_options = []
11741176
# Wrap with the automaton

scapy/utils.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,20 +3940,24 @@ def AutoArgparse(
39403940
# Process the parameters
39413941
positional = []
39423942
noargument = []
3943+
hexarguments = []
39433944
parameters = {}
39443945
for param in inspect.signature(func).parameters.values():
39453946
if not param.annotation:
39463947
continue
39473948
noarg = False
3948-
parname = param.name
3949-
paramkwargs = {}
3949+
parname = param.name.replace("_", "-")
3950+
paramkwargs: Dict[str, Any] = {}
39503951
if param.annotation is bool:
39513952
if param.default is True:
39523953
parname = "no-" + parname
39533954
paramkwargs["action"] = "store_false"
39543955
else:
39553956
paramkwargs["action"] = "store_true"
39563957
noarg = True
3958+
elif param.annotation is bytes:
3959+
paramkwargs["type"] = str
3960+
hexarguments.append(parname)
39573961
elif param.annotation in [str, int, float]:
39583962
paramkwargs["type"] = param.annotation
39593963
else:
@@ -3971,6 +3975,14 @@ def AutoArgparse(
39713975
paramkwargs["action"] = "append"
39723976
if param.name in argsdoc:
39733977
paramkwargs["help"] = argsdoc[param.name]
3978+
if param.annotation is bytes:
3979+
paramkwargs["help"] = "(hex) " + paramkwargs["help"]
3980+
elif param.annotation is bool:
3981+
paramkwargs["help"] = "(flag) " + paramkwargs["help"]
3982+
else:
3983+
paramkwargs["help"] = (
3984+
"(%s) " % param.annotation.__name__ + paramkwargs["help"]
3985+
)
39743986
# Add to the parameter list
39753987
parameters[parname] = paramkwargs
39763988
if noarg:
@@ -3992,11 +4004,25 @@ def AutoArgparse(
39924004

39934005
# Add parameters to parser
39944006
for parname, paramkwargs in parameters.items():
3995-
parser.add_argument(parname, **paramkwargs) # type: ignore
4007+
parser.add_argument(parname, **paramkwargs)
39964008

39974009
# Now parse the sys.argv parameters
39984010
params = vars(parser.parse_args())
39994011

4012+
# Convert hex parameters if provided
4013+
for p in hexarguments:
4014+
if params[p] is not None:
4015+
try:
4016+
params[p] = bytes.fromhex(params[p])
4017+
except ValueError:
4018+
print(
4019+
conf.color_theme.fail(
4020+
"ERROR: the value of parameter %s "
4021+
"'%s' is not valid hexadecimal !" % (p, params[p])
4022+
)
4023+
)
4024+
return None
4025+
40004026
# Act as in interactive mode
40014027
conf.logLevel = 20
40024028
from scapy.themes import DefaultTheme
@@ -4011,7 +4037,7 @@ def AutoArgparse(
40114037
}
40124038
)
40134039
except AssertionError as ex:
4014-
print("ERROR: " + str(ex))
4040+
print(conf.color_theme.fail("ERROR: " + str(ex)))
40154041
parser.print_help()
40164042
return None
40174043

0 commit comments

Comments
 (0)