diff --git a/sources/assets/exegol/load_supported_setups.sh b/sources/assets/exegol/load_supported_setups.sh index 6503e423c..a2e539947 100644 --- a/sources/assets/exegol/load_supported_setups.sh +++ b/sources/assets/exegol/load_supported_setups.sh @@ -1,15 +1,38 @@ #!/bin/zsh -# Expanding aliases. Bugfix #207 -EXEGOL_ALIASES="/opt/.exegol_aliases" -if [[ -f "$EXEGOL_ALIASES" ]]; then - source "$EXEGOL_ALIASES" -else - echo "Exiting, file $EXEGOL_ALIASES is missing" - exit 2 -fi +# Root my-resources PATH +MY_ROOT_PATH="/opt/my-resources" + +# Setup directory for user customization +MY_SETUP_PATH="$MY_ROOT_PATH/setup" + +export RED='\033[1;31m' +export BLUE='\033[1;34m' +export GREEN='\033[1;32m' +export NOCOLOR='\033[0m' + +### Echo functions + +function colorecho () { + echo -e "${BLUE}[EXEGOL] $*${NOCOLOR}" +} + +function criticalecho () { + echo -e "${RED}[EXEGOL ERROR] $*${NOCOLOR}" 2>&1 + exit 1 +} + +function criticalecho-noexit () { + echo -e "${RED}[EXEGOL ERROR] $*${NOCOLOR}" 2>&1 +} function init() { + colorecho "Initilization" + colorecho "Sourcing zshrc" + source "$HOME/.zshrc" + colorecho "Checking environment variables" + env + colorecho "Deploying /opt/my-resources" # Deploying the /opt/my-resources/ folder if not already there if [[ -d "$MY_ROOT_PATH" ]]; then # Setup basic structure @@ -19,13 +42,13 @@ function init() { echo "Exiting, 'my-resources' is disabled" exit 1 fi - + colorecho "Copying README.md to /opt/my-resources" # Copying README.md to /opt/my-resources/ (first use) [[ -f "$MY_SETUP_PATH/README.md" ]] || cp --preserve=mode /.exegol/skel/README.md "$MY_SETUP_PATH/README.md" } function deploy_zsh() { - ##### ZSH deployment + colorecho "Deploying zsh" if [[ -d "$MY_SETUP_PATH/zsh" ]]; then # TODO remove fallback 'cp' command grep -vE "^(\s*|#.*)$" "$MY_SETUP_PATH/zsh/history" >> ~/.zsh_history || cp --preserve=mode /.exegol/skel/zsh/history "$MY_SETUP_PATH/zsh/history" @@ -36,7 +59,7 @@ function deploy_zsh() { } function deploy_tmux() { - ##### TMUX deployment + colorecho "Deploying tmux" if [[ -d "$MY_SETUP_PATH/tmux" ]]; then # copy tmux/tmux.conf to ~/.tmux.conf [[ -f "$MY_SETUP_PATH/tmux/tmux.conf" ]] && cp "$MY_SETUP_PATH/tmux/tmux.conf" ~/.tmux.conf @@ -46,7 +69,7 @@ function deploy_tmux() { } function deploy_vim() { - ##### VIM deployment + colorecho "Deploying vim" local vpath if [[ -d "$MY_SETUP_PATH/vim" ]]; then # Copy vim/vimrc to ~/.vimrc @@ -63,7 +86,7 @@ function deploy_vim() { } function deploy_nvim () { - #### neovim deployment + colorecho "Deploying nvim" if [[ -d "$MY_SETUP_PATH/nvim" ]]; then mkdir -p ~/.config/ cp -r "$MY_SETUP_PATH/nvim/" ~/.config @@ -73,10 +96,11 @@ function deploy_nvim () { } function deploy_apt() { - ##### Install custom APT packages + colorecho "Deploying APT packages" local key_url local install_list - local tmpaptkeys=$(mktemp -d) + local tmpaptkeys + tmpaptkeys=$(mktemp -d) if [[ -d "$MY_SETUP_PATH/apt" ]]; then # Deploy custom apt repository cp "$MY_SETUP_PATH/apt/sources.list" /etc/apt/sources.list.d/exegol_user_sources.list @@ -85,12 +109,11 @@ function deploy_apt() { wget -nv "$key_url" -O "$tmpaptkeys/$(echo "$key_url" | md5sum | cut -d ' ' -f1).key" done if [[ -n $(find "$tmpaptkeys" -type f -name "*.key") ]]; then - gpg --no-default-keyring --keyring=$tmpaptkeys/user_custom.gpg --batch --import $tmpaptkeys/*.key && - gpg --no-default-keyring --keyring=$tmpaptkeys/user_custom.gpg --batch --output /etc/apt/trusted.gpg.d/user_custom.gpg --export --yes && + gpg --no-default-keyring --keyring="$tmpaptkeys/user_custom.gpg" --batch --import "$tmpaptkeys/*.key" && + gpg --no-default-keyring --keyring="$tmpaptkeys/user_custom.gpg" --batch --output /etc/apt/trusted.gpg.d/user_custom.gpg --export --yes && chmod 644 /etc/apt/trusted.gpg.d/user_custom.gpg fi rm -rf "$tmpaptkeys" - install_list=$(grep -vE "^(\s*|#.*)$" "$MY_SETUP_PATH/apt/packages.list" | tr "\n" " ") # Test if there is some package to install if [[ -n "$install_list" ]]; then @@ -108,7 +131,7 @@ function deploy_apt() { } function deploy_python3() { - ##### Install custom PIP3 packages + colorecho "Deploying python3 packages" if [[ -d "$MY_SETUP_PATH/python3" ]]; then # Install every pip3 packages listed in the requirements.txt file pip3 install -r "$MY_SETUP_PATH/python3/requirements.txt" @@ -120,22 +143,22 @@ function deploy_python3() { } function run_user_setup() { + colorecho "Executing user setup" # Executing user setup (or create the file) if [[ -f "$MY_SETUP_PATH/load_user_setup.sh" ]]; then - echo "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== Loading user setup ($MY_SETUP_PATH/load_user_setup.sh) ====" - echo "[Exegol] Installing [green]my-resources[/green] user's defined custom setup ..." + colorecho "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== Loading user setup ($MY_SETUP_PATH/load_user_setup.sh) ====" + colorecho "Installing my-resources user's defined custom setup ..." "$MY_SETUP_PATH"/load_user_setup.sh else - echo "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== User setup loader missing, deploying it ($MY_SETUP_PATH/load_user_setup.sh) ====" + colorecho "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== User setup loader missing, deploying it ($MY_SETUP_PATH/load_user_setup.sh) ====" cp /.exegol/skel/load_user_setup.sh "$MY_SETUP_PATH/load_user_setup.sh" chmod 760 "$MY_SETUP_PATH/load_user_setup.sh" fi - - echo "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== End of custom setups loading ====" + colorecho "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== End of custom setups loading ====" } function deploy_firefox_addons() { - ##### firefox custom addons deployment + colorecho "Deploying Firefox Add-Ons" local addon_folder local addon_list if [[ -d "$MY_SETUP_PATH/firefox/" ]]; then @@ -149,8 +172,7 @@ function deploy_firefox_addons() { else cp --preserve=mode /.exegol/skel/firefox/addons.txt "$MY_SETUP_PATH/firefox/addons.txt" fi - # shellcheck disable=SC2086 - python3 /opt/tools/firefox/user-setup.py -L $addon_list -D $addon_folder + python3 /opt/tools/firefox/user-setup.py -L "$addon_list" -D "$addon_folder" else mkdir --parents "$MY_SETUP_PATH/firefox/addons" && chmod 770 -R "$MY_SETUP_PATH/firefox/addons" cp --preserve=mode /.exegol/skel/firefox/addons.txt "$MY_SETUP_PATH/firefox/addons.txt" @@ -158,15 +180,15 @@ function deploy_firefox_addons() { } function deploy_bloodhound_config() { + colorecho "Deploying BloodHound User Config" [[ -f "$my_setup_bh_path/config.json" ]] && cp "$my_setup_bh_path/config.json" "$bh_config_homedir/config.json" } function deploy_bloodhound_customqueries_merge() { + colorecho "Merging User Custom Queries with Exegol Custom Queries for BloodHound" # Merge Exegol's customqueries.json file with the ones from my-resources local cq_merge_directory="$my_setup_bh_path/customqueries_merge" - [[ ! -d "$cq_merge_directory" ]] && cp -r /.exegol/skel/bloodhound/customqueries_merge "$cq_merge_directory" - if \ [[ -f "$bh_config_homedir/customqueries.json" ]] && \ [[ -n $(find "$cq_merge_directory" -type f -name "*.json") ]]; then @@ -175,48 +197,39 @@ function deploy_bloodhound_customqueries_merge() { } function deploy_bloodhound_customqueries_replacement() { - # Replace Exegol's customqueries.json file with the merge of ones from my-resources + colorecho "Merging User Custom Queries for BloodHound, and overwriting Exegol Custom Queries" local cq_replacement_directory="$my_setup_bh_path/customqueries_replacement" - [[ ! -d "$cq_replacement_directory" ]] && cp -r /.exegol/skel/bloodhound/customqueries_replacement "$cq_replacement_directory" - if [[ -n $(find "$cq_replacement_directory" -type f -name "*.json") ]]; then bqm --verbose --ignore-default --output-path "$bqm_output_file" -i "$cq_replacement_directory" fi } function deploy_bloodhound() { + colorecho "Deploying BloodHound" local bh_config_homedir=~/.config/bloodhound local my_setup_bh_path="$MY_SETUP_PATH/bloodhound" # Use the dry-run flag to not create the file as bqm prompts if it already exists, hence it only generates a random filename - local bqm_output_file=$(mktemp --dry-run) - + local bqm_output_file + bqm_output_file=$(mktemp --dry-run) [[ ! -d "$bh_config_homedir" ]] && mkdir -p "$bh_config_homedir" [[ ! -d "$my_setup_bh_path" ]] && cp -r /.exegol/skel/bloodhound "$my_setup_bh_path" - deploy_bloodhound_config - # If a user places Bloodhound json files in both folders merge and replacement, # replacement must be executed last to only keep the output of replacement. deploy_bloodhound_customqueries_merge deploy_bloodhound_customqueries_replacement - if [[ -f "$bqm_output_file" ]]; then mv "$bqm_output_file" "$bh_config_homedir/customqueries.json" && - echo "[Exegol] $bh_config_homedir/customqueries.json successfully replaced by $bqm_output_file" + colorecho "$bh_config_homedir/customqueries.json successfully replaced by $bqm_output_file" fi } # Starting # This procedure is supposed to be executed only once at the first startup, using a lockfile check -echo "This log file is the result of the execution of the official and personal customization script" -echo "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== Loading custom setups (/.exegol/load_supported_setups.sh) ====" - -# Root my-resources PATH -MY_ROOT_PATH="/opt/my-resources" -# Setup directory for user customization -MY_SETUP_PATH="$MY_ROOT_PATH/setup" +colorecho "This log file is the result of the execution of the official and personal customization script" +colorecho "[$(date +'%d-%m-%Y_%H-%M-%S')] ==== Loading custom setups (/.exegol/load_supported_setups.sh) ====" init diff --git a/sources/assets/firefox/requirements.txt b/sources/assets/firefox/requirements.txt index b3a74e8e5..5be48ee78 100644 --- a/sources/assets/firefox/requirements.txt +++ b/sources/assets/firefox/requirements.txt @@ -1,2 +1,3 @@ R2Log requests +cryptography \ No newline at end of file diff --git a/sources/assets/firefox/setup.py b/sources/assets/firefox/setup.py index b0e9787e4..9a824d61e 100644 --- a/sources/assets/firefox/setup.py +++ b/sources/assets/firefox/setup.py @@ -17,16 +17,18 @@ from time import sleep from R2Log import logger from glob import glob +from cryptography.hazmat.primitives.serialization import pkcs7 +from cryptography.x509.oid import NameOID PATHNAME = "/root/.mozilla/firefox/**.Exegol/" # Define addons urls urls = [ - "https://addons.mozilla.org/fr/firefox/addon/foxyproxy-standard/", - "https://addons.mozilla.org/fr/firefox/addon/darkreader/", - "https://addons.mozilla.org/fr/firefox/addon/uaswitcher/", - "https://addons.mozilla.org/fr/firefox/addon/cookie-editor/", - "https://addons.mozilla.org/fr/firefox/addon/wappalyzer/" + "https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/", + "https://addons.mozilla.org/en-US/firefox/addon/darkreader/", + "https://addons.mozilla.org/en-US/firefox/addon/uaswitcher/", + "https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/", + "https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/" ] # Define regex @@ -53,11 +55,19 @@ def download_addon(link, addon_name): addon_file.write(addon_dl.content) -def read_manifest(addon_path): +def get_addon_id(addon_path): archive = zipfile.ZipFile(addon_path, 'r') manifest = archive.read('manifest.json').decode() - # Read the id in the manifest - addon_id = re.search(reid, manifest).group(1) + try: + # Read the id in the manifest + addon_id = re.search(reid, manifest).group(1) + except: + # Read the id in the mozilla.rsa file + cert = archive.read('META-INF/mozilla.rsa') + der_cert = pkcs7.load_der_pkcs7_certificates(cert) + extension_cert = der_cert[0] + ext_cert_name = extension_cert.subject + addon_id = ext_cert_name.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value return addon_id @@ -130,6 +140,9 @@ def import_bookmarks(): if __name__ == "__main__": + # Initialize variables + install_ko = [] + # Create firefox profile Exegol logger.info("Creating Firefox profile") try: @@ -149,13 +162,20 @@ def import_bookmarks(): link, addon_name = get_link(url) # Download the addon download_addon(link, addon_name) - # Read manifest.json in the archive - addon_id = read_manifest("/tmp/" + addon_name) - install_addons(addon_name, addon_id, "/tmp/") - logger.success(f"{addon_name} installed sucessfully\n") - addon_list.append((addon_id, addon_name[0:-4], False)) - - logger.success("All addons were installed sucessfully\n") + try: + # Read manifest.json in the archive + addon_id = get_addon_id("/tmp/" + addon_name) + install_addons(addon_name, addon_id, "/tmp/") + logger.success(f"{addon_name} installed sucessfully\n") + addon_list.append((addon_id, addon_name[0:-4], False)) + except: + install_ko.append("- " + addon_name) + logger.error(f"{addon_name} could not be installed\n") + continue + if install_ko: + logger.info("All addons from the list were installed sucessfully except:\n%s\n" % "\n".join(install_ko)) + else: + logger.success("All addons from the list were installed sucessfully\n") # Run firefox to initialise profile logger.info("Initialising Firefox profile") diff --git a/sources/assets/firefox/user-setup.py b/sources/assets/firefox/user-setup.py index 6b5814d38..ea116f89b 100644 --- a/sources/assets/firefox/user-setup.py +++ b/sources/assets/firefox/user-setup.py @@ -5,7 +5,7 @@ # Date created : 07 march 2023 # Python Version : 3.* -from setup import get_link, download_addon, read_manifest, install_addons, activate_addons +from setup import get_link, download_addon, get_addon_id, install_addons, activate_addons from R2Log import logger from pathlib import Path from glob import glob @@ -15,7 +15,7 @@ import argparse PATHNAME = "/root/.mozilla/firefox/**.Exegol/" -re_links = r'^https://addons\.mozilla\.org/fr/firefox/addon/[^/]+/?$' +re_links = r'^https://addons\.mozilla\.org/[a-z]{2}(\-[A-Z]{2})?/firefox/addon/[^/]+/?$' def parse_args(): arg_parser = argparse.ArgumentParser(description="Automatically installs addons from a list or folder containing .xpi files.") @@ -26,10 +26,12 @@ def parse_args(): if __name__ == "__main__": + # Initialize variables args = parse_args() addon_links = args.addon_links addon_folder = args.addon_folder install_ok = False + install_ko = [] # Define a list containing all addons names and ids addon_list = [] @@ -47,13 +49,21 @@ def parse_args(): # Download the addon download_addon(link, addon_name) # Read manifest.json in the archive - addon_id = read_manifest("/tmp/" + addon_name) - install_addons(addon_name, addon_id, "/tmp/") - logger.success(f"{addon_name} installed sucessfully\n") - addon_list.append((addon_id, addon_name[0:-4], False)) - install_ok = True + try: + addon_id = get_addon_id("/tmp/" + addon_name) + install_addons(addon_name, addon_id, "/tmp/") + logger.success(f"{addon_name} installed sucessfully\n") + addon_list.append((addon_id, addon_name[0:-4], False)) + install_ok = True + except: + install_ko.append("- " + addon_name) + logger.error(f"{addon_name} could not be installed\n") + continue if install_ok: - logger.success("All addons from the list were installed sucessfully\n") + if install_ko: + logger.info("All addons from the list were installed sucessfully except:\n%s\n" % "\n".join(install_ko)) + else: + logger.success("All addons from the list were installed sucessfully\n") else: logger.error("No addons were found in the list %s.\n" % addon_links) @@ -61,7 +71,7 @@ def parse_args(): if glob(addon_folder + "/*.xpi"): for addon_path in glob(addon_folder + "/*.xpi"): addon_name = addon_path.split("/")[-1] - addon_id = read_manifest(addon_path) + addon_id = get_addon_id(addon_path) install_addons(addon_name, addon_id, addon_folder) logger.success(f"{addon_name} installed sucessfully\n") addon_list.append((addon_id, addon_name[0:-4], False))