mirror of
https://github.com/markqvist/rnsh.git
synced 2024-10-01 01:15:37 -04:00
Remote command append mode (-A) for listener
This commit is contained in:
parent
21b80819c6
commit
d4cb31e220
63
README.md
63
README.md
@ -24,6 +24,12 @@ There will sometimes be breaking changes in the protocol between
|
||||
releases. Use at your own peril!
|
||||
|
||||
## Recent Changes
|
||||
### v0.0.7
|
||||
Added `-A` command line option. This listener option causes the
|
||||
remote command line to be appended to the arguments list of the
|
||||
launched program. This allows the listener to jail connections
|
||||
to a particular executable while still allowing parameters.
|
||||
|
||||
### v0.0.6
|
||||
Minor improvements in transport efficiency
|
||||
|
||||
@ -92,7 +98,7 @@ Usage:
|
||||
rnsh [--config <configdir>] [-i <identityfile>] [-s <service_name>] [-l] -p
|
||||
rnsh -l [--config <configfile>] [-i <identityfile>] [-s <service_name>]
|
||||
[-v... | -q...] [-b <period>] (-n | -a <identity_hash> [-a <identity_hash>] ...)
|
||||
[-C] [[--] <program> [<arg> ...]]
|
||||
[-A | -C] [[--] <program> [<arg> ...]]
|
||||
rnsh [--config <configfile>] [-i <identityfile>] [-s <service_name>]
|
||||
[-v... | -q...] [-N] [-m] [-w <timeout>] <destination_hash>
|
||||
[[--] <program> [<arg> ...]]
|
||||
@ -100,33 +106,34 @@ Usage:
|
||||
rnsh --version
|
||||
|
||||
Options:
|
||||
--config DIR Alternate Reticulum config directory to use
|
||||
-i FILE --identity FILE Specific identity file to use
|
||||
-s NAME --service NAME Listen on/connect to specific service name if not default
|
||||
-p --print-identity Print identity information and exit
|
||||
-l --listen Listen (server) mode. If supplied, <program> <arg>...will
|
||||
be used as the command line when the initiator does not
|
||||
provide one or when remote command is disabled. If
|
||||
<program> is not supplied, the default shell of the
|
||||
user rnsh is running under will be used.
|
||||
-b --announce PERIOD Announce on startup and every PERIOD seconds
|
||||
Specify 0 for PERIOD to announce on startup only.
|
||||
-a HASH --allowed HASH Specify identities allowed to connect
|
||||
-n --no-auth Disable authentication
|
||||
-N --no-id Disable identify on connect
|
||||
-C --no-remote-command Disable executing command line from remote
|
||||
-m --mirror Client returns with code of remote process
|
||||
-w TIME --timeout TIME Specify client connect and request timeout in seconds
|
||||
-q --quiet Increase quietness (move level up), multiple increases effect
|
||||
DEFAULT LOGGING LEVEL
|
||||
CRITICAL (silent)
|
||||
Initiator -> ERROR
|
||||
WARNING
|
||||
Listener -> INFO
|
||||
DEBUG (insane)
|
||||
-v --verbose Increase verbosity (move level down), multiple increases effect
|
||||
--version Show version
|
||||
-h --help Show this help
|
||||
--config DIR Alternate Reticulum config directory to use
|
||||
-i FILE --identity FILE Specific identity file to use
|
||||
-s NAME --service NAME Listen on/connect to specific service name if not default
|
||||
-p --print-identity Print identity information and exit
|
||||
-l --listen Listen (server) mode. If supplied, <program> <arg>...will
|
||||
be used as the command line when the initiator does not
|
||||
provide one or when remote command is disabled. If
|
||||
<program> is not supplied, the default shell of the
|
||||
user rnsh is running under will be used.
|
||||
-b --announce PERIOD Announce on startup and every PERIOD seconds
|
||||
Specify 0 for PERIOD to announce on startup only.
|
||||
-a HASH --allowed HASH Specify identities allowed to connect
|
||||
-n --no-auth Disable authentication
|
||||
-N --no-id Disable identify on connect
|
||||
-A --remote-command-as-args Concatenate remote command to argument list of <program>/shell
|
||||
-C --no-remote-command Disable executing command line from remote
|
||||
-m --mirror Client returns with code of remote process
|
||||
-w TIME --timeout TIME Specify client connect and request timeout in seconds
|
||||
-q --quiet Increase quietness (move level up), multiple increases effect
|
||||
DEFAULT LOGGING LEVEL
|
||||
CRITICAL (silent)
|
||||
Initiator -> ERROR
|
||||
WARNING
|
||||
Listener -> INFO
|
||||
DEBUG (insane)
|
||||
-v --verbose Increase verbosity (move level down), multiple increases effect
|
||||
--version Show version
|
||||
-h --help Show this help
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "rnsh"
|
||||
version = "0.0.6"
|
||||
version = "0.0.7"
|
||||
description = "Shell over Reticulum"
|
||||
authors = ["acehoss <acehoss@acehoss.net>"]
|
||||
license = "MIT"
|
||||
|
61
rnsh/args.py
61
rnsh/args.py
@ -21,7 +21,7 @@ Usage:
|
||||
rnsh [--config <configdir>] [-i <identityfile>] [-s <service_name>] [-l] -p
|
||||
rnsh -l [--config <configfile>] [-i <identityfile>] [-s <service_name>]
|
||||
[-v... | -q...] [-b <period>] (-n | -a <identity_hash> [-a <identity_hash>] ...)
|
||||
[-C] [[--] <program> [<arg> ...]]
|
||||
[-A | -C] [[--] <program> [<arg> ...]]
|
||||
rnsh [--config <configfile>] [-i <identityfile>] [-s <service_name>]
|
||||
[-v... | -q...] [-N] [-m] [-w <timeout>] <destination_hash>
|
||||
[[--] <program> [<arg> ...]]
|
||||
@ -29,33 +29,34 @@ Usage:
|
||||
rnsh --version
|
||||
|
||||
Options:
|
||||
--config DIR Alternate Reticulum config directory to use
|
||||
-i FILE --identity FILE Specific identity file to use
|
||||
-s NAME --service NAME Listen on/connect to specific service name if not default
|
||||
-p --print-identity Print identity information and exit
|
||||
-l --listen Listen (server) mode. If supplied, <program> <arg>...will
|
||||
be used as the command line when the initiator does not
|
||||
provide one or when remote command is disabled. If
|
||||
<program> is not supplied, the default shell of the
|
||||
user rnsh is running under will be used.
|
||||
-b --announce PERIOD Announce on startup and every PERIOD seconds
|
||||
Specify 0 for PERIOD to announce on startup only.
|
||||
-a HASH --allowed HASH Specify identities allowed to connect
|
||||
-n --no-auth Disable authentication
|
||||
-N --no-id Disable identify on connect
|
||||
-C --no-remote-command Disable executing command line from remote
|
||||
-m --mirror Client returns with code of remote process
|
||||
-w TIME --timeout TIME Specify client connect and request timeout in seconds
|
||||
-q --quiet Increase quietness (move level up), multiple increases effect
|
||||
DEFAULT LOGGING LEVEL
|
||||
CRITICAL (silent)
|
||||
Initiator -> ERROR
|
||||
WARNING
|
||||
Listener -> INFO
|
||||
DEBUG (insane)
|
||||
-v --verbose Increase verbosity (move level down), multiple increases effect
|
||||
--version Show version
|
||||
-h --help Show this help
|
||||
--config DIR Alternate Reticulum config directory to use
|
||||
-i FILE --identity FILE Specific identity file to use
|
||||
-s NAME --service NAME Listen on/connect to specific service name if not default
|
||||
-p --print-identity Print identity information and exit
|
||||
-l --listen Listen (server) mode. If supplied, <program> <arg>...will
|
||||
be used as the command line when the initiator does not
|
||||
provide one or when remote command is disabled. If
|
||||
<program> is not supplied, the default shell of the
|
||||
user rnsh is running under will be used.
|
||||
-b --announce PERIOD Announce on startup and every PERIOD seconds
|
||||
Specify 0 for PERIOD to announce on startup only.
|
||||
-a HASH --allowed HASH Specify identities allowed to connect
|
||||
-n --no-auth Disable authentication
|
||||
-N --no-id Disable identify on connect
|
||||
-A --remote-command-as-args Concatenate remote command to argument list of <program>/shell
|
||||
-C --no-remote-command Disable executing command line from remote
|
||||
-m --mirror Client returns with code of remote process
|
||||
-w TIME --timeout TIME Specify client connect and request timeout in seconds
|
||||
-q --quiet Increase quietness (move level up), multiple increases effect
|
||||
DEFAULT LOGGING LEVEL
|
||||
CRITICAL (silent)
|
||||
Initiator -> ERROR
|
||||
WARNING
|
||||
Listener -> INFO
|
||||
DEBUG (insane)
|
||||
-v --verbose Increase verbosity (move level down), multiple increases effect
|
||||
--version Show version
|
||||
-h --help Show this help
|
||||
'''
|
||||
|
||||
|
||||
@ -64,7 +65,8 @@ class Args:
|
||||
global usage
|
||||
try:
|
||||
argv, program_args = _split_array_at(argv, "--")
|
||||
if len(program_args) > 0:
|
||||
# need to add first arg after -- back onto argv for docopts, but only for listener
|
||||
if len(program_args) > 0 and next(filter(lambda a: a == "-l" or a == "--listen", argv), None) is not None:
|
||||
argv.append(program_args[0])
|
||||
self.program_args = program_args[1:]
|
||||
|
||||
@ -88,6 +90,7 @@ class Args:
|
||||
self.valid = False
|
||||
self.no_auth = args.get("--no-auth", None) or False
|
||||
self.allowed = args.get("--allowed", None) or []
|
||||
self.remote_cmd_as_args = args.get("--remote-command-as-args", None) or False
|
||||
self.no_remote_cmd = args.get("--no-remote-command", None) or False
|
||||
self.program = args.get("<program>", None)
|
||||
self.program_args = args.get("<arg>", None) or []
|
||||
|
28
rnsh/rnsh.py
28
rnsh/rnsh.py
@ -69,6 +69,7 @@ _retry_timer: retry.RetryThread | None = None
|
||||
_destination: RNS.Destination | None = None
|
||||
_loop: asyncio.AbstractEventLoop | None = None
|
||||
_no_remote_command = True
|
||||
_remote_cmd_as_args = False
|
||||
|
||||
|
||||
async def _check_finished(timeout: float = 0):
|
||||
@ -115,8 +116,9 @@ def _print_identity(configdir, identitypath, service_name, include_destination:
|
||||
|
||||
|
||||
async def _listen(configdir, command, identitypath=None, service_name="default", verbosity=0, quietness=0, allowed=None,
|
||||
disable_auth=None, announce_period=900, no_remote_command=True):
|
||||
disable_auth=None, announce_period=900, no_remote_command=True, remote_cmd_as_args=False):
|
||||
global _identity, _allow_all, _allowed_identity_hashes, _reticulum, _cmd, _destination, _no_remote_command
|
||||
global _remote_cmd_as_args
|
||||
log = _get_logger("_listen")
|
||||
|
||||
|
||||
@ -128,15 +130,21 @@ async def _listen(configdir, command, identitypath=None, service_name="default",
|
||||
|
||||
_cmd = command
|
||||
if _cmd is None or len(_cmd) == 0:
|
||||
shell = pwd.getpwuid(os.getuid()).pw_shell
|
||||
shell = None
|
||||
try:
|
||||
shell = pwd.getpwuid(os.getuid()).pw_shell
|
||||
except Exception as e:
|
||||
log.error(f"Error looking up shell: {e}")
|
||||
log.info(f"Using {shell} for default command.")
|
||||
_cmd = [shell]
|
||||
_cmd = [shell] if shell else None
|
||||
else:
|
||||
log.info(f"Using command {shlex.join(_cmd)}")
|
||||
|
||||
_no_remote_command = no_remote_command
|
||||
if _cmd is None and _no_remote_command:
|
||||
raise Exception(f"Unable to look up shell for {os.getlogin}, cannot proceed with -C and no <program>.")
|
||||
_remote_cmd_as_args = remote_cmd_as_args
|
||||
if (_cmd is None or len(_cmd) == 0 or _cmd[0] is None or len(_cmd[0]) == 0) \
|
||||
and (_no_remote_command or _remote_cmd_as_args):
|
||||
raise Exception(f"Unable to look up shell for {os.getlogin}, cannot proceed with -A or -C and no <program>.")
|
||||
|
||||
if disable_auth:
|
||||
_allow_all = True
|
||||
@ -603,13 +611,16 @@ def _listen_request(path, data, request_id, link_id, remote_identity, requested_
|
||||
if not remote_version <= _PROTOCOL_VERSION_DEFAULT:
|
||||
return Session.error_response("Listener<->initiator version mismatch")
|
||||
|
||||
cmd = _cmd
|
||||
cmd = _cmd.copy()
|
||||
if remote_version >= _PROTOCOL_VERSION_1:
|
||||
remote_command = data[Session.REQUEST_IDX_CMD]
|
||||
if remote_command is not None and len(remote_command) > 0:
|
||||
if _no_remote_command:
|
||||
return Session.error_response("Listener does not permit initiator to provide command.")
|
||||
cmd = remote_command
|
||||
elif _remote_cmd_as_args:
|
||||
cmd.extend(remote_command)
|
||||
else:
|
||||
cmd = remote_command
|
||||
|
||||
if not _no_remote_command and (cmd is None or len(cmd) == 0):
|
||||
return Session.error_response("No command supplied and no default command available.")
|
||||
@ -939,7 +950,8 @@ async def _rnsh_cli_main():
|
||||
allowed=args.allowed,
|
||||
disable_auth=args.no_auth,
|
||||
announce_period=args.announce,
|
||||
no_remote_command=args.no_remote_cmd)
|
||||
no_remote_command=args.no_remote_cmd,
|
||||
remote_cmd_as_args=args.remote_cmd_as_args)
|
||||
return 0
|
||||
|
||||
if args.destination is not None and args.service_name is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user