-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for targetrc file to execute commands when a target shell is spawned #859
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #859 +/- ##
=======================================
Coverage 76.33% 76.34%
=======================================
Files 313 313
Lines 26859 26883 +24
=======================================
+ Hits 20503 20524 +21
- Misses 6356 6359 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
dissect/target/tools/shell.py
Outdated
runcommands_file = pathlib.Path( | ||
getattr(target._config, "TARGETRCFILE", self.DEFAULT_RUNCOMMANDSFILE) | ||
).expanduser() | ||
self.load_runcommands(runcommands_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not in TargetCmd
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The registry shell inherits from TargetCmd. Further, the "ordinary" shell and the registry shell are not fully compatible. Therefore, I don't think it makes sense to execute the same rc file in both shells.
We could support the registry shell with a different rc file. (I asked the team this on Thursday, and they indicated to restrict the rc file to the "ordinary" shell.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JSCU-CNI would you mind giving your thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We agree it may be better to have different rc files for different shells.
Perhaps the logic of loading the targetrc file and executing commands can be stored in a superclass and inheriting classes can override where the commands are loaded from.
For example, the _load_targetrc
function and calling said function from __init__
can be moved to the ExtendedCmd
class, which has a DEFAULT_RUNCOMMANDSFILE
property of None
. Then, inheriting classes could override that property. This also leaves a good boilerplate for usages of ExtendedCmd
that are not inheriting from TargetCmd
.
0fac854
to
72ee60f
Compare
dissect/target/tools/shell.py
Outdated
def _get_targetrc_path(self) -> pathlib.Path: | ||
"""Get the path to the run commands file.""" | ||
|
||
return pathlib.Path(self.DEFAULT_RUNCOMMANDSFILE).expanduser() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does expanduser()
work for ~
in paths on windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does.
(Verified on virtual machine, and see https://docs.python.org/3/library/os.path.html#os.path.expanduser)
dissect/target/tools/shell.py
Outdated
@@ -95,6 +95,7 @@ class ExtendedCmd(cmd.Cmd): | |||
""" | |||
|
|||
CMD_PREFIX = "cmd_" | |||
DEFAULT_RUNCOMMANDSFILE = "~/.targetrc" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this to TargetCmd
and have this value be None
?
dissect/target/tools/shell.py
Outdated
@@ -96,6 +96,7 @@ class ExtendedCmd(cmd.Cmd): | |||
|
|||
CMD_PREFIX = "cmd_" | |||
_runtime_aliases = {} | |||
DEFAULT_RUNCOMMANDSFILE = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEFAULT_RUNCOMMANDSFILE = None | |
DEFAULT_RUNCOMMANDS_FILE = None |
dissect/target/tools/shell.py
Outdated
"""Get the path to the run commands file. Can return None if DEFAULT_RUNCOMMANDSFILE is not set.""" | ||
return pathlib.Path(self.DEFAULT_RUNCOMMANDSFILE).expanduser() if self.DEFAULT_RUNCOMMANDSFILE else None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Get the path to the run commands file. Can return None if DEFAULT_RUNCOMMANDSFILE is not set.""" | |
return pathlib.Path(self.DEFAULT_RUNCOMMANDSFILE).expanduser() if self.DEFAULT_RUNCOMMANDSFILE else None | |
"""Get the path to the run commands file. Can return ``None`` if ``DEFAULT_RUNCOMMANDS_FILE`` is not set.""" | |
return pathlib.Path(self.DEFAULT_RUNCOMMANDS_FILE).expanduser() if self.DEFAULT_RUNCOMMANDS_FILE else None |
dissect/target/tools/shell.py
Outdated
targetrc_path = self._get_targetrc_path() | ||
if targetrc_path is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targetrc_path = self._get_targetrc_path() | |
if targetrc_path is not None: | |
if targetrc_path := self._get_targetrc_path() is not None: |
dissect/target/tools/shell.py
Outdated
DEFAULT_RUNCOMMANDSFILE = "~/.targetrc" | ||
CONFIG_KEY_RUNCOMMANDSFILE = "TARGETRCFILE" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEFAULT_RUNCOMMANDSFILE = "~/.targetrc" | |
CONFIG_KEY_RUNCOMMANDSFILE = "TARGETRCFILE" | |
DEFAULT_RUNCOMMANDS_FILE = "~/.targetrc" | |
CONFIG_KEY_RUNCOMMANDS_FILE = "TARGETRCFILE" |
dissect/target/tools/shell.py
Outdated
"""Get the path to the run commands file.""" | ||
|
||
return pathlib.Path( | ||
getattr(self.target._config, self.CONFIG_KEY_RUNCOMMANDSFILE, self.DEFAULT_RUNCOMMANDSFILE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getattr(self.target._config, self.CONFIG_KEY_RUNCOMMANDSFILE, self.DEFAULT_RUNCOMMANDSFILE) | |
getattr(self.target._config, self.CONFIG_KEY_RUNCOMMANDS_FILE, self.DEFAULT_RUNCOMMANDS_FILE) |
dissect/target/tools/shell.py
Outdated
DEFAULT_RUNCOMMANDSFILE = "~/.targetrc.registry" | ||
CONFIG_KEY_RUNCOMMANDSFILE = "TARGETRCFILE_REGISTRY" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEFAULT_RUNCOMMANDSFILE = "~/.targetrc.registry" | |
CONFIG_KEY_RUNCOMMANDSFILE = "TARGETRCFILE_REGISTRY" | |
DEFAULT_RUNCOMMANDS_FILE = "~/.targetrc.registry" | |
CONFIG_KEY_RUNCOMMANDS_FILE = "TARGETRCFILE_REGISTRY" |
This avoids unnecessary state in the TargetCLI class
This prevents polution of the TargetCli interface.
dissect/target/tools/shell.py
Outdated
except Exception as e: | ||
log.debug("Error processing .targetrc file: %s", e) | ||
|
||
def _get_targetrc_path(self) -> Optional[pathlib.Path]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def _get_targetrc_path(self) -> Optional[pathlib.Path]: | |
def _get_targetrc_path(self) -> pathlib.Path | None: |
dissect/target/tools/shell.py
Outdated
@@ -19,7 +19,7 @@ | |||
import sys | |||
from contextlib import contextmanager | |||
from datetime import datetime, timedelta, timezone | |||
from typing import Any, BinaryIO, Callable, Iterator, TextIO | |||
from typing import Any, BinaryIO, Callable, Iterator, Optional, TextIO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from typing import Any, BinaryIO, Callable, Iterator, Optional, TextIO | |
from typing import Any, BinaryIO, Callable, Iterator, TextIO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meant to be a request changes.
Support execution of a
~/.targetrc
file when a target shell is opened, and~/.targetrc.registry
in case of the registry shell.We have decided on separate run command files because the registry and target shell are not compatible.
Additionally:
TARGETRCFILE
(andTARGETRCFILE_REGISTRY
) variables inside the target configuration file.Closes #592