-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New simple package structure: The __main__.py is the entry point to p…
…ackage with optional arguments (python3 -m swiftguard [--gui/--cli]). It starts app.py or cli.py, which in turn initiate the whole app or just the worker in cli mode. Several improvements and bugfixes
- Loading branch information
Showing
11 changed files
with
369 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
__main__.py: TODO: Headline... | ||
start in cli: python3 -m swiftguard or python3 -m swiftguard --cli | ||
or in gui: python3 -m swiftguard --gui. | ||
TODO: Description... | ||
""" | ||
|
||
# Header. | ||
__author__ = "Lennart Haack" | ||
__email__ = "[email protected]" | ||
__license__ = "GNU GPLv3" | ||
__version__ = "0.0.2" | ||
__build__ = "2023.2" | ||
__date__ = "2023-09-28" | ||
__status__ = "Prototype" | ||
|
||
# Imports. | ||
import argparse | ||
|
||
if __name__ == "__main__": | ||
# Create argument parser to let the user choose between CLI and GUI. | ||
parser = argparse.ArgumentParser( | ||
prog="swiftGuard", | ||
description=f"swiftGuard v{__version__} ({__build__})\n\n" | ||
"Anti-forensic macOS tray application designed to " | ||
"safeguard your system by monitoring USB ports. It ensures your " | ||
"device's security by automatically initiating either a system " | ||
"shutdown or hibernation if an unauthorized device connects or a " | ||
"connected device is unplugged. It offers the flexibility to whitelist" | ||
" designated devices, to select an action to be executed and to set a " | ||
"countdown timer, allowing to disarm the shutdown process." | ||
"It can be run as a CLI or as a GUI, see following options.", | ||
epilog="For more information: " | ||
"https://github.com/Lennolium/swiftGuard", | ||
formatter_class=argparse.RawDescriptionHelpFormatter, | ||
) | ||
|
||
# CLI argument. | ||
parser.add_argument( | ||
"-c", "--cli", action="store_true", help="starts in CLI mode (default)" | ||
) | ||
|
||
# GUI argument. | ||
parser.add_argument( | ||
"-g", | ||
"--gui", | ||
action="store_true", | ||
help="starts in GUI mode (recommended for desktop)", | ||
) | ||
|
||
# Parse arguments. | ||
args = parser.parse_args() | ||
|
||
# Start GUI: We just import the GUI here, because it adds a lot of | ||
# dependencies, and the CLI should be as lightweight as possible. | ||
if args.gui: | ||
from swiftguard import app | ||
|
||
app.main() | ||
|
||
# Start CLI (default). | ||
else: | ||
from swiftguard import cli | ||
|
||
cli.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
cli.py: TODO: Headline... | ||
TODO: Description... | ||
""" | ||
|
||
# Header. | ||
__author__ = "Lennart Haack" | ||
__email__ = "[email protected]" | ||
__license__ = "GNU GPLv3" | ||
__version__ = "0.0.1" | ||
__date__ = "2023-10-01" | ||
__status__ = "Prototype/Development/Production" | ||
|
||
# Imports. | ||
import signal | ||
import sys | ||
|
||
from swiftguard.utils.helpers import startup | ||
from swiftguard.utils.log import LogCount, add_handler, create_logger | ||
from swiftguard.utils.workers import WorkerUsb | ||
|
||
# Root logger and log counter. | ||
LOG_COUNT = LogCount() | ||
LOGGER = create_logger(LOG_COUNT) | ||
|
||
|
||
# Handle uncaught exceptions and log them to CRITICAL. | ||
def handle_exception(exc_type, exc_value, exc_traceback): | ||
# Do not log KeyboardInterrupt (Ctrl+C). | ||
if issubclass(exc_type, KeyboardInterrupt): | ||
sys.__excepthook__(exc_type, exc_value, exc_traceback) | ||
return | ||
|
||
LOGGER.critical( | ||
"Uncaught Exception:", | ||
exc_info=(exc_type, exc_value, exc_traceback), | ||
) | ||
|
||
|
||
def exit_handler(signum, frame): | ||
""" | ||
The exit_handler function is a signal handler that catches the | ||
SIGINT and SIGTERM signals. It then prints out a message to the | ||
log file, and exits with status 0. | ||
:param signum: Identify the signal that caused the exit_handler | ||
to be called | ||
:param frame: Reference the frame object that called function | ||
:return: The exit_handler function | ||
""" | ||
|
||
LOGGER.info("Exiting the application properly ...") | ||
sys.exit(0) | ||
|
||
|
||
def main(): | ||
""" | ||
The main function is the entry point of the standalone script. | ||
It initializes and starts the main worker loop. It is not possible | ||
to defuse the countdown if a delay is set and the script is running | ||
standalone. | ||
NOTE: For further instructions for using this script standalone, | ||
please refer to the header of this file. | ||
:return: None | ||
""" | ||
|
||
# Register handlers for clean exit of program. | ||
for sig in [signal.SIGINT, signal.SIGTERM, signal.SIGQUIT]: | ||
signal.signal(sig, exit_handler) | ||
|
||
# Set the exception hook. | ||
sys.excepthook = handle_exception | ||
|
||
# Startup. | ||
config = startup() | ||
|
||
log_dest = config["Application"]["log"].split(", ") | ||
for dest in log_dest: | ||
# Logging to file is default (can not be disabled). | ||
if dest == "file": | ||
continue | ||
elif dest == "syslog": | ||
add_handler(LOGGER, "syslog") | ||
|
||
elif dest == "stdout": | ||
add_handler(LOGGER, "stdout") | ||
|
||
# Get log level from config file and apply it to the root logger. | ||
# 1 = DEBUG, 2 = INFO, 3 = WARNING, 4 = ERROR, 5 = CRITICAL. | ||
log_level = int(config["Application"]["log_level"]) * 10 | ||
LOGGER.setLevel(log_level) | ||
|
||
# Create worker and start main worker loop. | ||
print("Start guarding the USB ports ...", file=sys.stdout) | ||
worker = WorkerUsb(config) | ||
worker.loop() | ||
|
||
# Exit program. | ||
sys.exit(0) | ||
|
||
|
||
# You can also just start the script with python3 -m swiftguard.cli | ||
# instead of python3 -m swiftguard. | ||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>KeepAlive</key> | ||
<dict> | ||
<key>SuccessfulExit</key> | ||
<false/> | ||
</dict> | ||
<key>Label</key> | ||
<string>dev.lennolium.swiftguard</string> | ||
<key>ProgramArguments</key> | ||
<array> | ||
<string>/usr/bin/open</string> | ||
<string>/Applications/swiftGuard.app</string> | ||
</array> | ||
<key>RunAtLoad</key> | ||
<true/> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[Unit] | ||
Description=swiftGuard | ||
After=multi-user.target | ||
StartLimitBurst=5 | ||
StartLimitIntervalSec=10 | ||
|
||
[Service] | ||
Type=simple | ||
Restart=on-failure | ||
RestartSec=1 | ||
User= ... TODO | ||
ExecStart=/usr/bin/python3 /path/script.py ... TODO | ||
Type=simple | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,9 +10,11 @@ | |
__author__ = "Lennart Haack" | ||
__email__ = "[email protected]" | ||
__license__ = "GNU GPLv3" | ||
__version__ = "0.0.1" | ||
__date__ = "2023-09-30" | ||
__status__ = "Prototype/Development/Production" | ||
__version__ = "0.0.2" | ||
__build__ = "2023.2" | ||
__date__ = "2023-09-28" | ||
__status__ = "Prototype" | ||
|
||
# Imports. | ||
from .log import LogCount, add_handler, create_logger | ||
from .autostart import add_autostart # noqa: F401 | ||
from .log import LogCount, add_handler, create_logger # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
autostart.py: TODO: Headline... | ||
TODO: Description... | ||
""" | ||
|
||
# Header. | ||
__author__ = "Lennart Haack" | ||
__email__ = "[email protected]" | ||
__license__ = "GNU GPLv3" | ||
__version__ = "0.0.2" | ||
__build__ = "2023.2" | ||
__date__ = "2023-09-28" | ||
__status__ = "Prototype" | ||
|
||
# Imports. | ||
import logging | ||
import os | ||
import platform | ||
import shutil | ||
|
||
# Constants. | ||
CURRENT_PLATFORM = platform.uname()[0].upper() | ||
USER_HOME = os.path.expanduser("~") | ||
APP_PATH = os.path.dirname(os.path.realpath(__file__))[:-6] | ||
CONFIG_FILE = f"{USER_HOME}/Library/Preferences/swiftguard/swiftguard.ini" | ||
LOG_FILE = f"{USER_HOME}/Library/Logs/swiftguard/swiftguard.log" | ||
|
||
# Child logger. | ||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
def add_autostart(): | ||
# TODO: docstring. | ||
# macOS: Create launch agent. | ||
if CURRENT_PLATFORM.startswith("DARWIN"): | ||
launch_agent_dest = ( | ||
f"{USER_HOME}/Library/LaunchAgents/dev.lennolium.swiftguard.plist" | ||
) | ||
try: | ||
# Create LaunchAgents directory if it does not exist. | ||
if not os.path.isdir(os.path.dirname(launch_agent_dest)): | ||
os.mkdir(os.path.dirname(launch_agent_dest)) | ||
|
||
LOGGER.info( | ||
f"Created directory " | ||
f"{os.path.dirname(launch_agent_dest)}." | ||
) | ||
|
||
# Copy the plist to the LaunchAgents directory. | ||
shutil.copy( | ||
os.path.join( | ||
APP_PATH, "install", "dev.lennolium.swiftguard.plist" | ||
), | ||
launch_agent_dest, | ||
) | ||
|
||
except Exception as e: | ||
LOGGER.error( | ||
f"Autostart could not be configured. Could not copy " | ||
f"launch agent plist to {launch_agent_dest}. \n" | ||
f"Error: {e}" | ||
) | ||
|
||
# Linux: Create systemd service (WiP). | ||
else: | ||
raise NotImplementedError("Linux is not supported yet.") | ||
# # Debian based, e.g. Ubuntu: Create systemd service. | ||
# # See https://linuxhandbook.com/create-systemd-services/ | ||
# user_systemd_dest = | ||
# f"{USER_HOME}/.config/systemd/user/" | ||
# systemd_service_dest = | ||
# "/etc/systemd/system/swiftguard.service" | ||
# systemd_service_dest_alt = " | ||
# /usr/systemd/system/swiftguard.service" | ||
# | ||
# # Non-Debian based, e.g. Arch Linux: Create systemd service. | ||
# systemd_service_dest_alt2 = | ||
# "/usr/lib/systemd/system/swiftguard.service" | ||
# | ||
# # Copy the service to the systemd directory. | ||
# shutil.copy( | ||
# os.path.join(APP_PATH, "install", "swiftguard.service"), | ||
# systemd_service_dest, | ||
# ) | ||
# | ||
# # User: Reload the systemd daemon, enable and start the | ||
# # service. | ||
# os.system("systemctl --user daemon-reload") | ||
# os.system("systemctl --user enable swiftguard.service") | ||
# os.system("systemctl --user start swiftguard.service") | ||
# | ||
# # System. | ||
# os.system("systemctl daemon-reload") | ||
# os.system("systemctl enable swiftguard.service") | ||
# os.system("systemctl start swiftguard.service") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
conf.py: TODO: Headline... | ||
TODO: Description... | ||
""" | ||
|
||
# Header. | ||
__author__ = "Lennart Haack" | ||
__email__ = "[email protected]" | ||
__license__ = "GNU GPLv3" | ||
__version__ = "0.0.2" | ||
__build__ = "2023.2" | ||
__date__ = "2023-09-28" | ||
__status__ = "Prototype" | ||
|
||
# Imports. | ||
|
||
# TODO: hier die ganzen config funktionen einfügen... |
Oops, something went wrong.