-
-
Notifications
You must be signed in to change notification settings - Fork 248
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 python runner module S28 #1320
base: master
Are you sure you want to change the base?
Changes from all commits
06b94ba
658e859
9cc672a
920fc02
4be75e4
4adb369
e4295e8
59e6d13
987150f
d6bf9c0
7b1bf5e
61c8d49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#!/bin/bash | ||
# EMBA - EMBEDDED LINUX ANALYZER | ||
# | ||
# Copyright 2024-2024 Thomas Gingele <[email protected]> | ||
# | ||
# EMBA comes with ABSOLUTELY NO WARRANTY. This is free software, and you are | ||
# welcome to redistribute it under the terms of the GNU General Public License. | ||
# See LICENSE file for usage of this software. | ||
# | ||
# EMBA is licensed under GPLv3 | ||
# | ||
# Author(s): Thomas Gingele | ||
# | ||
# Description: This is an experimental EMBA module. It is designed to run user-defined python | ||
# scripts during the analysis. | ||
# | ||
|
||
S28_python_run() { | ||
module_log_init "${FUNCNAME[0]}" | ||
module_title "Python Runner" | ||
pre_module_reporter "${FUNCNAME[0]}" | ||
|
||
local lSCRIPT_DIR="${MOD_DIR}/${FUNCNAME[0]}" | ||
local lPYTHON_SCRIPT_COUNT=${#PYTHON_SCRIPTS[@]} | ||
local lCOUNT_SUBMODULE_FINDINGS=0 | ||
local lCOUNT_TOTAL_FINDINGS=0 | ||
local lSCRIPT="" | ||
|
||
if [[ ${lPYTHON_SCRIPT_COUNT} -gt 0 ]]; then | ||
print_output "[*] ${lPYTHON_SCRIPT_COUNT} Python script/s queued for execution." | ||
|
||
for lSCRIPT in "${PYTHON_SCRIPTS[@]}"; do | ||
sub_module_title "Execution of Python runner for ${ORANGE}${lSCRIPT}${NC}" | ||
print_output "[*] Executing: ${ORANGE}${lSCRIPT_DIR}/${lSCRIPT}.py${NC}" | ||
|
||
lCOUNT_SUBMODULE_FINDINGS=$(python3 "${lSCRIPT_DIR}/${lSCRIPT}.py" | grep "FINDINGS" | sed "s/FINDINGS://") | ||
lCOUNT_TOTAL_FINDINGS=$((lCOUNT_TOTAL_FINDINGS + lCOUNT_SUBMODULE_FINDINGS)) | ||
|
||
cat "${LOG_PATH_MODULE}/${lSCRIPT}.txt" >> "${LOG_FILE}" | ||
print_output "[*] Python module ${ORANGE}${lSCRIPT}${NC} reported a total of ${ORANGE}${lCOUNT_SUBMODULE_FINDINGS}${NC} findings." | ||
done | ||
|
||
else | ||
print_output "[*] No Python scripts queued for execution." | ||
fi | ||
|
||
sub_module_title "Final results for ${FUNCNAME[0]}" | ||
print_output "Total results count: ${lCOUNT_TOTAL_FINDINGS}" | ||
module_end_log "${FUNCNAME[0]}" "${lCOUNT_TOTAL_FINDINGS}" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/python3 | ||
# pylint: disable=too-few-public-methods | ||
# to-few-public-methods: Format is treated similarly to an enum and hence | ||
# has no public methods. | ||
""" | ||
EMBA - EMBEDDED LINUX ANALYZER | ||
|
||
Copyright 2025-2025 Thomas Gingele <[email protected]> | ||
|
||
EMBA comes with ABSOLUTELY NO WARRANTY. This is free software, and you are | ||
welcome to redistribute it under the terms of the GNU General Public License. | ||
See LICENSE file for usage of this software. | ||
|
||
EMBA is licensed under GPLv3 | ||
SPDX-License-Identifier: GPL-3.0-only | ||
|
||
Author(s): Thomas Gingele | ||
|
||
Description: This file converts EMBAs formatting variables into values | ||
which can be used by Python. | ||
""" | ||
import re | ||
|
||
from os import environ | ||
|
||
|
||
class FormatMeta(type): | ||
""" | ||
Metaclass for a Singlton of type Format. | ||
""" | ||
|
||
_instances = {} | ||
|
||
def __call__(cls, *args, **kwargs): | ||
if cls not in cls._instances: | ||
instance = super().__call__(*args, **kwargs) | ||
cls._instances[cls] = instance | ||
|
||
return cls._instances[cls] | ||
|
||
|
||
class Format(metaclass=FormatMeta): | ||
""" | ||
Class holding all formatting/color codes from the EMBA environment | ||
variables as attributes. | ||
""" | ||
|
||
def __init__(self): | ||
""" | ||
This function grabs all available formatting codes | ||
from the environment variables via a regex | ||
and adds them to the Format instance as attributes. | ||
""" | ||
pattern = r"^\\033\[[;0-9]+m$" | ||
for key in environ: | ||
if re.search(pattern, environ[key]): | ||
setattr(self, key, environ[key].replace("\\033", "\x1b")) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#!/usr/bin/python3 | ||
# pylint: disable=consider-using-with, no-member | ||
# consider-using-with: The log file is opened without 'with' on purpose | ||
# to enable writing to it across methods. | ||
# no-member: Attributes of the Format class are dynamically generated during | ||
# runtime. | ||
""" | ||
EMBA - EMBEDDED LINUX ANALYZER | ||
|
||
Copyright 2024-2024 Thomas Gingele <[email protected]> | ||
|
||
EMBA comes with ABSOLUTELY NO WARRANTY. This is free software, and you are | ||
welcome to redistribute it under the terms of the GNU General Public License. | ||
See LICENSE file for usage of this software. | ||
|
||
EMBA is licensed under GPLv3 | ||
SPDX-License-Identifier: GPL-3.0-only | ||
|
||
Author(s): Thomas Gingele | ||
|
||
Description: This file contains wrapper code for custom Python modules. | ||
""" | ||
from os import _Environ | ||
from embaformatting import Format | ||
|
||
|
||
class EmbaModule(): | ||
""" | ||
Module handling class for EMBA python scripts. | ||
|
||
Functions: | ||
__init__: | ||
Create a new instance of the class and set up logging. | ||
|
||
__del__: | ||
Close module files and destroy the class instance. | ||
|
||
__write_formatted_log: | ||
Base method for logging. Should not be | ||
called by Python modules directly. | ||
|
||
log: | ||
Log a new message into the module log files. | ||
|
||
add_finding: | ||
Add a new finding to the module. This will later be | ||
used during report generation. | ||
|
||
panic: | ||
Ensures propper logging when throwing exceptions. | ||
""" | ||
|
||
def __init__(self, argv: list, env: _Environ): | ||
self.format = Format() | ||
self.findings = [] | ||
self.filename = argv[0].split("/")[-1].split('.')[0] | ||
|
||
try: | ||
self.logfile_dir = env.get('LOG_PATH_MODULE') | ||
self.logfile = open( | ||
f"{self.logfile_dir}/{self.filename}.txt", | ||
"w", | ||
encoding="utf-8" | ||
) | ||
|
||
except KeyError as key_error: | ||
err = f"Unable to determine log path for module '{self.filename}'." | ||
self.panic(err) | ||
raise key_error | ||
|
||
except PermissionError as perm_error: | ||
err = f"Access to '{self.filename}.py' denied." | ||
self.panic(err) | ||
raise perm_error | ||
|
||
except FileNotFoundError as file_not_found_error: | ||
err = f"Unable to access '{self.filename}'." | ||
self.panic(err) | ||
raise file_not_found_error | ||
|
||
def __del__(self): | ||
self.logfile.close() | ||
|
||
def __write_formatted_log(self, operator: str, text: str): | ||
lines = text.split('\n') | ||
for line in lines: | ||
self.logfile.write(f"[{operator}] {line}\n") | ||
|
||
def log(self, text: str): | ||
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
|
||
""" | ||
Creates a log entry. | ||
Supports multiple lines. | ||
|
||
Parameters: | ||
text (str): The contents of the log entry. | ||
""" | ||
self.__write_formatted_log( | ||
f"{self.format.ORANGE}*{self.format.NC}", | ||
Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'NC' member Warning
Instance of 'Format' has no 'NC' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is also intended. Since the attributes of the Format class are dynamically generated from the EMBA environment variables during runtime, the immediate class definition does not have them. Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'ORANGE' member Warning
Instance of 'Format' has no 'ORANGE' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See answer here. |
||
text | ||
) | ||
|
||
def add_finding(self, description: str): | ||
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
|
||
""" | ||
Creates a log entry. | ||
Supports multiple lines. | ||
|
||
Parameters: | ||
description (str): A description of the finding. | ||
""" | ||
self.findings.append(description) | ||
self.__write_formatted_log( | ||
f"{self.format.GREEN}F{len(self.findings)}{self.format.NC}", | ||
Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'GREEN' member Warning
Instance of 'Format' has no 'GREEN' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See answer here. Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'NC' member Warning
Instance of 'Format' has no 'NC' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See answer here. |
||
description | ||
) | ||
|
||
def panic(self, description: str): | ||
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved
Hide resolved
|
||
""" | ||
Formats and logs error messages. | ||
Does NOT terminate the script. | ||
Supports multiple lines. | ||
|
||
Parameters: | ||
description (str): A description of the error or an error message. | ||
""" | ||
self.__write_formatted_log( | ||
f"{self.format.RED}!{self.format.NC}", | ||
Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'NC' member Warning
Instance of 'Format' has no 'NC' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See answer here. Check warning Code scanning / Pylint (reported by Codacy) Instance of 'Format' has no 'RED' member Warning
Instance of 'Format' has no 'RED' member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See answer here. |
||
description | ||
) | ||
|
||
|
||
def setup_module(argv: list, env: _Environ): | ||
""" | ||
Creates a new emba module wrapper. | ||
|
||
Parameters: | ||
argv (list): The list of arguments used to start the Python process. | ||
env (_Environ): The environment variables of the Python process. | ||
|
||
Returns: | ||
A new EmbaModule class instance. | ||
""" | ||
return EmbaModule(argv, env) | ||
|
||
|
||
def shutdown_module(module: EmbaModule): | ||
""" | ||
Shut down an emba python module. | ||
This will also print the amount of findings as an | ||
interger so EMBA can parse the number. | ||
|
||
Parameters: | ||
module (EmbaModule): A class instance of EmbaModule. | ||
|
||
Returns: | ||
none | ||
""" | ||
print(f"FINDINGS:{len(module.findings)}", end="") | ||
del module |
Check warning
Code scanning / Pylint (reported by Codacy)
Too few public methods (0/2) Warning
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.
This is intended, as Format is treated like an enum. For check_project.sh runs or manual prospector checks, this warning would already be disabled with pylint: disable=R0903.