mirror of
				https://github.com/optim-enterprises-bv/secureblue.git
				synced 2025-10-31 18:37:47 +00:00 
			
		
		
		
	chore: copy config from upstream and remove dep (#593)
This commit is contained in:
		
							
								
								
									
										14
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ on: | |||||||
|   workflow_dispatch: # allow manually triggering  |   workflow_dispatch: # allow manually triggering  | ||||||
| jobs: | jobs: | ||||||
|   run_tests: |   run_tests: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-24.04 | ||||||
|     name: Install Bats and run tests |     name: Install Bats and run tests | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout repo |       - name: Checkout repo | ||||||
| @@ -17,10 +17,20 @@ jobs: | |||||||
|       - name: Setup Bats and bats libs |       - name: Setup Bats and bats libs | ||||||
|         id: setup-bats |         id: setup-bats | ||||||
|         uses: bats-core/bats-action@2104b40bb7b6c2d5110b23a26b0bf265ab8027db #v3.0.0 |         uses: bats-core/bats-action@2104b40bb7b6c2d5110b23a26b0bf265ab8027db #v3.0.0 | ||||||
|  |         with: | ||||||
|  |            support-path: "${{ github.workspace }}/.bats/bats-support" | ||||||
|  |            assert-path: "${{ github.workspace }}/.bats/bats-assert" | ||||||
|  |            detik-path: "${{ github.workspace }}/.bats/bats-detik" | ||||||
|  |            file-path: "${{ github.workspace }}/.bats/bats-file" | ||||||
|  |        | ||||||
|  |       - name: Install just | ||||||
|  |         run: |           | ||||||
|  |           sudo apt-get install just | ||||||
|  |  | ||||||
|       - name: Run tests |       - name: Run tests | ||||||
|         shell: bash |         shell: bash | ||||||
|         env: |         env: | ||||||
|           INSTALL_SCRIPT: install/install_secureblue.sh |           INSTALL_SCRIPT: install/install_secureblue.sh | ||||||
|  |           BATS_LIB_PATH: "${{ github.workspace }}/.bats" | ||||||
|         run: | |         run: | | ||||||
|           bats -p -t --verbose-run .github/workflows/tests |           bats --timing --trace --verbose-run -r .github/workflows/tests | ||||||
							
								
								
									
										31
									
								
								.github/workflows/tests/justfile_tests.bats
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/tests/justfile_tests.bats
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | #!/usr/bin/env bats | ||||||
|  |  | ||||||
|  | setup() { | ||||||
|  |     sudo mkdir -p /usr/share/ublue-os/just/ | ||||||
|  |     sudo mkdir -p /usr/share/bluebuild/justfiles/ | ||||||
|  |     sudo mkdir -p /usr/lib/ujust/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     sudo cp -fr files/system/usr/lib/ujust /usr/lib/ujust | ||||||
|  |     sudo cp -f files/system/usr/bin/ujust /usr/bin/ujust | ||||||
|  |     sudo cp -f files/system/usr/share/ublue-os/just/60-custom.just /usr/share/ublue-os/just/ | ||||||
|  |     sudo cp -f files/system/usr/share/ublue-os/justfile /usr/share/ublue-os/ | ||||||
|  |     sudo cp -f files/justfiles/*.just /usr/share/bluebuild/justfiles/ | ||||||
|  |     for filepath in /usr/share/bluebuild/justfiles/*.just; do | ||||||
|  |         sudo sh -c "echo \"import '$filepath'\" >> /usr/share/ublue-os/just/60-custom.just" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @test "Ensure ujust is configured correctly for tests" { | ||||||
|  |     run ujust logs-this-boot | ||||||
|  |     [ "$status" -eq 0 ] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @test "Ensure motd toggle functions properly" { | ||||||
|  |     run ujust toggle-user-motd | ||||||
|  |     [ "$status" -eq 0 ] | ||||||
|  |     [ -f "${HOME}/.config/no-show-user-motd" ] | ||||||
|  |     run ujust toggle-user-motd | ||||||
|  |     [ "$status" -eq 0 ] | ||||||
|  |     [ ! -f "${HOME}/.config/no-show-user-motd" ] | ||||||
|  | } | ||||||
| @@ -10,11 +10,7 @@ After rebasing to secureblue, follow the following steps in order. | |||||||
| If you are using an nvidia image, run this after installation: | If you are using an nvidia image, run this after installation: | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| rpm-ostree kargs \ | ujust set-kargs-nvidia | ||||||
|     --append-if-missing=rd.driver.blacklist=nouveau \ |  | ||||||
|     --append-if-missing=modprobe.blacklist=nouveau \ |  | ||||||
|     --append-if-missing=nvidia-drm.modeset=1 \ |  | ||||||
|     --append-if-missing=nvidia-drm.fbdev=1 |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| You may also need this (solves flickering and luks issues on some nvidia hardware): | You may also need this (solves flickering and luks issues on some nvidia hardware): | ||||||
|   | |||||||
							
								
								
									
										379
									
								
								files/justfiles/audit.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								files/justfiles/audit.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | |||||||
|  | # Audit secureblue | ||||||
|  | audit-secureblue: | ||||||
|  |     #!/bin/bash | ||||||
|  |  | ||||||
|  |     STATUS_SUCCESS="SUCCESS" | ||||||
|  |     STATUS_WARNING="WARNING" | ||||||
|  |     STATUS_FAILURE="FAILURE" | ||||||
|  |     print_status() { | ||||||
|  |         local check_name="$1" | ||||||
|  |         local status="$2" | ||||||
|  |  | ||||||
|  |         local color_code | ||||||
|  |         case "$status" in | ||||||
|  |             $STATUS_SUCCESS) color_code=32 ;; # Green | ||||||
|  |             $STATUS_WARNING) color_code=33 ;; # Yellow | ||||||
|  |             $STATUS_FAILURE) color_code=31 ;;    # Red | ||||||
|  |             *) color_code=0 ;; | ||||||
|  |         esac | ||||||
|  |  | ||||||
|  |         local formatted_status | ||||||
|  |         formatted_status=$(printf "%*s" $(( (7 + ${#status}) / 2 )) "$status") | ||||||
|  |         formatted_status=$(printf "%-7s" "$formatted_status") | ||||||
|  |  | ||||||
|  |         printf "%-64s [ \033[%dm%s\033[0m ]\n" "$check_name"... "$color_code" "$formatted_status" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     hasPermission() { | ||||||
|  |         local permissions=$1 | ||||||
|  |         local prefix=$2 | ||||||
|  |         local query=$3 | ||||||
|  |         local line=$(grep "^${prefix}=" <<< "$permissions" | sed -e "s/^${prefix}=//" -e "s/#.*//") | ||||||
|  |         IFS=';' read -r -a list <<< "$line" | ||||||
|  |         for p in ${list[@]}; do | ||||||
|  |             if [[ "$p" =~ ^$query$ ]]; then | ||||||
|  |                 return | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |         return 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     KARGS=$(rpm-ostree kargs) | ||||||
|  |     KARGS_LIST=( | ||||||
|  |         "init_on_alloc=1" | ||||||
|  |         "init_on_free=1" | ||||||
|  |         "slab_nomerge" | ||||||
|  |         "page_alloc.shuffle=1" | ||||||
|  |         "randomize_kstack_offset=on" | ||||||
|  |         "vsyscall=none" | ||||||
|  |         "lockdown=confidentiality" | ||||||
|  |         "random.trust_cpu=off" | ||||||
|  |         "random.trust_bootloader=off" | ||||||
|  |         "iommu=force" | ||||||
|  |         "intel_iommu=on" | ||||||
|  |         "amd_iommu=force_isolation" | ||||||
|  |         "iommu.passthrough=0" | ||||||
|  |         "iommu.strict=1" | ||||||
|  |         "pti=on" | ||||||
|  |         "module.sig_enforce=1" | ||||||
|  |         "mitigations=auto,nosmt" | ||||||
|  |         "spectre_v2=on" | ||||||
|  |         "spec_store_bypass_disable=on" | ||||||
|  |         "l1d_flush=on" | ||||||
|  |         "gather_data_sampling=force" | ||||||
|  |         "efi=disable_early_pci_dma" | ||||||
|  |         "debugfs=off" | ||||||
|  |         "ia32_emulation=0" | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     for karg in "${KARGS_LIST[@]}"; do | ||||||
|  |         KARG_TEST_STRING="Checking for $karg karg" | ||||||
|  |         if echo "$KARGS" | grep -q "$karg"; then | ||||||
|  |             print_status "$KARG_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |         else | ||||||
|  |             print_status "$KARG_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     SYSCTL_TEST_STRING="Ensuring no sysctl overrides" | ||||||
|  |     readarray -t sysctl_hardening_conf < <(grep -v -E -e "^#" -e "^$" </usr/etc/sysctl.d/hardening.conf) | ||||||
|  |     declare -A sysctl_hardening | ||||||
|  |     for line in "${sysctl_hardening_conf[@]}"; do | ||||||
|  |         parameter="$(sed -E -e "s/(.*) = .*/\1/"  <<<"$line")" | ||||||
|  |         value="$(sed -E "s/.* = (.*)/\1/" <<<"$line")" | ||||||
|  |         sysctl_hardening["$parameter"]+="$value" | ||||||
|  |     done | ||||||
|  |     sysctl_results="$(sysctl -a 2> >(grep -v "sysctl: permission denied on key "))" | ||||||
|  |     sysctl_errors=() | ||||||
|  |     for sysctl_parameter in "${!hardening[@]}"; do | ||||||
|  |         hardened_parameter_value="${hardening["$sysctl_parameter"]}" | ||||||
|  |         parameter_name="$(sed -E -e "s/\./\\\./g" -e "s/\*/\.\*/" <<<"$sysctl_parameter")" | ||||||
|  |         readarray -t sysctl_parameter_values < <(grep -E "^$key = " <<<"$sysctl_results") | ||||||
|  |         for parameter_value in "${sysctl_parameter_values[@]}"; do | ||||||
|  |             parameter_value="$(sed -E  -e "s/.* = (.*)/\1/" -e "s/\t/ /g" <<<"$result" | tr -s " " )" | ||||||
|  |             if [[ "$parameter_value" != "$hardened_parameter_value" && ("$hardened_parameter_value" != 0 && "$parameter_value" != disabled) ]]; then | ||||||
|  |                 sysctl_errors+=("$sysctl_parameter should be $hardened_parameter_value, found $parameter_value") | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |     done | ||||||
|  |     if [[ "${#sysctl_errors}" == 0 ]] && diff /usr/etc/sysctl.d/hardening.conf /etc/sysctl.d/hardening.conf > /dev/null; then | ||||||
|  |         print_status "$SYSCTL_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$SYSCTL_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         for error in "${sysctl_errors[@]}"; do | ||||||
|  |             echo "> $error" | ||||||
|  |         done | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     SIGNED_IMAGE_TEST_STRING="Ensuring a signed image is in use" | ||||||
|  |     if rpm-ostree status | grep -q "● ostree-image-signed"; then | ||||||
|  |         print_status "$SIGNED_IMAGE_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$SIGNED_IMAGE_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     MODPROBE_TEST_STRING="Ensuring no modprobe overrides" | ||||||
|  |     readarray -t unwanted_modules < <(comm -12 <(lsmod | cut -f 1 -d " " | sort) <(cat /usr/etc/modprobe.d/blacklist.conf | grep -E '^(blacklist)|(install)' | cut -f 2 -d " " | sort)) | ||||||
|  |     if [[ "${#unwanted_modules[@]}" == 0 ]] && diff /usr/etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf > /dev/null; then | ||||||
|  |         print_status "$MODPROBE_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$MODPROBE_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         for module in "${unwanted_modules[@]}"; do | ||||||
|  |             echo "> $module is in blacklist.conf but it is loaded" | ||||||
|  |             if [[ "$module" == "bluetooth" ]]; then | ||||||
|  |                 bluetooth_loaded=true | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     PTRACE_TEST_STRING="Ensuring ptrace is forbidden" | ||||||
|  |     if [[ "$(cat /proc/sys/kernel/yama/ptrace_scope)" == 3 ]]; then | ||||||
|  |         print_status "$PTRACE_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$PTRACE_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         ptrace_allowed=true | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     AUTHSELECT_TEST_STRING="Ensuring no authselect overrides" | ||||||
|  |     if diff /usr/etc/authselect /etc/authselect --suppress-common-lines -r > /dev/null; then | ||||||
|  |         print_status "$AUTHSELECT_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$AUTHSELECT_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     CONTAINER_POLICY_TEST_STRING="Ensuring no container policy overrides" | ||||||
|  |     if diff /usr/etc/containers/policy.json /etc/containers/policy.json > /dev/null && [ ! -f $HOME/.config/containers/policy.json ]; then | ||||||
|  |         print_status "$CONTAINER_POLICY_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$CONTAINER_POLICY_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     USBGUARD_TEST_STRING="Ensuring usbguard is active" | ||||||
|  |     if systemctl is-active --quiet usbguard; then | ||||||
|  |         print_status "$USBGUARD_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$USBGUARD_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     CHRONYD_TEST_STRING="Ensuring chronyd is active" | ||||||
|  |     if systemctl is-active --quiet chronyd; then | ||||||
|  |         print_status "$CHRONYD_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$CHRONYD_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     SECUREDNS_TEST_STRING="Ensuring system DNS resolution is secure" | ||||||
|  |     if systemctl is-active --quiet systemd-resolved; then | ||||||
|  |         DNSSEC_STATUS="$(cat /etc/systemd/resolved.conf.d/10-securedns.conf | grep "DNSSEC")" | ||||||
|  |         DOT_STATUS="$(cat /etc/systemd/resolved.conf.d/10-securedns.conf | grep "DNSOverTLS")" | ||||||
|  |         if [[ "$DNSSEC_STATUS" == "DNSSEC=true" && "$DOT_STATUS" == "DNSOverTLS=true" ]]; then | ||||||
|  |             print_status "$SECUREDNS_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |         else | ||||||
|  |             print_status "$SECUREDNS_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         fi | ||||||
|  |     else | ||||||
|  |         print_status "$SECUREDNS_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     BASH_TEST_STRING="Ensuring bash environment lockdown" | ||||||
|  |     BASH_ENV_FILES=(~/.bashrc ~/.bash_profile) | ||||||
|  |     all_locked=1 | ||||||
|  |  | ||||||
|  |     for file in "${BASH_ENV_FILES[@]}"; do | ||||||
|  |         if [ -f "$file" ]; then | ||||||
|  |             if lsattr "$file" 2>/dev/null | awk '{print $1}' | grep -q 'i'; then | ||||||
|  |                 continue | ||||||
|  |             else | ||||||
|  |                 all_locked=0 | ||||||
|  |                 break | ||||||
|  |             fi | ||||||
|  |         else | ||||||
|  |             all_locked=0 | ||||||
|  |             break | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     if [ "$all_locked" -eq 1 ]; then | ||||||
|  |         print_status "$BASH_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$BASH_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     WHEEL_TEST_STRING="Ensuring user is not a member of wheel" | ||||||
|  |     if groups | grep -q "\bwheel\b"; then | ||||||
|  |         print_status "$WHEEL_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     else | ||||||
|  |         print_status "$WHEEL_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     GNOME_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for GNOME" | ||||||
|  |     if [ -f "/etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf" ]; then | ||||||
|  |         print_status "$GNOME_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$GNOME_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     PLASMA_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for KDE Plasma" | ||||||
|  |     if [ -f "/etc/systemd/user/plasma-kwin_wayland.service.d/override.conf" ]; then | ||||||
|  |         print_status "$PLASMA_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$PLASMA_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     SWAY_XWAYLAND_TEST_STRING="Ensuring xwayland is disabled for Sway" | ||||||
|  |     if [ -f "/etc/sway/config.d/99-noxwayland.conf" ]; then | ||||||
|  |         print_status "$SWAY_XWAYLAND_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$SWAY_XWAYLAND_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     EXTENSIONS_TEST_STRING="Ensuring GNOME user extensions are disabled" | ||||||
|  |     if command -v gnome-shell &> /dev/null; then | ||||||
|  |         if [ "$(gsettings get org.gnome.shell allow-extension-installation)" = "false" ]; then | ||||||
|  |             print_status "$EXTENSIONS_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |         else | ||||||
|  |             print_status "$EXTENSIONS_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     SELINUX_TEST_STRING="Ensuring SELinux is in Enforcing mode" | ||||||
|  |     if [ "$(getenforce)" = "Enforcing" ]; then | ||||||
|  |         print_status "$SELINUX_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$SELINUX_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     ENVIRONMENT_TEST_STRING="Ensuring no environment file overrides" | ||||||
|  |     if diff /usr/etc/environment /etc/environment > /dev/null; then | ||||||
|  |         print_status "$ENVIRONMENT_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$ENVIRONMENT_TEST_STRING" "$STATUS_WARNING" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     GHNS_TEST_STRING="Ensuring KDE GHNS is disabled" | ||||||
|  |     KDE_GLOBALS_FILE="/etc/xdg/kdeglobals" | ||||||
|  |     if test -e $KDE_GLOBALS_FILE; then | ||||||
|  |         GHNS_STRING="$(grep 'ghns=false' $KDE_GLOBALS_FILE)" | ||||||
|  |         if [[ $GHNS_STRING == "ghns=false" ]]; then | ||||||
|  |             print_status "$GHNS_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |         else | ||||||
|  |             print_status "$GHNS_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     HARDENED_MALLOC_TEST_STRING="Ensuring hardened_malloc is set in ld.so.preload" | ||||||
|  |     if diff /usr/etc/ld.so.preload /etc/ld.so.preload > /dev/null; then | ||||||
|  |         print_status "$HARDENED_MALLOC_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$HARDENED_MALLOC_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     SECUREBOOT_TEST_STRING="Ensuring secure boot is enabled" | ||||||
|  |     if [ "$(mokutil --sb-state)" == "SecureBoot enabled" ]; then | ||||||
|  |         print_status "$SECUREBOOT_TEST_STRING" "$STATUS_SUCCESS" | ||||||
|  |     else | ||||||
|  |         print_status "$SECUREBOOT_TEST_STRING" "$STATUS_FAILURE" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if command -v flatpak &> /dev/null; then | ||||||
|  |         remotes="$(flatpak remotes -d)" | ||||||
|  |         while read -r remote ; do | ||||||
|  |             ref="$(cut -f 1 <<<"$remote")" | ||||||
|  |             url="$(cut -f 3 <<< "$remote")" | ||||||
|  |             subset="$(cut -f 5 <<< "$remote")" | ||||||
|  |             remote_string="Auditing flatpak remote $ref" | ||||||
|  |             if [[ "$url" != "https://dl.flathub.org/repo/" && "$url" != "https://dl.flathub.org/beta-repo/" ]]; then | ||||||
|  |                 print_status "$remote_string" "$STATUS_FAILURE" | ||||||
|  |                 echo "> $ref is configured with an unknown url!" | ||||||
|  |             elif [ "$subset" != "verified" ]; then | ||||||
|  |                 print_status "$remote_string" "$STATUS_FAILURE" | ||||||
|  |                 echo "> $ref is not a verified repo!" | ||||||
|  |             else | ||||||
|  |                 print_status "$remote_string" "$STATUS_SUCCESS" | ||||||
|  |             fi | ||||||
|  |         done <<< "$remotes" | ||||||
|  |  | ||||||
|  |         declare -A flatpaks | ||||||
|  |         while read -r ref version; do | ||||||
|  |             flatpaks+=(["${ref}"]="${ref}//${version}") | ||||||
|  |         done < <(flatpak list | sort -k 1 | cut --fields 2,4) | ||||||
|  |  | ||||||
|  |         for f in ${!flatpaks[@]}; do | ||||||
|  |             warnings=() | ||||||
|  |             status="$STATUS_SUCCESS" | ||||||
|  |             fullref=${flatpaks["$f"]} | ||||||
|  |             permissions=$(flatpak info --show-permissions "$fullref") | ||||||
|  |  | ||||||
|  |             if hasPermission "$permissions" "shared" "network"; then | ||||||
|  |                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||||
|  |                 warnings+=("> $f has network access!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --unshare=network $f'") | ||||||
|  |             fi | ||||||
|  |             if hasPermission "$permissions" "sockets" "x11" && ! hasPermission "$permissions" "sockets" "fallback-x11"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f has x11 access!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --nosocket=x11 $f'") | ||||||
|  |             fi | ||||||
|  |             if hasPermission "$permissions" "sockets" "session-bus"; then | ||||||
|  |                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||||
|  |                 warnings+=("> $f has access to the D-Bus session bus!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --nosocket=session-bus $f'") | ||||||
|  |             fi | ||||||
|  |             if hasPermission "$permissions" "sockets" "system-bus"; then | ||||||
|  |                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||||
|  |                 warnings+=("> $f has access to the D-Bus system bus!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --nosocket=system-bus $f'") | ||||||
|  |             fi | ||||||
|  |             if ! hasPermission "$permissions" "LD_PRELOAD" .*"/libhardened_malloc.so"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f is not requesting hardened_malloc!") | ||||||
|  |                 warnings+=("> To enable it run:") | ||||||
|  |                 warnings+=("> 'ujust harden-flatpak $f'") | ||||||
|  |             fi | ||||||
|  |             if ! hasPermission "$permissions" "filesystems" "host-os:ro"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f is missing host-os:ro permission,") | ||||||
|  |                 warnings+=("> which is needed to load hardened_malloc!") | ||||||
|  |                 warnings+=("> To add it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --filesystem=host-os:ro $f'") | ||||||
|  |             fi | ||||||
|  |             if [[ "$bluetooth_loaded" == "true" ]] && hasPermission "$permissions" "features" "bluetooth"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f has bluetooth access!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --disallow=bluetooth $f'") | ||||||
|  |             fi | ||||||
|  |             if [[ "$ptrace_allowed" == "true" ]] && hasPermission "$permissions" "features" "devel"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f has ptrace access!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --disallow=devel $f'") | ||||||
|  |             fi | ||||||
|  |             if hasPermission "$permissions" "shared" "ipc"; then | ||||||
|  |                 status="$STATUS_FAILURE" | ||||||
|  |                 warnings+=("> $f has inter-process communications access!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --unshare=ipc $f'") | ||||||
|  |             fi | ||||||
|  |             if hasPermission "$permissions" "devices" "all"; then | ||||||
|  |                 [[ "$status" != "$STATUS_FAILURE" ]] && status="$STATUS_WARNING" | ||||||
|  |                 warnings+=("> $f has device=all permission,") | ||||||
|  |                 warnings+=("> granting access to GPU, input devices, raw USB, and virtualization,") | ||||||
|  |                 warnings+=("> and introducing a vector for sandbox escapes!") | ||||||
|  |                 warnings+=("> To remove it use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --nodevice=all $f'") | ||||||
|  |                 warnings+=("> We recommend you enable device=dri to grant GPU access, if needed by the app") | ||||||
|  |                 warnings+=("> To add GPU access use Flatseal or run:") | ||||||
|  |                 warnings+=("> 'flatpak override -u --device=dri $f'") | ||||||
|  |             fi | ||||||
|  |             flatpak_test_string="Auditing $f" | ||||||
|  |             print_status "$flatpak_test_string" "$status" | ||||||
|  |             for warning in "${warnings[@]}"; do | ||||||
|  |                 echo "$warning" | ||||||
|  |             done | ||||||
|  |         done | ||||||
|  |     fi | ||||||
| @@ -1,5 +1,17 @@ | |||||||
| alias brew := install-brew | alias brew := install-brew | ||||||
|  |  | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
| # Install Homebrew (Brew is now included by default. This command remains included for utility.) | # Install Homebrew (Brew is now included by default. This command remains included for utility.) | ||||||
| install-brew: | install-brew: | ||||||
|     #!/usr/bin/env bash |     #!/usr/bin/env bash | ||||||
|   | |||||||
							
								
								
									
										320
									
								
								files/justfiles/dns.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								files/justfiles/dns.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,320 @@ | |||||||
|  | # setup system DNS resolution | ||||||
|  | dns-selector: | ||||||
|  |     #! /bin/run0 /bin/bash | ||||||
|  |     # constants | ||||||
|  |     readonly resolved_conf="/etc/systemd/resolved.conf.d/10-securedns.conf" | ||||||
|  |     readonly policy_file="/etc/chromium/policies/managed/10-securedns-browser.json" | ||||||
|  |     mkdir -p /etc/systemd/resolved.conf.d/ | ||||||
|  |     mkdir -p /etc/chromium/policies/managed/ | ||||||
|  |     # variables | ||||||
|  |     valid_input="0" | ||||||
|  |     resolver_selection="" | ||||||
|  |     resolver_subselection="" | ||||||
|  |     resolver_has_second_ip="" | ||||||
|  |     resolver_supports_ipv6="" | ||||||
|  |     resolver_ipv4_address="" | ||||||
|  |     resolver_ipv4_address_2="" | ||||||
|  |     resolver_ipv6_address="" | ||||||
|  |     resolver_ipv6_address_2="" | ||||||
|  |     resolver_hostname="" | ||||||
|  |     resolver_https_address="" | ||||||
|  |     set_browser_policy="" | ||||||
|  |  | ||||||
|  |     echo "Below will be some options to set the DNS resolver for systemd-resolved." | ||||||
|  |     echo "All resolvers support DNS-over-TLS (DoT) or DNS-over-QUIC (DoQ), DNS-over-HTTPS (DoH), and DNSSEC." | ||||||
|  |     echo "Please select which DNS resolver you would like to set:" | ||||||
|  |     echo "    0) Network Resolver - security may vary (system default state)" | ||||||
|  |     echo "    1) Control D - has content filtering, anycast" | ||||||
|  |     echo "    2) Mullvad - has content filtering, anycast" | ||||||
|  |     echo "    3) Cloudflare - very fast with some data collection, anycast" | ||||||
|  |     echo "    4) DNSForge - powerful filtering but can be very slow" | ||||||
|  |     echo "    5) Custom Resolver - use a custom resolver (must support DoT/DoQ and DNSSEC, DoH support is also required to set a browser policy should that be desired)" | ||||||
|  |     while [[ "$valid_input" == "0" ]]; do | ||||||
|  |         read -p "Selection [0-5]: " resolver_selection | ||||||
|  |         if [[ "$resolver_selection" == [012345]* ]]; then | ||||||
|  |             valid_input="1" | ||||||
|  |         else | ||||||
|  |             echo "That is not a valid selection." | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |     valid_input="0" | ||||||
|  |  | ||||||
|  |     echo "" # blank space | ||||||
|  |     case "$resolver_selection" in | ||||||
|  |         0) | ||||||
|  |             echo "Resetting resolved to default state." | ||||||
|  |             if [[ -f "$policy_file" ]]; then | ||||||
|  |                 rm $policy_file | ||||||
|  |                 echo "Removed browser policy." | ||||||
|  |             fi | ||||||
|  |             cp /usr$resolved_conf $resolved_conf | ||||||
|  |             systemctl restart systemd-resolved | ||||||
|  |             echo "Configuration file for resolved reset and service restarted." | ||||||
|  |             exit 0 | ||||||
|  |             ;; | ||||||
|  |         1) | ||||||
|  |             resolver_has_second_ip="y" | ||||||
|  |             resolver_supports_ipv6="y" | ||||||
|  |             echo "Setting resolver Control D." | ||||||
|  |             echo "What content would you like to filter:" | ||||||
|  |             echo "    0) No filtering" | ||||||
|  |             echo "    1) Malware: Malware filtering" | ||||||
|  |             echo "    2) Standard: Malware + ad and tracker filtering" | ||||||
|  |             echo "    3) Social: Standard + social media filtering" | ||||||
|  |             echo "    4) Family: Social + adult content filtering (also enables safe search in major search engines)" | ||||||
|  |             while [[ "$valid_input" == "0" ]]; do | ||||||
|  |                 read -p "Selection [0-4]: " resolver_subselection | ||||||
|  |                 if [[ "$resolver_subselection" == [01234]* ]]; then | ||||||
|  |                     valid_input="1" | ||||||
|  |                 else | ||||||
|  |                     echo "That is not a valid selection." | ||||||
|  |                 fi | ||||||
|  |             done | ||||||
|  |             valid_input="0" | ||||||
|  |             case "$resolver_subselection" in | ||||||
|  |                 0) | ||||||
|  |                     resolver_ipv4_address="76.76.2.0" | ||||||
|  |                     resolver_ipv4_address_2="76.76.10.0" | ||||||
|  |                     resolver_ipv6_address="2606:1a40::" | ||||||
|  |                     resolver_ipv6_address_2="2606:1a40:1::" | ||||||
|  |                     resolver_hostname="p0.freedns.controld.com" | ||||||
|  |                     resolver_https_address="https://freedns.controld.com/p0" | ||||||
|  |                     ;; | ||||||
|  |                 1) | ||||||
|  |                     resolver_ipv4_address="76.76.2.1" | ||||||
|  |                     resolver_ipv4_address_2="76.76.10.1" | ||||||
|  |                     resolver_ipv6_address="2606:1a40::1" | ||||||
|  |                     resolver_ipv6_address_2="2606:1a40:1::1" | ||||||
|  |                     resolver_hostname="p1.freedns.controld.com" | ||||||
|  |                     resolver_https_address="https://freedns.controld.com/p1" | ||||||
|  |                     ;; | ||||||
|  |                 2) | ||||||
|  |                     resolver_ipv4_address="76.76.2.2" | ||||||
|  |                     resolver_ipv4_address_2="76.76.10.2" | ||||||
|  |                     resolver_ipv6_address="2606:1a40::2" | ||||||
|  |                     resolver_ipv6_address_2="2606:1a40:1::2" | ||||||
|  |                     resolver_hostname="p2.freedns.controld.com" | ||||||
|  |                     resolver_https_address="https://freedns.controld.com/p2" | ||||||
|  |                     ;; | ||||||
|  |                 3) | ||||||
|  |                     resolver_ipv4_address="76.76.2.3" | ||||||
|  |                     resolver_ipv4_address_2="76.76.10.3" | ||||||
|  |                     resolver_ipv6_address="2606:1a40::3" | ||||||
|  |                     resolver_ipv6_address_2="2606:1a40:1::3" | ||||||
|  |                     resolver_hostname="p3.freedns.controld.com" | ||||||
|  |                     resolver_https_address="https://freedns.controld.com/p3" | ||||||
|  |                     ;; | ||||||
|  |                 4) | ||||||
|  |                     resolver_ipv4_address="76.76.2.4" | ||||||
|  |                     resolver_ipv4_address_2="76.76.10.4" | ||||||
|  |                     resolver_ipv6_address="2606:1a40::4" | ||||||
|  |                     resolver_ipv6_address_2="2606:1a40:1::4" | ||||||
|  |                     resolver_hostname="family.freedns.controld.com" | ||||||
|  |                     resolver_https_address="https://freedns.controld.com/family" | ||||||
|  |                     ;; | ||||||
|  |             esac | ||||||
|  |             ;; | ||||||
|  |         2) | ||||||
|  |             resolver_has_second_ip="n" | ||||||
|  |             resolver_supports_ipv6="y" | ||||||
|  |             echo "Setting resolver Mullvad." | ||||||
|  |             echo "What content would you like to filter:" | ||||||
|  |             echo "    0) No filtering" | ||||||
|  |             echo "    1) Standard: Ad and tracker filtering" | ||||||
|  |             echo "    2) Base: Standard + malware filtering" | ||||||
|  |             echo "    3) Extended: Base + social media filtering" | ||||||
|  |             echo "    4) Family: Base + gambling and adult content filtering" | ||||||
|  |             echo "    5) All: Family + social media filtering" | ||||||
|  |             while [[ "$valid_input" == "0" ]]; do | ||||||
|  |                 read -p "Selection [0-5]: " resolver_subselection | ||||||
|  |                 if [[ "$resolver_subselection" == [012345]* ]]; then | ||||||
|  |                     valid_input="1" | ||||||
|  |                 else | ||||||
|  |                     echo "That is not a valid selection." | ||||||
|  |                 fi | ||||||
|  |             done | ||||||
|  |             valid_input="0" | ||||||
|  |             case "$resolver_subselection" in | ||||||
|  |                 0) | ||||||
|  |                     resolver_ipv4_address="194.242.2.2" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::2" | ||||||
|  |                     resolver_hostname="dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |                 1) | ||||||
|  |                     resolver_ipv4_address="194.242.2.3" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::3" | ||||||
|  |                     resolver_hostname="adblock.dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |                 2) | ||||||
|  |                     resolver_ipv4_address="194.242.2.4" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::4" | ||||||
|  |                     resolver_hostname="base.dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |                 3) | ||||||
|  |                     resolver_ipv4_address="194.242.2.5" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::5" | ||||||
|  |                     resolver_hostname="extended.dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |                 4) | ||||||
|  |                     resolver_ipv4_address="194.242.2.6" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::6" | ||||||
|  |                     resolver_hostname="family.dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |                 5) | ||||||
|  |                     resolver_ipv4_address="194.242.2.9" | ||||||
|  |                     resolver_ipv6_address="2a07:e340::9" | ||||||
|  |                     resolver_hostname="all.dns.mullvad.net" | ||||||
|  |                     ;; | ||||||
|  |             esac | ||||||
|  |             resolver_https_address="https://$resolver_hostname/dns-query" | ||||||
|  |             ;; | ||||||
|  |         3) | ||||||
|  |             resolver_has_second_ip="y" | ||||||
|  |             resolver_supports_ipv6="y" | ||||||
|  |             echo "Setting resolver Cloudflare. (glory to the cloud)" | ||||||
|  |             echo "What content would you like to filter:" | ||||||
|  |             echo "    0) No filtering" | ||||||
|  |             echo "    1) Security: Malware filtering" | ||||||
|  |             echo "    2) Family: Security + adult content filtering" | ||||||
|  |             while [[ "$valid_input" == "0" ]]; do | ||||||
|  |                 read -p "Selection [0-2]: " resolver_subselection | ||||||
|  |                 if [[ "$resolver_subselection" == [012]* ]]; then | ||||||
|  |                     valid_input="1" | ||||||
|  |                 else | ||||||
|  |                     echo "That is not a valid selection." | ||||||
|  |                 fi | ||||||
|  |             done | ||||||
|  |             valid_input="0" | ||||||
|  |             case "$resolver_subselection" in | ||||||
|  |                 0) | ||||||
|  |                     resolver_ipv4_address="1.1.1.1" | ||||||
|  |                     resolver_ipv4_address_2="1.0.0.1" | ||||||
|  |                     resolver_ipv6_address="2606:4700:4700::1111" | ||||||
|  |                     resolver_ipv6_address_2="2606:4700:4700::1001" | ||||||
|  |                     resolver_hostname="cloudflare-dns.com" | ||||||
|  |                     ;; | ||||||
|  |                 1) | ||||||
|  |                     resolver_ipv4_address="1.1.1.2" | ||||||
|  |                     resolver_ipv4_address_2="1.0.0.2" | ||||||
|  |                     resolver_ipv6_address="2606:4700:4700::1112" | ||||||
|  |                     resolver_ipv6_address_2="2606:4700:4700::1002" | ||||||
|  |                     resolver_hostname="security.cloudflare-dns.com" | ||||||
|  |                     ;; | ||||||
|  |                 2) | ||||||
|  |                     resolver_ipv4_address="1.1.1.3" | ||||||
|  |                     resolver_ipv4_address_2="1.0.0.3" | ||||||
|  |                     resolver_ipv6_address="2606:4700:4700::1113" | ||||||
|  |                     resolver_ipv6_address_2="2606:4700:4700::1003" | ||||||
|  |                     resolver_hostname="family.cloudflare-dns.com" | ||||||
|  |                     ;; | ||||||
|  |             esac | ||||||
|  |             resolver_https_address="https://$resolver_hostname/dns-query" | ||||||
|  |             ;; | ||||||
|  |         4) | ||||||
|  |             resolver_has_second_ip="y" | ||||||
|  |             resolver_supports_ipv6="y" | ||||||
|  |             echo "Setting resolver DNSForge." | ||||||
|  |             echo "What content would you like to filter:" | ||||||
|  |             echo "    0) Standard: Ad, tracker, and malware filtering" | ||||||
|  |             echo "    1) Clean: Standard + adult content filtering" | ||||||
|  |             echo "    2) Hard: Clean + stricter ad, tracker, and malware filtering" | ||||||
|  |             while [[ "$valid_input" == "0" ]]; do | ||||||
|  |                 read -p "Selection [0-2]: " resolver_subselection | ||||||
|  |                 if [[ "$resolver_subselection" == [012]* ]]; then | ||||||
|  |                     valid_input="1" | ||||||
|  |                 else | ||||||
|  |                     echo "That is not a valid selection." | ||||||
|  |                 fi | ||||||
|  |             done | ||||||
|  |             valid_input="0" | ||||||
|  |             case "$resolver_subselection" in | ||||||
|  |                 0) | ||||||
|  |                     resolver_ipv4_address="176.9.93.198" | ||||||
|  |                     resolver_ipv4_address_2="176.9.1.117" | ||||||
|  |                     resolver_ipv6_address="2a01:4f8:151:34aa::198" | ||||||
|  |                     resolver_ipv6_address_2="2a01:4f8:141:316d::117" | ||||||
|  |                     resolver_hostname="dnsforge.de" | ||||||
|  |                     ;; | ||||||
|  |                 1) | ||||||
|  |                     resolver_ipv4_address="49.12.223.2" | ||||||
|  |                     resolver_ipv4_address_2="49.12.43.208" | ||||||
|  |                     resolver_ipv6_address="2a01:4f8:c17:4fbc::2" | ||||||
|  |                     resolver_ipv6_address_2="2a01:4f8:c012:ed89::208" | ||||||
|  |                     resolver_hostname="clean.dnsforge.de" | ||||||
|  |                     ;; | ||||||
|  |                 2) | ||||||
|  |                     resolver_ipv4_address="49.12.222.213" | ||||||
|  |                     resolver_ipv4_address_2="88.198.122.154" | ||||||
|  |                     resolver_ipv6_address="2a01:4f8:c17:2c61::213" | ||||||
|  |                     resolver_ipv6_address_2="2a01:4f8:c013:5ec0::154" | ||||||
|  |                     resolver_hostname="hard.dnsforge.de" | ||||||
|  |                     ;; | ||||||
|  |             esac | ||||||
|  |             resolver_https_address="https://$resolver_hostname/dns-query" | ||||||
|  |             ;; | ||||||
|  |         5) | ||||||
|  |             echo "Setting custom resolver." | ||||||
|  |             echo "NOTE: If the resolver does not support DoT/DoQ or DNSSEC, this process will not work." | ||||||
|  |             echo "" | ||||||
|  |             echo "Please provide the technical information." | ||||||
|  |             read -p "Please enter the resolver's IP address (e.g. '1.1.1.2'): " resolver_ipv4_address | ||||||
|  |             read -p "Does the resolver provide two distinct IP addresses (e.g. '1.1.1.2' and '1.0.0.2')? [Y/n] " resolver_has_second_ip | ||||||
|  |             resolver_has_second_ip=${resolver_has_second_ip:-y} | ||||||
|  |             if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||||
|  |                 read -p "Please enter the resolver's second IP address: " resolver_ipv4_address_2 | ||||||
|  |             fi | ||||||
|  |             read -p "Does the resolver support IPv6 (e.g. '2606:4700:4700::1112')? [Y/n] " resolver_supports_ipv6 | ||||||
|  |             resolver_supports_ipv6=${resolver_supports_ipv6:-y} | ||||||
|  |             if [[ "$resolver_supports_ipv6" == [Yy]* ]]; then | ||||||
|  |                 read -p "Please enter the resolver's IPv6 address: " resolver_ipv6_address | ||||||
|  |                 if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||||
|  |                     read -p "Please enter the resolver's second IPv6 address: " resolver_ipv6_address_2 | ||||||
|  |                 fi | ||||||
|  |             fi | ||||||
|  |             read -p "Please enter the second resolver's hostname (e.g. 'security.cloudflare-dns.com'): " resolver_hostname | ||||||
|  |             ;; | ||||||
|  |     esac | ||||||
|  |  | ||||||
|  |     read -p "Would you like the resolver to be set in the default browser (hardened-chromium) via management policy? [y/N] " set_browser_policy | ||||||
|  |     if [[ "$set_browser_policy" == [Yy]* && "$resolver_selection" == 5 ]]; then | ||||||
|  |         read -p "Please enter the second resolver's HTTPS address (e.g. 'https://security.cloudflare-dns.com/dns-query'): " resolver_https_address | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     resolved_conf_dns_string="DNS=" | ||||||
|  |     resolved_conf_dns_string+=" $resolver_ipv4_address" | ||||||
|  |     resolved_conf_dns_string+="#$resolver_hostname" | ||||||
|  |     if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||||
|  |         resolved_conf_dns_string+=" $resolver_ipv4_address_2" | ||||||
|  |         resolved_conf_dns_string+="#$resolver_hostname" | ||||||
|  |     fi | ||||||
|  |     if [[ "$resolver_supports_ipv6" == [Yy]* ]]; then | ||||||
|  |         resolved_conf_dns_string+=" $resolver_ipv6_address" | ||||||
|  |         resolved_conf_dns_string+="#$resolver_hostname" | ||||||
|  |         if [[ "$resolver_has_second_ip" == [Yy]* ]]; then | ||||||
|  |             resolved_conf_dns_string+=" $resolver_ipv6_address_2" | ||||||
|  |             resolved_conf_dns_string+="#$resolver_hostname" | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     cat << EOF > "$resolved_conf" | ||||||
|  |     [Resolve] | ||||||
|  |     DNSSEC=true | ||||||
|  |     DNSOverTLS=true | ||||||
|  |     $resolved_conf_dns_string | ||||||
|  |     EOF | ||||||
|  |  | ||||||
|  |     systemctl restart systemd-resolved | ||||||
|  |  | ||||||
|  |     echo "Config file for resolved configured with selected resolver and service restarted." | ||||||
|  |  | ||||||
|  |     if [[ "$set_browser_policy" != [Yy]* ]]; then | ||||||
|  |         exit 0 | ||||||
|  |     fi | ||||||
|  |     cat << EOF > "$policy_file" | ||||||
|  |     { | ||||||
|  |         "DnsOverHttpsMode": "secure", | ||||||
|  |         "DnsOverHttpsTemplates": "$resolver_https_address" | ||||||
|  |     } | ||||||
|  |     EOF | ||||||
|  |  | ||||||
|  |     echo "Browser policy set with selected resolver." | ||||||
							
								
								
									
										30
									
								
								files/justfiles/hardening.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								files/justfiles/hardening.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | # Harden flatpaks by preloading hardened_malloc (highest supported hwcap). When called with a flatpak application ID as an argument, applies the overrides to that application instead of globally. | ||||||
|  | harden-flatpak FLATPAK="": | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     var1={{ FLATPAK }} | ||||||
|  |     flatpak_id="${var1:-}" | ||||||
|  |     flatpak override --user --filesystem=host-os:ro $flatpak_id | ||||||
|  |     uarches="$(/usr/lib64/ld-linux-x86-64.so.2 --help | grep '(supported, searched)' | cut -d'v' -f2)" | ||||||
|  |     bestuarch="${uarches:0:1}" | ||||||
|  |     if [ -z "$bestuarch" ] ; then | ||||||
|  |         echo "No microarchitecture support detected. Using default x86-64-v1 architecture${flatpak_id:+" for $flatpak_id's malloc"}." | ||||||
|  |         flatpak override --user --env=LD_PRELOAD=/var/run/host/usr/lib64/libhardened_malloc.so $flatpak_id | ||||||
|  |     else | ||||||
|  |         echo "x86-64-v$bestuarch support detected. Using x86-64-v$bestuarch microarchitecture${flatpak_id:+" for $flatpak_id's malloc"}." | ||||||
|  |         flatpak override --user --env=LD_PRELOAD=/var/run/host/usr/lib64/glibc-hwcaps/x86-64-v"$bestuarch"/libhardened_malloc.so $flatpak_id | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Setup USBGuard | ||||||
|  | setup-usbguard: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     echo "Notice: This will generate a policy based on your existing connected USB devices." | ||||||
|  |     ACTIVE_USERNAME=$(whoami) | ||||||
|  |     pkexec sh -c ' | ||||||
|  |         mkdir -p /var/log/usbguard | ||||||
|  |         mkdir -p /etc/usbguard | ||||||
|  |         chmod 755 /etc/usbguard | ||||||
|  |         usbguard generate-policy > /etc/usbguard/rules.conf | ||||||
|  |         systemctl enable --now usbguard.service | ||||||
|  |         usbguard add-user $1 | ||||||
|  |     ' -- $ACTIVE_USERNAME | ||||||
|  |     systemctl enable --user --now usbguard-notifier.service | ||||||
							
								
								
									
										89
									
								
								files/justfiles/kargs.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								files/justfiles/kargs.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | # Add additional boot parameters for hardening (requires reboot) | ||||||
|  | set-kargs-hardening: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     read -p "Do you need support for 32-bit processes/syscalls? (This is mostly used by legacy software, with some exceptions, such as Steam) [y/N]: " YES | ||||||
|  |     if [[ "$YES" == [Yy]* ]]; then | ||||||
|  |         echo "Keeping 32-bit support." | ||||||
|  |     else | ||||||
|  |         IAEMU_NO="--append-if-missing=ia32_emulation=0" | ||||||
|  |         echo "Disabling 32-bit support, for the next boot." | ||||||
|  |     fi | ||||||
|  |     read -p "Do you want to force disable Simultaneous Multithreading (SMT) / Hyperthreading? (This can cause a reduction in the performance of certain tasks in favor of security) (Note that in most hardware SMT will be disabled anyways to mitigate a known vulnerability, this turns it off on all hardware regardless) [y/N]: " YES | ||||||
|  |     if [[ "$YES" == [Yy]* ]]; then | ||||||
|  |         NOSMT_YES="--append-if-missing=nosmt=force" | ||||||
|  |         echo "Force disabling SMT/Hyperthreading." | ||||||
|  |     else | ||||||
|  |         echo "Not force disabling SMT/Hyperthreading." | ||||||
|  |     fi | ||||||
|  |     read -p "Would you like to set additional (unstable) hardening kargs? (Warning: Setting these kargs may lead to boot issues on some hardware.) [y/N]: " YES | ||||||
|  |     if [[ "$YES" == [Yy]* ]]; then | ||||||
|  |     UNSTABLE_YES="--append-if-missing=efi=disable_early_pci_dma \ | ||||||
|  |         --append-if-missing=debugfs=off" | ||||||
|  |         echo "Setting unstable hardening kargs." | ||||||
|  |     else | ||||||
|  |         echo "Not setting unstable hardening kargs." | ||||||
|  |     fi | ||||||
|  |     echo "Applying boot parameters..." | ||||||
|  |     rpm-ostree kargs \ | ||||||
|  |       ${UNSTABLE_YES:+$UNSTABLE_YES} ${IAEMU_NO:+$IAEMU_NO} ${NOSMT_YES:+$NOSMT_YES} \ | ||||||
|  |       --append-if-missing=init_on_alloc=1 \ | ||||||
|  |       --append-if-missing=init_on_free=1 \ | ||||||
|  |       --append-if-missing=slab_nomerge \ | ||||||
|  |       --append-if-missing=page_alloc.shuffle=1 \ | ||||||
|  |       --append-if-missing=randomize_kstack_offset=on \ | ||||||
|  |       --append-if-missing=vsyscall=none \ | ||||||
|  |       --append-if-missing=lockdown=confidentiality \ | ||||||
|  |       --append-if-missing=random.trust_cpu=off \ | ||||||
|  |       --append-if-missing=random.trust_bootloader=off \ | ||||||
|  |       --append-if-missing=iommu=force \ | ||||||
|  |       --append-if-missing=intel_iommu=on \ | ||||||
|  |       --append-if-missing=amd_iommu=force_isolation \ | ||||||
|  |       --append-if-missing=iommu.passthrough=0 \ | ||||||
|  |       --append-if-missing=iommu.strict=1 \ | ||||||
|  |       --append-if-missing=pti=on \ | ||||||
|  |       --append-if-missing=module.sig_enforce=1 \ | ||||||
|  |       --append-if-missing=mitigations=auto,nosmt \ | ||||||
|  |       --append-if-missing=spectre_v2=on \ | ||||||
|  |       --append-if-missing=spec_store_bypass_disable=on \ | ||||||
|  |       --append-if-missing=l1d_flush=on \ | ||||||
|  |       --append-if-missing=gather_data_sampling=force  | ||||||
|  |     echo "Hardening kargs applied." | ||||||
|  |  | ||||||
|  | # Remove all hardening boot parameters (requires reboot) | ||||||
|  | remove-kargs-hardening: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     rpm-ostree kargs \ | ||||||
|  |       --delete-if-present="init_on_alloc=1" \ | ||||||
|  |       --delete-if-present="init_on_free=1" \ | ||||||
|  |       --delete-if-present="slab_nomerge" \ | ||||||
|  |       --delete-if-present="page_alloc.shuffle=1" \ | ||||||
|  |       --delete-if-present="randomize_kstack_offset=on" \ | ||||||
|  |       --delete-if-present="vsyscall=none" \ | ||||||
|  |       --delete-if-present="lockdown=confidentiality" \ | ||||||
|  |       --delete-if-present="random.trust_cpu=off" \ | ||||||
|  |       --delete-if-present="random.trust_bootloader=off" \ | ||||||
|  |       --delete-if-present="iommu=force" \ | ||||||
|  |       --delete-if-present="intel_iommu=on" \ | ||||||
|  |       --delete-if-present="amd_iommu=force_isolation" \ | ||||||
|  |       --delete-if-present="iommu.passthrough=0" \ | ||||||
|  |       --delete-if-present="iommu.strict=1" \ | ||||||
|  |       --delete-if-present="pti=on" \ | ||||||
|  |       --delete-if-present="module.sig_enforce=1" \ | ||||||
|  |       --delete-if-present="mitigations=auto,nosmt" \ | ||||||
|  |       --delete-if-present="efi=disable_early_pci_dma" \ | ||||||
|  |       --delete-if-present="debugfs=off" \ | ||||||
|  |       --delete-if-present="spectre_v2=on" \ | ||||||
|  |       --delete-if-present="spec_store_bypass_disable=on" \ | ||||||
|  |       --delete-if-present="l1d_flush=on" \ | ||||||
|  |       --delete-if-present="gather_data_sampling=force" \ | ||||||
|  |       --delete-if-present="ia32_emulation=0" | ||||||
|  |     echo "Hardening kargs removed." | ||||||
|  |  | ||||||
|  | # Set nvidia kargs | ||||||
|  | set-kargs-nvidia: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     rpm-ostree kargs \ | ||||||
|  |       --append-if-missing=rd.driver.blacklist=nouveau \ | ||||||
|  |       --append-if-missing=modprobe.blacklist=nouveau \ | ||||||
|  |       --append-if-missing=nvidia-drm.modeset=1 \ | ||||||
|  |       --append-if-missing=nvidia-drm.fbdev=1 | ||||||
							
								
								
									
										22
									
								
								files/justfiles/luks.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								files/justfiles/luks.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | # vim: set ft=make : | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  | # Enable automatic LUKS unlock via TPM | ||||||
|  | setup-luks-tpm-unlock: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     run0 /usr/libexec/luks-enable-tpm2-autounlock | ||||||
|  |  | ||||||
|  | # Disable automatic LUKS unlock via TPM | ||||||
|  | remove-luks-tpm-unlock: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     run0 /usr/libexec/luks-disable-tpm2-autounlock | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										223
									
								
								files/justfiles/toggles.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								files/justfiles/toggles.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | |||||||
|  | # Toggle the cups service on/off | ||||||
|  | toggle-cups: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     if systemctl is-enabled --quiet cups; then | ||||||
|  |       firewall-cmd --permanent --remove-port=631/tcp | ||||||
|  |       firewall-cmd --permanent --remove-port=631/udp  | ||||||
|  |       firewall-cmd --reload  | ||||||
|  |       systemctl mask cups | ||||||
|  |       systemctl disable cups | ||||||
|  |       systemctl stop cups | ||||||
|  |       systemctl daemon-reload | ||||||
|  |       echo "Cups disabled." | ||||||
|  |     else | ||||||
|  |       firewall-cmd --permanent --add-port=631/tcp | ||||||
|  |       firewall-cmd --permanent --add-port=631/udp  | ||||||
|  |       firewall-cmd --reload  | ||||||
|  |       systemctl unmask cups | ||||||
|  |       systemctl enable cups | ||||||
|  |       systemctl start cups | ||||||
|  |       systemctl daemon-reload | ||||||
|  |       echo "Cups enabled." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle bluetooth kernel modules on/off (requires reboot) | ||||||
|  | toggle-bluetooth-modules: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     BLUE_MOD_FILE="/etc/modprobe.d/99-bluetooth.conf" | ||||||
|  |     if test -e $BLUE_MOD_FILE; then | ||||||
|  |       sudo rm -f $BLUE_MOD_FILE | ||||||
|  |       echo "Bluetooth kernel modules disabled. Reboot to take effect." | ||||||
|  |     else | ||||||
|  |       sudo sh -c 'echo "install bluetooth /sbin/modprobe --ignore-install bluetooth" >> "$1"' _ "$BLUE_MOD_FILE" | ||||||
|  |       sudo sh -c 'echo "install btusb /sbin/modprobe --ignore-install btusb" >> "$1"' _ "$BLUE_MOD_FILE" | ||||||
|  |       sudo chmod 644 $BLUE_MOD_FILE | ||||||
|  |       echo "Bluetooth kernel modules enabled. Reboot to take effect." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle GHNS (KDE Get New Stuff) | ||||||
|  | toggle-ghns: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     KDE_GLOBALS_FILE="/etc/xdg/kdeglobals" | ||||||
|  |     if test -e $KDE_GLOBALS_FILE; then | ||||||
|  |       if grep -q "ghns=false" "$KDE_GLOBALS_FILE"; then | ||||||
|  |         sed -i "s/ghns=false/ghns=true/" "$KDE_GLOBALS_FILE" | ||||||
|  |         echo "GHNS enabled." | ||||||
|  |       elif grep -q "ghns=true" "$KDE_GLOBALS_FILE"; then | ||||||
|  |         sed -i "s/ghns=true/ghns=false/" "$KDE_GLOBALS_FILE" | ||||||
|  |         echo "GHNS disabled." | ||||||
|  |       else  | ||||||
|  |         echo "The kdeglobals file is missing the ghns toggle." | ||||||
|  |       fi | ||||||
|  |     else | ||||||
|  |       echo "No kdeglobals file found. Are you on kinoite?" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # enable a kernel module that is disabled by modprobe.d (requires restart) | ||||||
|  | override-enable-module mod_name: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     MOD_NAME="{{ mod_name }}" | ||||||
|  |     MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" | ||||||
|  |     if test -e $MOD_FILE; then | ||||||
|  |       echo "$MOD_NAME module is already enabled." | ||||||
|  |     else | ||||||
|  |       sudo sh -c 'echo "install $1 /sbin/modprobe --ignore-install $1" >> "$2"' _ "$MOD_NAME" "$MOD_FILE"  | ||||||
|  |       sudo chmod 644 $MOD_FILE | ||||||
|  |       echo "Override created to enable $MOD_NAME module. Reboot to take effect." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # reset the override by `just override-enable-module`, i.e. disable the module again (requires restart) | ||||||
|  | override-reset-module mod_name: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     MOD_NAME="{{ mod_name }}" | ||||||
|  |     MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" | ||||||
|  |     if test -e $MOD_FILE; then | ||||||
|  |       sudo rm -f $MOD_FILE | ||||||
|  |       echo "The override for $MOD_NAME module has been reset. Reboot to take effect." | ||||||
|  |     else | ||||||
|  |       echo "No override found for $MOD_NAME module." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle anticheat support by changing ptrace scope (requires restart) | ||||||
|  | toggle-anticheat-support: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     SYSCTL_HARDENING_FILE="/etc/sysctl.d/hardening.conf" | ||||||
|  |     if grep -q "kernel.yama.ptrace_scope = 3" "$SYSCTL_HARDENING_FILE"; then | ||||||
|  |         sed -i "s/kernel.yama.ptrace_scope = 3/kernel.yama.ptrace_scope = 1/" "$SYSCTL_HARDENING_FILE" | ||||||
|  |         echo "Anticheat support enabled. ptrace_scope set to 1." | ||||||
|  |     elif grep -q "kernel.yama.ptrace_scope = 1" "$SYSCTL_HARDENING_FILE"; then | ||||||
|  |         sed -i "s/kernel.yama.ptrace_scope = 1/kernel.yama.ptrace_scope = 3/" "$SYSCTL_HARDENING_FILE" | ||||||
|  |         echo "Anticheat support disabled. ptrace_scope set back to 3." | ||||||
|  |     else  | ||||||
|  |         echo "The sysctl hardening file is missing the ptrace_scope setting." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle Gnome JIT JavaScript for GJS and WebkitGTK (requires session restart) | ||||||
|  | toggle-gnome-jit-js: | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     ENV_FILE="/etc/profile.d/gnome-disable-jit.sh" | ||||||
|  |     if test -e $ENV_FILE; then | ||||||
|  |         sudo rm -f $ENV_FILE | ||||||
|  |         echo "JIT JavaScript for Gnome and WebkitGTK has been enabled." | ||||||
|  |     else | ||||||
|  |         sudo cp /usr$ENV_FILE $ENV_FILE | ||||||
|  |         sudo chmod 644 $ENV_FILE | ||||||
|  |         echo "JIT JavaScript for Gnome and WebkitGTK has been disabled." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle support for using GNOME user extensions | ||||||
|  | toggle-gnome-extensions: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     GSETTING="$(gsettings get org.gnome.shell allow-extension-installation)" | ||||||
|  |     if [[ "${GSETTING}" == "false" ]]; then | ||||||
|  |       gsettings set org.gnome.shell allow-extension-installation true | ||||||
|  |       echo "Support for GNOME user extensions have been enabled" | ||||||
|  |     else | ||||||
|  |       gsettings reset org.gnome.shell allow-extension-installation | ||||||
|  |       echo "Support for GNOME user extensions have been disabled" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle Xwayland support | ||||||
|  | toggle-xwayland ACTION="prompt": | ||||||
|  |     #!/usr/bin/pkexec /usr/bin/bash | ||||||
|  |     source /usr/lib/ujust/ujust.sh | ||||||
|  |     OPTION={{ ACTION }} | ||||||
|  |     if [ "$OPTION" == "prompt" ]; then | ||||||
|  |       echo "${bold}Toggling Xwayland (requires logout)${normal}" | ||||||
|  |       echo 'For which DE/WM do you want to toggle Xwayland?' | ||||||
|  |       OPTION=$(ugum choose "GNOME" "KDE Plasma" "Sway") | ||||||
|  |     elif [ "$OPTION" == "help" ]; then | ||||||
|  |       echo "Usage: ujust toggle-xwayland <option>" | ||||||
|  |       echo "  <option>: Specify the quick option - 'gnome', 'plasma', or 'sway'" | ||||||
|  |       echo "  Use 'gnome' to Toggle Xwayland for GNOME." | ||||||
|  |       echo "  Use 'plasma' to Toggle Xwayland for KDE Plasma." | ||||||
|  |       echo "  Use 'sway' to Toggle Xwayland for Sway." | ||||||
|  |       exit 0 | ||||||
|  |     fi | ||||||
|  |     if [ "$OPTION" == "GNOME" ] || [ "${OPTION,,}" == "gnome" ]; then | ||||||
|  |       GNOME_XWAYLAND_FILE="/etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf" | ||||||
|  |       if test -e $GNOME_XWAYLAND_FILE; then | ||||||
|  |         sudo rm -f $GNOME_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for GNOME has been enabled." | ||||||
|  |       else | ||||||
|  |         sudo cp /usr$GNOME_XWAYLAND_FILE $GNOME_XWAYLAND_FILE | ||||||
|  |         sudo chmod 644 $GNOME_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for GNOME has been disabled." | ||||||
|  |       fi | ||||||
|  |     elif [ "$OPTION" == "KDE Plasma" ] || [ "${OPTION,,}" == "plasma" ]; then | ||||||
|  |       PLASMA_XWAYLAND_FILE="/etc/systemd/user/plasma-kwin_wayland.service.d/override.conf" | ||||||
|  |       if test -e $PLASMA_XWAYLAND_FILE; then | ||||||
|  |         sudo rm -f $PLASMA_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for KDE Plasma has been enabled." | ||||||
|  |       else | ||||||
|  |         sudo cp /usr$PLASMA_XWAYLAND_FILE $PLASMA_XWAYLAND_FILE | ||||||
|  |         sudo chmod 644 $PLASMA_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for KDE Plasma has been disabled." | ||||||
|  |       fi | ||||||
|  |     elif [ "$OPTION" == "Sway" ] || [ "${OPTION,,}" == "sway" ]; then | ||||||
|  |       SWAY_XWAYLAND_FILE="/etc/sway/config.d/99-noxwayland.conf" | ||||||
|  |       if test -e $SWAY_XWAYLAND_FILE; then | ||||||
|  |         sudo rm -f $SWAY_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for Sway has been enabled." | ||||||
|  |       else | ||||||
|  |         sudo cp /usr$SWAY_XWAYLAND_FILE $SWAY_XWAYLAND_FILE | ||||||
|  |         sudo chmod 644 $SWAY_XWAYLAND_FILE | ||||||
|  |         echo "Xwayland for Sway has been disabled." | ||||||
|  |       fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Toggle bash environment lockdown (mitigates LD_PRELOAD attacks) | ||||||
|  | toggle-bash-environment-lockdown: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     BASH_ENV_FILES=("$HOME/.bashrc" "$HOME/.bash_profile") | ||||||
|  |     echo "${b}WARNING${n} This will overwrite your .bashrc and .bash_profile." | ||||||
|  |     echo "This is needed to ensure the mitigation is effective." | ||||||
|  |     echo "Do you understand?" | ||||||
|  |     echo "Please type in \"YES I UNDERSTAND\" and press enter" | ||||||
|  |     read ACCEPT | ||||||
|  |     if [ "$ACCEPT" == "YES I UNDERSTAND" ]; then | ||||||
|  |       if lsattr "${BASH_ENV_FILES[0]}" 2>/dev/null | awk '{print $1}' | grep -q 'i'; then | ||||||
|  |         echo "Bash environment '(${BASH_ENV_FILES[@]})' is locked down. Unlocking it." | ||||||
|  |         for file in "${BASH_ENV_FILES[@]}"; do | ||||||
|  |             pkexec chattr -i "$file" | ||||||
|  |         done | ||||||
|  |       else | ||||||
|  |         echo "Bash environment '(${BASH_ENV_FILES[@]})' is unlocked. Locking it." | ||||||
|  |         echo " | ||||||
|  |     # .bashrc | ||||||
|  |  | ||||||
|  |     # Source global definitions | ||||||
|  |     if [ -f /etc/bashrc ]; then | ||||||
|  |         . /etc/bashrc | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # User specific environment | ||||||
|  |     if ! [[ "\$PATH" =~ "\$HOME/.local/bin:\$HOME/bin:" ]]; then | ||||||
|  |         PATH="\$HOME/.local/bin:\$HOME/bin:\$PATH" | ||||||
|  |     fi | ||||||
|  |     export PATH | ||||||
|  |  | ||||||
|  |     # Uncomment the following line if you don't like systemctl's auto-paging feature: | ||||||
|  |     # export SYSTEMD_PAGER= | ||||||
|  |  | ||||||
|  |     unset rc | ||||||
|  |           " > ~/.bashrc | ||||||
|  |  | ||||||
|  |         echo " | ||||||
|  |     # .bash_profile | ||||||
|  |  | ||||||
|  |     # Get the aliases and functions | ||||||
|  |     if [ -f ~/.bashrc ]; then | ||||||
|  |         . ~/.bashrc | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # User specific environment and startup programs | ||||||
|  |         " > ~/.bash_profile | ||||||
|  |  | ||||||
|  |         for file in "${BASH_ENV_FILES[@]}"; do | ||||||
|  |             pkexec chattr +i "$file" | ||||||
|  |         done | ||||||
|  |       fi | ||||||
|  |     else | ||||||
|  |       echo "Capitalization matters when you type \"YES I UNDERSTAND\"" | ||||||
|  |     fi | ||||||
							
								
								
									
										178
									
								
								files/justfiles/utilities.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								files/justfiles/utilities.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | |||||||
|  | # vim: set ft=make : | ||||||
|  | # Copyright 2024 secureblue | ||||||
|  | # | ||||||
|  | # This file includes code from Universal Blue which is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" | ||||||
|  | # BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language | ||||||
|  | # governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  | uid := `id -u` | ||||||
|  | shell := `grep :$(id -u): /etc/passwd | cut -d: -f7` | ||||||
|  |  | ||||||
|  | # Boot into this device's BIOS/UEFI screen | ||||||
|  | bios: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     if [ -d /sys/firmware/efi ]; then | ||||||
|  |       systemctl reboot --firmware-setup | ||||||
|  |     else | ||||||
|  |       echo "Rebooting to legacy BIOS from OS is not supported." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Show all messages from this boot | ||||||
|  | logs-this-boot: | ||||||
|  |     sudo journalctl -b 0 | ||||||
|  |  | ||||||
|  | # Show all messages from last boot | ||||||
|  | logs-last-boot: | ||||||
|  |     sudo journalctl -b -1 | ||||||
|  |  | ||||||
|  | # Regenerate GRUB config, useful in dual-boot scenarios where a second operating system isn't listed | ||||||
|  | regenerate-grub: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     if [ -d /sys/firmware/efi ]; then | ||||||
|  |       sudo grub2-mkconfig -o /etc/grub2-efi.cfg | ||||||
|  |     else | ||||||
|  |       sudo grub2-mkconfig -o /etc/grub2.cfg | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Enroll Nvidia driver & KMOD signing key for secure boot - Enter password "universalblue" if prompted | ||||||
|  | enroll-secure-boot-key: | ||||||
|  |     sudo mokutil --timeout -1 | ||||||
|  |     echo 'The next line will prompt for a MOK password. Then, input "universalblue"' | ||||||
|  |     sudo mokutil --import /etc/pki/akmods/certs/akmods-ublue.der | ||||||
|  |     echo 'At next reboot, the mokutil UEFI menu UI will be displayed (*QWERTY* keyboard input and navigation).\nThen, select "Enroll MOK", and input "universalblue" as the password' | ||||||
|  |  | ||||||
|  | # Toggle display of the user-motd in terminal | ||||||
|  | toggle-user-motd: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     if test -e "${HOME}/.config/no-show-user-motd"; then | ||||||
|  |       rm -f "${HOME}/.config/no-show-user-motd" | ||||||
|  |     else | ||||||
|  |       if test ! -d "${HOME}/.config"; then | ||||||
|  |         mkdir "${HOME}/.config" | ||||||
|  |       fi | ||||||
|  |       touch "${HOME}/.config/no-show-user-motd" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  | # Update device firmware | ||||||
|  | [no-exit-message] | ||||||
|  | update-firmware: | ||||||
|  |     fwupdmgr refresh --force | ||||||
|  |     fwupdmgr get-updates | ||||||
|  |     fwupdmgr update | ||||||
|  |  | ||||||
|  | # Clean up old up unused podman images, volumes, flatpak packages and rpm-ostree content | ||||||
|  | clean-system: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     podman image prune -af | ||||||
|  |     podman volume prune -f | ||||||
|  |     flatpak uninstall --unused | ||||||
|  |     rpm-ostree cleanup -bm | ||||||
|  |  | ||||||
|  | # Check for local overrides | ||||||
|  | check-local-overrides: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     diff -r \ | ||||||
|  |       --suppress-common-lines \ | ||||||
|  |       --color="always" \ | ||||||
|  |       --exclude "passwd*" \ | ||||||
|  |       --exclude "group*" \ | ||||||
|  |       --exclude="subgid*" \ | ||||||
|  |       --exclude="subuid*" \ | ||||||
|  |       --exclude="machine-id" \ | ||||||
|  |       --exclude="adjtime" \ | ||||||
|  |       --exclude="fstab" \ | ||||||
|  |       --exclude="system-connections" \ | ||||||
|  |       --exclude="shadow*" \ | ||||||
|  |       --exclude="gshadow*" \ | ||||||
|  |       --exclude="ssh_host*" \ | ||||||
|  |       --exclude="cmdline" \ | ||||||
|  |       --exclude="crypttab" \ | ||||||
|  |       --exclude="hostname" \ | ||||||
|  |       --exclude="localtime" \ | ||||||
|  |       --exclude="locale*" \ | ||||||
|  |       --exclude="*lock" \ | ||||||
|  |       --exclude=".updated" \ | ||||||
|  |       --exclude="*LOCK" \ | ||||||
|  |       --exclude="vconsole*" \ | ||||||
|  |       --exclude="00-keyboard.conf" \ | ||||||
|  |       --exclude="grub" \ | ||||||
|  |       --exclude="system.control*" \ | ||||||
|  |       --exclude="cdi" \ | ||||||
|  |       --exclude="default.target" \ | ||||||
|  |       /usr/etc /etc 2>/dev/null | sed '/Binary\ files\ /d' | ||||||
|  |  | ||||||
|  | # Debug dump pastebin for issue reporting | ||||||
|  | debug-info: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     rpm_ostree_status=$(echo -e "=== Rpm-Ostree Status ===\n"; rpm-ostree status --verbose) | ||||||
|  |     sysinfo=$(echo -e "\n"; fpaste --sysinfo --printonly) | ||||||
|  |     flatpaks=$(echo "=== Flatpaks Installed ==="; flatpak list --columns=application,version,options) | ||||||
|  |     audit_results=$(echo -e "\n=== Audit Results ===\n"; ujust audit-secureblue) | ||||||
|  |     local_overrides=$(echo -e "\n=== Listing Local Overrides ===\n"; ujust check-local-overrides) | ||||||
|  |     recent_events=$(echo -e "\n=== Recent System Events ===\n"; journalctl -b -p err..alert --since "1 hour ago") | ||||||
|  |     failed_services=$(echo -e "\n=== Failed Services ===\n"; systemctl list-units --state=failed) | ||||||
|  |     content="$rpm_ostree_status$sysinfo$flatpaks$audit_results$local_overrides$recent_events$failed_services" | ||||||
|  |     echo "$content" | fpaste --confirm --private=1 | ||||||
|  |  | ||||||
|  | # Rerun Yafti | ||||||
|  | rerun-yafti: | ||||||
|  |     yafti -f /usr/share/ublue-os/firstboot/yafti.yml | ||||||
|  |  | ||||||
|  | alias assemble := distrobox-assemble | ||||||
|  |  | ||||||
|  | # Create distroboxes from a defined manifest | ||||||
|  | distrobox-assemble CONTAINER="prompt" ACTION="create" FILE="/etc/distrobox/distrobox.ini": | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     # Distroboxes are gathered from distrobox.ini, please add them there | ||||||
|  |     source /usr/lib/ujust/ujust.sh | ||||||
|  |     AssembleList {{ FILE }} {{ ACTION }} {{ CONTAINER }} | ||||||
|  |  | ||||||
|  | # Create toolbox containers from a defined manifest (this spec will not be expanded) | ||||||
|  | toolbox-assemble CONTAINER="prompt" ACTION="create" FILE="/etc/toolbox/toolbox.ini": | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     # Toolboxes are gathered from toolbox.ini, please add them there | ||||||
|  |     source /usr/lib/ujust/ujust.sh | ||||||
|  |     ToolboxAssembleList {{ FILE }} {{ ACTION }} {{ CONTAINER }} | ||||||
|  |  | ||||||
|  |     alias nvidia := configure-nvidia | ||||||
|  |  | ||||||
|  | # Configure the Nvidia driver | ||||||
|  | configure-nvidia ACTION="prompt": | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     source /usr/lib/ujust/ujust.sh | ||||||
|  |     OPTION={{ ACTION }} | ||||||
|  |     if [ "$OPTION" == "prompt" ]; then | ||||||
|  |       echo "${bold}Configuring Nvidia drivers${normal}" | ||||||
|  |       echo 'What would you like to do?' | ||||||
|  |       OPTION=$(ugum choose "Set needed kernel arguments" "Test CUDA support") | ||||||
|  |     elif [ "$OPTION" == "help" ]; then | ||||||
|  |       echo "Usage: ujust configure-nvidia <option>" | ||||||
|  |       echo "  <option>: Specify the quick option - 'kargs' or 'test-cuda'" | ||||||
|  |       echo "  Use 'kargs' to Set needed kernel arguments" | ||||||
|  |       echo "  Use 'test-cuda' to Test CUDA support" | ||||||
|  |       exit 0 | ||||||
|  |     fi | ||||||
|  |     if [ "$OPTION" == "Set needed kernel arguments" ] || [ "${OPTION,,}" == "kargs" ]; then | ||||||
|  |       if command -v nvidia-smi; then | ||||||
|  |       else | ||||||
|  |         echo 'You do not appear to be on a Nvidia image, please refer to the README for your uBlue-OS image.' | ||||||
|  |       fi | ||||||
|  |     elif [ "$OPTION" == "Test CUDA support" ] || [ "${OPTION,,}" == "test-cuda" ]; then | ||||||
|  |       if lsmod | grep -wq "nvidia"; then | ||||||
|  |         podman run \ | ||||||
|  |           --user 1000:1000 \ | ||||||
|  |           --security-opt=no-new-privileges \ | ||||||
|  |           --cap-drop=ALL \ | ||||||
|  |           --security-opt label=type:nvidia_container_t  \ | ||||||
|  |           --device=nvidia.com/gpu=all \ | ||||||
|  |           docker.io/nvidia/samples:vectoradd-cuda11.2.1 | ||||||
|  |       else | ||||||
|  |         echo 'The Nvidia kernel module is not loaded. You may be using secure boot without the needed signing key, lacking the needed kargs, or may not be on a Nvidia image. See "just enroll-secure-boot-key" and "just nvidia-set-kargs".' | ||||||
|  |       fi | ||||||
|  |     fi | ||||||
| @@ -1,53 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| # Tell build process to exit if there are any errors. |  | ||||||
| set -oue pipefail |  | ||||||
|  |  | ||||||
| POLICY_FILE="/usr/etc/containers/policy.json" |  | ||||||
|  |  | ||||||
| if [[ ! -f "$POLICY_FILE" ]]; then |  | ||||||
|     echo "Error: $POLICY_FILE does not exist." |  | ||||||
|     exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| sed -i 's/insecureAcceptAnything/reject/' "$POLICY_FILE" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| yq -i -o=j '.transports.docker |= |  | ||||||
|     {"ghcr.io/jasonn3": [ |  | ||||||
|         { |  | ||||||
|           "type": "sigstoreSigned", |  | ||||||
|           "keyPath": "/usr/etc/pki/containers/build-container-installer.pub", |  | ||||||
|           "signedIdentity": { |  | ||||||
|             "type": "matchRepository" |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
| + .' "$POLICY_FILE" |  | ||||||
|  |  | ||||||
| yq -i -o=j '.transports.docker |= |  | ||||||
|     {"ghcr.io/zelikos": [ |  | ||||||
|         { |  | ||||||
|           "type": "sigstoreSigned", |  | ||||||
|           "keyPath": "/usr/etc/pki/containers/davincibox.pub", |  | ||||||
|           "signedIdentity": { |  | ||||||
|             "type": "matchRepository" |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
| + .' "$POLICY_FILE" |  | ||||||
|  |  | ||||||
| yq -i -o=j '.transports.docker |= |  | ||||||
|     {"ghcr.io/wayblueorg": [ |  | ||||||
|         { |  | ||||||
|           "type": "sigstoreSigned", |  | ||||||
|           "keyPath": "/usr/etc/pki/containers/wayblue.pub", |  | ||||||
|           "signedIdentity": { |  | ||||||
|             "type": "matchRepository" |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
| + .' "$POLICY_FILE" |  | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| # Tell build process to exit if there are any errors. |  | ||||||
| set -oue pipefail |  | ||||||
|  |  | ||||||
| patch /usr/share/ublue-os/just/15-luks.just < use-pkexec-in-luks-just.patch |  | ||||||
| patch /usr/share/ublue-os/just/40-nvidia.just < remove-unusable-just-command.patch |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| 61,74d60 |  | ||||||
| < # Switch between Nvidia image and NVK |  | ||||||
| < toggle-nvk: |  | ||||||
| <     #!/usr/bin/bash |  | ||||||
| <     CURRENT_IMAGE=$(rpm-ostree status -b --json | jq -r '.deployments[0]."container-image-reference"' | sed -E 's/^.+\/(.+:.+)$/\1/') |  | ||||||
| <     CURRENT_URI=$(rpm-ostree status -b --json | jq -r '.deployments[0]."container-image-reference"' | sed -E 's/^(.+\/).+:.+$/\1/') |  | ||||||
| <     NEW_IMAGE=$CURRENT_IMAGE |  | ||||||
| <     if [[ "$CURRENT_IMAGE" =~ "nvidia" ]]; then |  | ||||||
| <       NEW_IMAGE=${CURRENT_IMAGE/-nvidia/} |  | ||||||
| <     else |  | ||||||
| <       NEW_IMAGE=${CURRENT_IMAGE/:/-nvidia:} |  | ||||||
| <     fi |  | ||||||
| <     echo "Rebasing to ${NEW_IMAGE}" |  | ||||||
| <     rpm-ostree rebase ${CURRENT_URI}${NEW_IMAGE} |  | ||||||
| <  |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| 6c6 |  | ||||||
| <     sudo /usr/libexec/luks-enable-tpm2-autounlock |  | ||||||
| --- |  | ||||||
| >     pkexec /usr/libexec/luks-enable-tpm2-autounlock |  | ||||||
| 11c11 |  | ||||||
| <     sudo /usr/libexec/luks-disable-tpm2-autounlock |  | ||||||
| --- |  | ||||||
| >     pkexec /usr/libexec/luks-disable-tpm2-autounlock |  | ||||||
							
								
								
									
										131
									
								
								files/system/etc/containers/policy.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								files/system/etc/containers/policy.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | |||||||
|  | { | ||||||
|  |   "default": [ | ||||||
|  |       { | ||||||
|  |           "type": "reject" | ||||||
|  |       } | ||||||
|  |   ], | ||||||
|  |   "transports": { | ||||||
|  |       "docker": { | ||||||
|  |         "ghcr.io/wayblueorg": [ | ||||||
|  |           { | ||||||
|  |             "type": "sigstoreSigned", | ||||||
|  |             "keyPath": "/usr/etc/pki/containers/wayblue.pub", | ||||||
|  |             "signedIdentity": { | ||||||
|  |               "type": "matchRepository" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "ghcr.io/zelikos": [ | ||||||
|  |           { | ||||||
|  |             "type": "sigstoreSigned", | ||||||
|  |             "keyPath": "/usr/etc/pki/containers/davincibox.pub", | ||||||
|  |             "signedIdentity": { | ||||||
|  |               "type": "matchRepository" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "ghcr.io/jasonn3": [ | ||||||
|  |           { | ||||||
|  |             "type": "sigstoreSigned", | ||||||
|  |             "keyPath": "/usr/etc/pki/containers/build-container-installer.pub", | ||||||
|  |             "signedIdentity": { | ||||||
|  |               "type": "matchRepository" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "registry.access.redhat.com": [ | ||||||
|  |             { | ||||||
|  |                 "type": "signedBy", | ||||||
|  |                 "keyType": "GPGKeys", | ||||||
|  |                 "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "registry.redhat.io": [ | ||||||
|  |             { | ||||||
|  |                 "type": "signedBy", | ||||||
|  |                 "keyType": "GPGKeys", | ||||||
|  |                 "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "quay.io/toolbx-images": [ | ||||||
|  |             { | ||||||
|  |                 "type": "sigstoreSigned", | ||||||
|  |                 "keyPath": "/etc/pki/containers/quay.io-toolbx-images.pub", | ||||||
|  |                 "signedIdentity": { | ||||||
|  |                     "type": "matchRepository" | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "ghcr.io/ublue-os": [ | ||||||
|  |             { | ||||||
|  |                 "type": "sigstoreSigned", | ||||||
|  |                 "keyPath": "/etc/pki/containers/ublue-os.pub", | ||||||
|  |                 "signedIdentity": { | ||||||
|  |                     "type": "matchRepository" | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "docker-daemon": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "atomic": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "containers-storage": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "dir": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "oci": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "oci-archive": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "docker-archive": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     "tarball": { | ||||||
|  |         "": [ | ||||||
|  |             { | ||||||
|  |                 "type": "reject" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | docker: | ||||||
|  |   quay.io/toolbx-images: | ||||||
|  |     use-sigstore-attachments: true | ||||||
							
								
								
									
										3
									
								
								files/system/etc/containers/registries.d/ublue-os.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								files/system/etc/containers/registries.d/ublue-os.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | docker: | ||||||
|  |   ghcr.io/ublue-os: | ||||||
|  |     use-sigstore-attachments: true | ||||||
							
								
								
									
										59
									
								
								files/system/etc/distrobox/distrobox.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								files/system/etc/distrobox/distrobox.ini
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | # Add more distros and then use: | ||||||
|  | # distrobox assemble create --replace --file /etc/distrobox/distrobox.ini --name containername | ||||||
|  | # This will replace your distroboxes in place | ||||||
|  | # Tip: Use additional_packages as declarative config! | ||||||
|  | # See https://distrobox.privatedns.org/usage/distrobox-assemble/ | ||||||
|  | [arch] | ||||||
|  | image=ghcr.io/ublue-os/arch-distrobox:latest | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [arch-amdgpupro] | ||||||
|  | image=ghcr.io/ublue-os/arch-distrobox-amdgpupro:latest | ||||||
|  | nvidia=false | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [bluefin-cli] | ||||||
|  | image=ghcr.io/ublue-os/bluefin-cli | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [debian] | ||||||
|  | image=quay.io/toolbx-images/debian-toolbox:unstable | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [fedora] | ||||||
|  | image=ghcr.io/ublue-os/fedora-distrobox:latest | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [opensuse] | ||||||
|  | image=quay.io/toolbx-images/opensuse-toolbox:tumbleweed | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [ubuntu] | ||||||
|  | image=ghcr.io/ublue-os/ubuntu-toolbox:latest | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [alma] | ||||||
|  | image=quay.io/toolbx-images/almalinux-toolbox:latest | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [centos] | ||||||
|  | image=quay.io/toolbx-images/centos-toolbox:latest | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [wolfi] | ||||||
|  | image=ghcr.io/ublue-os/wolfi-toolbox | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
|  |  | ||||||
|  | [wolfi-dx] | ||||||
|  | image=ghcr.io/ublue-os/wolfi-dx-toolbox | ||||||
|  | nvidia=true | ||||||
|  | pull=true | ||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | -----BEGIN PUBLIC KEY----- | ||||||
|  | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQr63Nsc66mA3oGMArrQPm8/AkuTO | ||||||
|  | K+ZrK3WCWzx00LW5K1qu+BS3U4eyMmXaFKIsX69PEFZWzXKy9psum8wj9Q== | ||||||
|  | -----END PUBLIC KEY----- | ||||||
							
								
								
									
										4
									
								
								files/system/etc/pki/containers/ublue-os.pub
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								files/system/etc/pki/containers/ublue-os.pub
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | -----BEGIN PUBLIC KEY----- | ||||||
|  | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHLRpBfPRYiMl9wb7s6fx47PzzNWu | ||||||
|  | 3zyJgXhWEvxoOgwv9CpwjbvUwR9qHxNMWkJhuGE6cjDA2hpy1I6NbA+24Q== | ||||||
|  | -----END PUBLIC KEY----- | ||||||
							
								
								
									
										2
									
								
								files/system/etc/profile.d/brew.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								files/system/etc/profile.d/brew.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | [[ -d /home/linuxbrew/.linuxbrew && $- == *i* ]] && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" | ||||||
							
								
								
									
										13
									
								
								files/system/etc/profile.d/user-motd.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								files/system/etc/profile.d/user-motd.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  |  | ||||||
|  | # Prevent doublesourcing | ||||||
|  | if [ -z "$USERMOTDSOURCED" ]; then | ||||||
|  |   USERMOTDSOURCED="Y" | ||||||
|  |   if test -d "$HOME"; then | ||||||
|  |     if test ! -e "$HOME"/.config/no-show-user-motd; then | ||||||
|  |       if test -x "/usr/libexec/ublue-motd"; then | ||||||
|  |         /usr/libexec/ublue-motd | ||||||
|  |       fi | ||||||
|  |     fi | ||||||
|  |   fi | ||||||
|  | fi | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | [Unit] | ||||||
|  | Wants=network-online.target | ||||||
|  | After=network-online.target | ||||||
|  |  | ||||||
|  | [Service] | ||||||
|  | ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | [Timer] | ||||||
|  | RandomizedDelaySec=10m | ||||||
|  | OnCalendar=*-*-* 4:00:00 | ||||||
|  | Persistent=true | ||||||
							
								
								
									
										11
									
								
								files/system/etc/toolbox/toolbox.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								files/system/etc/toolbox/toolbox.ini
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | # Add more distros and then use: | ||||||
|  | # ujust toolbox-assemble prompt create | ||||||
|  | # This will replace your toolboxes in place | ||||||
|  | [rhel-toolbox-8] | ||||||
|  | image=registry.access.redhat.com/ubi8/toolbox:latest | ||||||
|  |  | ||||||
|  | [rhel-toolbox-9] | ||||||
|  | image=registry.access.redhat.com/ubi9/toolbox:latest | ||||||
|  |  | ||||||
|  | [fedora-toolbox-39] | ||||||
|  | image=fedora:39 | ||||||
							
								
								
									
										13
									
								
								files/system/etc/udev/rules.d/50-framework16.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								files/system/etc/udev/rules.d/50-framework16.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | # Audio Expansion Card | ||||||
|  | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0010", ATTR{power/autosuspend}="10", ATTR{power/control}="auto", GOTO="rules_end" | ||||||
|  |  | ||||||
|  | # Framework Laptop 16 Keyboard Module - ANSI | ||||||
|  | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0012", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||||
|  |  | ||||||
|  | # Framework Laptop 16 Numpad Module | ||||||
|  | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0014", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||||
|  |  | ||||||
|  | # Framework Laptop 16 Keyboard Module | ||||||
|  | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0018", ATTR{power/autosuspend}="-1", ATTR{power/control}="on", ATTR{power/wakeup}="disabled", GOTO="rules_end" | ||||||
|  |  | ||||||
|  | LABEL="rules_end" | ||||||
							
								
								
									
										46
									
								
								files/system/etc/udev/rules.d/50-usb-realtek-net.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								files/system/etc/udev/rules.d/50-usb-realtek-net.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # This is used to change the default configuration of Realtek USB ethernet adapters | ||||||
|  |  | ||||||
|  | ACTION!="add", GOTO="usb_realtek_net_end" | ||||||
|  | SUBSYSTEM!="usb", GOTO="usb_realtek_net_end" | ||||||
|  | ENV{DEVTYPE}!="usb_device", GOTO="usb_realtek_net_end" | ||||||
|  |  | ||||||
|  | # Modify this to change the default value | ||||||
|  | ENV{REALTEK_MODE1}="1" | ||||||
|  | ENV{REALTEK_MODE2}="3" | ||||||
|  |  | ||||||
|  | # Realtek | ||||||
|  | ATTR{idVendor}=="0bda", ATTR{idProduct}=="815[2,3,5,6]", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="0bda", ATTR{idProduct}=="8053", ATTR{bcdDevice}=="e???", ATTR{bConfigurationValue}!="$env{REALTEK_MODE2}", ATTR{bConfigurationValue}="$env{REALTEK_MODE2}" | ||||||
|  |  | ||||||
|  | # Samsung | ||||||
|  | ATTR{idVendor}=="04e8", ATTR{idProduct}=="a101", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  |  | ||||||
|  | # Lenovo | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="304f", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3052", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3054", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3057", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3062", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3069", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3082", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="3098", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="7205", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="720a", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="720b", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="720c", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="7214", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="721e", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="8153", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="a359", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  | ATTR{idVendor}=="17ef", ATTR{idProduct}=="a387", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  |  | ||||||
|  | # TP-LINK | ||||||
|  | ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  |  | ||||||
|  | # Nvidia | ||||||
|  | ATTR{idVendor}=="0955", ATTR{idProduct}=="09ff", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  |  | ||||||
|  | # LINKSYS | ||||||
|  | ATTR{idVendor}=="13b1", ATTR{idProduct}=="0041", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}" | ||||||
|  |  | ||||||
|  | LABEL="usb_realtek_net_end" | ||||||
							
								
								
									
										1
									
								
								files/system/etc/udev/rules.d/70-titan-key.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								files/system/etc/udev/rules.d/70-titan-key.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1|096e", ATTRS{idProduct}=="5026|0858|085b", TAG+="uaccess" | ||||||
							
								
								
									
										89
									
								
								files/system/etc/udev/rules.d/70-u2f.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								files/system/etc/udev/rules.d/70-u2f.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | # Copyright (C) 2013-2015 Yubico AB | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or modify it | ||||||
|  | # under the terms of the GNU Lesser General Public License as published by | ||||||
|  | # the Free Software Foundation; either version 2.1, or (at your option) | ||||||
|  | # any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, but | ||||||
|  | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser | ||||||
|  | # General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU Lesser General Public License | ||||||
|  | # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | # this udev file should be used with udev 188 and newer | ||||||
|  | ACTION!="add|change", GOTO="u2f_end" | ||||||
|  |  | ||||||
|  | # Yubico YubiKey | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0121|0200|0402|0403|0406|0407|0410", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Happlink (formerly Plug-Up) Security KEY | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Neowave Keydo and Keydo AES | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1d0|f1ae", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # HyperSecu HyperFIDO | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e|2ccf", ATTRS{idProduct}=="0880", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Feitian ePass FIDO, BioPass FIDO2 | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0850|0852|0853|0854|0856|0858|085a|085b|085d|0866|0867", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # JaCarta U2F | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="24dc", ATTRS{idProduct}=="0101|0501", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # U2F Zero | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # VASCO SecureClick | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1a44", ATTRS{idProduct}=="00bb", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Bluink Key | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2abe", ATTRS{idProduct}=="1002", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Thetis Key | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1ea8", ATTRS{idProduct}=="f025", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Nitrokey FIDO U2F, Nitrokey FIDO2, Safetech SafeKey | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4287|42b1|42b3", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Google Titan U2F | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="5026", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Tomu board + chopstx U2F + SoloKeys | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="cdab|a2ca", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # SoloKeys | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5070|50b0", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Trezor | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Infineon FIDO | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="058b", ATTRS{idProduct}=="022d", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Ledger Blue, Nano S and Nano X | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000|0001|0004|0005|0015|1005|1015|4005|4015", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Kensington VeriMark | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="06cb", ATTRS{idProduct}=="0088", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # Longmai mFIDO | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="4c4d", ATTRS{idProduct}=="f703", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # eWBM FIDO2 - Goldengate 310, 320, 500, 450 | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4a1a|4c2a|5c2f|f47c", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # OnlyKey (FIDO2 / U2F) | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # GoTrust Idem Key | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="f143", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | # ellipticSecure MIRKey | ||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ac", TAG+="uaccess", GROUP="plugdev", MODE="0660" | ||||||
|  |  | ||||||
|  | LABEL="u2f_end" | ||||||
							
								
								
									
										96
									
								
								files/system/etc/udev/rules.d/70-wooting.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								files/system/etc/udev/rules.d/70-wooting.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | # Wooting One Legacy | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff01", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff01", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting One update mode  | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2402", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two Legacy | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff02", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="ff02", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two update mode   | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2403", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting One | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1100", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1100", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting One Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1101", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1101", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting One 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1102", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1102", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1200", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1200", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1201", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1201", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1202", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1202", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Lekker | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1210", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1210", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Lekker Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1211", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1211", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Lekker 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1212", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1212", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Lekker update mode   | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="121f", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two HE | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1220", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1220", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two HE Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1221", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1221", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two HE 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1222", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1222", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two HE update mode   | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="122f", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two HE (ARM) | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1230", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1230", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two HE Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1231", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1231", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting Two HE 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1232", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1232", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting Two HE (ARM) update mode   | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="123f", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting 60HE | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1300", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1300", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting 60HE Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1301", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1301", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting 60HE 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1302", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1302", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting 60HE update mode   | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="130f", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting 60HE (ARM) | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1310", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1310", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting 60HE (ARM) Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1311", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1311", MODE="0660", TAG+="uaccess" | ||||||
|  | # Wooting 60HE (ARM) 2nd Alt-gamepad mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1312", MODE="0660", TAG+="uaccess" | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="1312", MODE="0660", TAG+="uaccess" | ||||||
|  |  | ||||||
|  | # Wooting 60HE (ARM) update mode | ||||||
|  | SUBSYSTEM=="hidraw", ATTRS{idVendor}=="31e3", ATTRS{idProduct}=="131f", MODE="0660", TAG+="uaccess" | ||||||
							
								
								
									
										4
									
								
								files/system/etc/udev/rules.d/88-neutron_hifi_dac.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								files/system/etc/udev/rules.d/88-neutron_hifi_dac.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | # udev rule for Neutron HiFi DAC V1 | ||||||
|  | # https://neutronhifi.com/devices/dac/v1 | ||||||
|  |  | ||||||
|  | SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="82f9", MODE="0666" | ||||||
							
								
								
									
										5
									
								
								files/system/etc/udev/rules.d/90-apple-superdrive.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								files/system/etc/udev/rules.d/90-apple-superdrive.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | # Apple SuperDrive udev rule | ||||||
|  | # Credits: @yookoala from GitHub | ||||||
|  | # See: https://gist.github.com/yookoala/818c1ff057e3d965980b7fd3bf8f77a6 | ||||||
|  |  | ||||||
|  | ACTION=="add", ATTRS{idProduct}=="1500", ATTRS{idVendor}=="05ac", DRIVERS=="usb", RUN+="/usr/bin/sg_raw %r/sr%n EA 00 00 00 00 00 01" | ||||||
							
								
								
									
										1
									
								
								files/system/etc/udev/rules.d/92-viia.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								files/system/etc/udev/rules.d/92-viia.rules
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666", TAG+="uaccess", TAG+="udev-acl" | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | # Change the permissions of the battery threshold attributes so that they can be modified by ordinary users | ||||||
|  | # See https://gitlab.com/marcosdalvarez/thinkpad-battery-threshold-extension | ||||||
|  |  | ||||||
|  | ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold" | ||||||
|  | ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold" | ||||||
|  | ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold" | ||||||
|  | ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold" | ||||||
							
								
								
									
										204
									
								
								files/system/usr/bin/ugum
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										204
									
								
								files/system/usr/bin/ugum
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,204 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  |  | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ################################################################## | ||||||
|  | # This is a helper script to provide a basic fallback replacement  | ||||||
|  | # for just commands and bash scripts that want to use gum in uBlue | ||||||
|  | ################################################################## | ||||||
|  |  | ||||||
|  | # Supported menu handlers | ||||||
|  | SUPPORTED_HANDLERS=( | ||||||
|  |     "fzf" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | # Check if gum is present | ||||||
|  | GUM=$(which gum 2>/dev/null) | ||||||
|  |  | ||||||
|  | # Check if fzf is installed and set it as the handler | ||||||
|  | FALLBACK_HANDLER=$(which fzf 2>/dev/null) | ||||||
|  | HANDLER="" | ||||||
|  | if [[ -n $FALLBACK_HANDLER ]]; then | ||||||
|  |     HANDLER="fzf" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # If $MENU is set | ||||||
|  | if [[ -n $MENU ]]; then | ||||||
|  |     for BIN in "${SUPPORTED_HANDLERS[@]}" | ||||||
|  |     do | ||||||
|  |         if [[ "$BIN" == "$MENU" ]]; then | ||||||
|  |             HANDLER=$BIN | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Logic for what to do if gum is not installed | ||||||
|  | function noGum () { | ||||||
|  |     if [[ -z "$1" ]]; then | ||||||
|  |         # If no arguments are provided then error with  | ||||||
|  |         echo "ugum supports only choose or confirm as the first argument!" | ||||||
|  |         echo "Usage:" | ||||||
|  |         echo '    ugum choose option1 option2 \"option 3\"' | ||||||
|  |         echo '        Returns: selected string' | ||||||
|  |         echo '    ugum confirm "this is an optional question' | ||||||
|  |         echo '        Returns: exit code in $? will be 0 for YES and 1 for NO' | ||||||
|  |         exit 5 | ||||||
|  |     elif [[ "$1" == "choose" ]]; then | ||||||
|  |         # If choose is the verb then run the choose function and pass all remaining args to an appropriate handler | ||||||
|  |         if [[ "$HANDLER" == "fzf" ]]; then | ||||||
|  |             # Use fzf for choice selector | ||||||
|  |             choose_Fzf "${@:2}" | ||||||
|  |         else | ||||||
|  |             # Use generic bash selector | ||||||
|  |             choose_Generic "${@:2}" | ||||||
|  |         fi | ||||||
|  |     elif [[ "$1" == "confirm" ]]; then | ||||||
|  |         # If confirm is the verb then run the confirm function and pass all remaining args to an appropriate handler | ||||||
|  |         if [[ "$HANDLER" == "fzf" ]]; then | ||||||
|  |             # Use fzf as a confirm dialog | ||||||
|  |             confirm_Fzf "${@:2}" | ||||||
|  |         else | ||||||
|  |             # Use a generic bash dialog | ||||||
|  |             confirm_Generic "${@:2}" | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Implements a generic bash choice dialog | ||||||
|  | function choose_Generic () { | ||||||
|  |     # Change PS3 to our select prompt | ||||||
|  |     PS3='Please enter your choice: ' | ||||||
|  |  | ||||||
|  |     # Make an array to contain all options in | ||||||
|  |     OPTIONS=() | ||||||
|  |  | ||||||
|  |     # Parse the arguments for the ones we support and care about | ||||||
|  |     for arg in "$@" | ||||||
|  |     do | ||||||
|  |         # If the argument does not start with - | ||||||
|  |         if [[ ! $arg =~ ^- ]]; then | ||||||
|  |             OPTIONS+=("$arg") | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     # Make a select prompt in bash | ||||||
|  |     select opt in "${OPTIONS[@]}" | ||||||
|  |     do | ||||||
|  |         case $opt in | ||||||
|  |             "") | ||||||
|  |                 # Invalid options print to STDERR and then loops back for the user to select again | ||||||
|  |                 echo "Invalid option $REPLY" >&2 | ||||||
|  |                 ;; | ||||||
|  |             "$opt") | ||||||
|  |                 echo "$opt" | ||||||
|  |                 break | ||||||
|  |                 ;; | ||||||
|  |         esac | ||||||
|  |     done  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Implements a choice dialog using fzf | ||||||
|  | function choose_Fzf () { | ||||||
|  |     # Change our select prompt | ||||||
|  |     PROMPT='Please select your choice: ' | ||||||
|  |  | ||||||
|  |     # Make an array to contain all options in | ||||||
|  |     local OPTIONS | ||||||
|  |  | ||||||
|  |     # Parse the arguments for the ones we support and care about | ||||||
|  |     for arg in "$@" | ||||||
|  |     do | ||||||
|  |         # If the argument does not start with - | ||||||
|  |         if [[ ! $arg =~ ^- ]]; then | ||||||
|  |             if [[ "$OPTIONS" == "" ]]; then | ||||||
|  |                 OPTIONS="${arg}" | ||||||
|  |                 continue | ||||||
|  |             fi | ||||||
|  |             OPTIONS="${OPTIONS}\n${arg}" | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     # Make a select prompt using fzf | ||||||
|  |     echo -e "$OPTIONS" | fzf --layout=reverse --height="~20%" --prompt="$PROMPT" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Implements a generic bash confirm dialog | ||||||
|  | function confirm_Generic () { | ||||||
|  |     # Set default prompt | ||||||
|  |     PROMPT="Are you sure?" | ||||||
|  |  | ||||||
|  |     # Parse the arguments for the ones we support and care about  | ||||||
|  |     for arg in "$@" | ||||||
|  |     do | ||||||
|  |         if [[ ! $arg =~ ^- ]]; then | ||||||
|  |             PROMPT="$arg" | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     # Print the prompt and read input | ||||||
|  |     read -r -p "$PROMPT [Y/n]: " YESNO | ||||||
|  |     confirm_Parse "$YESNO" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Implements a confirm dialog in fzf | ||||||
|  | function confirm_Fzf () { | ||||||
|  |     PROMPT=$(confirm_getPrompt "$@") | ||||||
|  |  | ||||||
|  |     # Make the confirm prompt using fzf and read response | ||||||
|  |     YESNO=$(echo -e "Yes\nNo" | fzf --layout=reverse --height="~20%" --prompt="$PROMPT ") | ||||||
|  |     confirm_Parse "$YESNO" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Gets the prompt for the confirm dialog, with a fallback to "Are you sure?" | ||||||
|  | function confirm_getPrompt () { | ||||||
|  |     # Set default prompt | ||||||
|  |     PROMPT="Are you sure?" | ||||||
|  |  | ||||||
|  |     # Parse the arguments for the ones we support and care about  | ||||||
|  |     for arg in "$@" | ||||||
|  |     do | ||||||
|  |         if [[ ! $arg =~ ^- ]]; then | ||||||
|  |             PROMPT="$arg" | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     # Return the prompt | ||||||
|  |     echo "$PROMPT" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Parse the confirm response and translate it the same exit codes gum uses | ||||||
|  | function confirm_Parse () { | ||||||
|  |     case "$@" in | ||||||
|  |         [Yy]*) | ||||||
|  |             # Use exit code 0 for yes, just like gum | ||||||
|  |             exit 0 | ||||||
|  |             ;; | ||||||
|  |         [Nn]*) | ||||||
|  |             # Use exit code 1 for no, just like gum | ||||||
|  |             exit 1 | ||||||
|  |             ;; | ||||||
|  |         *) | ||||||
|  |             # Default exit code is 0 | ||||||
|  |             exit 0 | ||||||
|  |             ;; | ||||||
|  |     esac | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # If gum is not present | ||||||
|  | if [[ -z "$GUM" ]]; then | ||||||
|  |     noGum "$@" | ||||||
|  | else | ||||||
|  |     # If gum is present just pass args to gum | ||||||
|  |     $GUM "$@" | ||||||
|  | fi | ||||||
							
								
								
									
										15
									
								
								files/system/usr/bin/ujust
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								files/system/usr/bin/ujust
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  |  | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  | /usr/bin/just --justfile /usr/share/ublue-os/justfile "${@}" | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | add_dracutmodules+=" fido2 tpm2-tss pkcs11 pcsc " | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | enable flatpak-system-update.service | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=Flatpak Automatic Update | ||||||
|  | Documentation=man:flatpak(1) | ||||||
|  | Wants=network-online.target | ||||||
|  | After=network-online.target | ||||||
|  |  | ||||||
|  | [Service] | ||||||
|  | Type=oneshot | ||||||
|  | ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||||
|  | ExecStart=/usr/bin/flatpak --system uninstall --unused -y --noninteractive ; /usr/bin/flatpak --system update -y --noninteractive ; /usr/bin/flatpak --system repair | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=Flatpak Automatic Update Trigger | ||||||
|  | Documentation=man:flatpak(1) | ||||||
|  |  | ||||||
|  | [Timer] | ||||||
|  | RandomizedDelaySec=10m | ||||||
|  | OnBootSec=2m | ||||||
|  | OnCalendar=*-*-* 4:00:00 | ||||||
|  | Persistent=true | ||||||
|  |  | ||||||
|  | [Install] | ||||||
|  | WantedBy=timers.target | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | enable flatpak-user-update.service | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=Flatpak Automatic Update | ||||||
|  | Documentation=man:flatpak(1) | ||||||
|  | Wants=network-online.target | ||||||
|  | After=network-online.target | ||||||
|  |  | ||||||
|  | [Service] | ||||||
|  | Type=oneshot | ||||||
|  | ExecCondition=/bin/bash -c '[[ "$(busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered | cut -c 3-)" == @(2|4) ]]' | ||||||
|  | ExecStart=/usr/bin/flatpak --user uninstall --unused -y --noninteractive ; /usr/bin/flatpak --user update -y --noninteractive ; /usr/bin/flatpak --user repair | ||||||
							
								
								
									
										12
									
								
								files/system/usr/lib/systemd/user/flatpak-user-update.timer
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								files/system/usr/lib/systemd/user/flatpak-user-update.timer
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=Flatpak Automatic Update Trigger | ||||||
|  | Documentation=man:flatpak(1) | ||||||
|  |  | ||||||
|  | [Timer] | ||||||
|  | RandomizedDelaySec=10m | ||||||
|  | OnBootSec=2m | ||||||
|  | OnCalendar=*-*-* 4:00:00 | ||||||
|  | Persistent=true | ||||||
|  |  | ||||||
|  | [Install] | ||||||
|  | WantedBy=timers.target | ||||||
							
								
								
									
										11
									
								
								files/system/usr/lib/ujust/COPYRIGHT.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								files/system/usr/lib/ujust/COPYRIGHT.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | Copyright 2024 Universal Blue | ||||||
|  |  | ||||||
|  | The files in this directory contain code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | you may not use these files except in compliance with the License. | ||||||
|  | You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  | Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | See the License for the specific language governing permissions and limitations under the License. | ||||||
							
								
								
									
										50
									
								
								files/system/usr/lib/ujust/libcolors.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								files/system/usr/lib/ujust/libcolors.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # Disable shellchecks for things that do not matter for | ||||||
|  | # a sourceable file | ||||||
|  | # shellcheck disable=SC2034,SC2155 | ||||||
|  | ######## | ||||||
|  | ### Basic Colors | ||||||
|  | ### the bg function allows flipping these to background colors | ||||||
|  | ### using the 90-97 colors is not supported by the bg function | ||||||
|  | ### add them as extended colors instead which uses | ||||||
|  | ### option 38 (foreground) which can be flipped to 48 (background) | ||||||
|  | ######## | ||||||
|  | declare -r black=$'\033[30m' | ||||||
|  | declare -r red=$'\033[31m' | ||||||
|  | declare -r green=$'\033[32m' | ||||||
|  | declare -r yellow=$'\033[33m' | ||||||
|  | declare -r blue=$'\033[34m' | ||||||
|  | declare -r magenta=$'\033[35m' | ||||||
|  | declare -r purple="$magenta" | ||||||
|  | declare -r cyan=$'\033[36m' | ||||||
|  | declare -r lightgrey=$'\033[37m' | ||||||
|  | declare -r lightgray="$lightgrey" | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ### Extended Colors | ||||||
|  | ### You can use cpick from https://github.com/ethanbaker/cpick to get the colors | ||||||
|  | ### cpick bash varname | sed -E 's/readonly/declare/' | ||||||
|  | ######## | ||||||
|  | declare -r darkgrey=$'\033[38;2;168;168;168m' | ||||||
|  | declare -r darkgray="$darkgrey" | ||||||
|  | declare -r lightred=$'\033[38;2;255;114;118m' | ||||||
|  | declare -r lightgreen=$'\033[38;2;146;240;146m' | ||||||
|  | declare -r lightyellow=$'\033[38;2;255;255;224m' | ||||||
|  | declare -r lightblue=$'\033[38;2;172;215;230m' | ||||||
|  | declare -r pink=$'\033[38;2;255;20;146m' | ||||||
|  | declare -r lightmagenta="$pink" | ||||||
|  | declare -r lightcyan=$'\033[38;2;224;255;255m' | ||||||
|  | declare -r white=$'\033[38;2;250;235;215m' | ||||||
|  | declare -r lightpink=$'\033[38;2;255;181;192m' | ||||||
|  | declare -r darkorange=$'\033[38;2;255;129;3m' | ||||||
|  |  | ||||||
|  | ## Function to generate background color from foreground color | ||||||
|  | ## NOTE: doublequote the color or future calls to bg will error out! | ||||||
|  | # bgblue=$(Bg "$blue") | ||||||
|  | # echo "${bgblue}text now has blue background${normal} this text has no background color" | ||||||
|  | function Bg (){ | ||||||
|  |     COLOR="$1" | ||||||
|  |      | ||||||
|  |     # Flip foreground to background | ||||||
|  |     echo "$COLOR" | sed -E 's/\[3([0-8]{1,1})/\[4\1/' | ||||||
|  | } | ||||||
							
								
								
									
										138
									
								
								files/system/usr/lib/ujust/libdistrobox.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								files/system/usr/lib/ujust/libdistrobox.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # shellcheck disable=SC2154 | ||||||
|  | ######## | ||||||
|  | ## Function to create a distrobox with standardized args | ||||||
|  | ######## | ||||||
|  | ## Create a distrobox using default fedora:latest, name the box "my-fedora-box" and give it a custom homedir | ||||||
|  | # Distrobox "fedora:latest" "my-fedora-box" "$HOME/.var/containers/fedora-box" | ||||||
|  | ## Create a debian toolbox distrobox named debian-unstable | ||||||
|  | # Distrobox "quay.io/toolbx-images/debian-toolbox:unstable" "debian-unstable" | ||||||
|  | ## Create an ubuntu distrobox named someubuntubox with no custom homedir and unshare network namespace | ||||||
|  | ## ($3 is required if supplying extra args, using "" makes the function skip it) | ||||||
|  | # Distrobox "ubuntu:latest" "someubuntubox" "" --unshare-ns | ||||||
|  | function Distrobox (){ | ||||||
|  |     IMAGE="$1" | ||||||
|  |     NAME="$2" | ||||||
|  |     HOMEDIR="" | ||||||
|  |     # If custom home directory is supplied | ||||||
|  |     if [ -n "$3" ]; then | ||||||
|  |         HOMEDIR="$3" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If a custom home directory is not specified | ||||||
|  |     if [ -z "$HOMEDIR" ]; then | ||||||
|  |         distrobox create --nvidia -Y --image "$IMAGE" -n "$NAME" "${@:3}" | ||||||
|  |     else | ||||||
|  |         # Make the custom homedir path if it does not exist | ||||||
|  |         if [ ! -d "$HOMEDIR" ]; then | ||||||
|  |             mkdir -p "$HOMEDIR" | ||||||
|  |         fi | ||||||
|  |         # Create distrobox with custom home path | ||||||
|  |         distrobox create --nvidia -Y --image "$IMAGE" -n "$NAME" -H "$HOMEDIR" "${@:4}" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to assemble pre-defined distrobox containers from manifest files | ||||||
|  | ######## | ||||||
|  | ## Assemble all containers defined in an ini file without confirmation | ||||||
|  | # Assemble noconfirmcreate "/etc/distrobox/distrobox.ini" | ||||||
|  | # Assemble noconfirmcreate "" ALL | ||||||
|  | ## Assemble ubuntu from default ini manifest, with confirmation | ||||||
|  | # Assemble confirm "" ubuntu | ||||||
|  | ## Remove a container defined in the default ini manifest | ||||||
|  | # Assemble rm "" ubuntu | ||||||
|  | function Assemble(){ | ||||||
|  |     # Set defaults | ||||||
|  |     ACTION="create" | ||||||
|  |     FILE="/etc/distrobox/distrobox.ini" | ||||||
|  |     NAME="" | ||||||
|  |  | ||||||
|  |     # If an action is provided | ||||||
|  |     if [ -n "$1" ]; then | ||||||
|  |         # Set ACTION to the action specified | ||||||
|  |         # and remove "noconfirm" from $1 when assigning it to ACTION | ||||||
|  |         ACTION="${1/noconfirm/}" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If a filename is provided | ||||||
|  |     if [ -n "$2" ]; then | ||||||
|  |         # Set FILE to the provided filename | ||||||
|  |         FILE="$2" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If container name is ALL | ||||||
|  |     if [ "$3" == "ALL" ] || [ -z "$3" ]; then | ||||||
|  |         if [[ ! "$1" =~ ^noconfirm ]]; then | ||||||
|  |             # Ask user if they REALLY want to assemble all the containers | ||||||
|  |             echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n}\nALL containers defined in ${b}$FILE${n}." | ||||||
|  |             CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||||
|  |             if [ "$CONFIRM" == "1" ]; then | ||||||
|  |                 echo "Aborting..." | ||||||
|  |                 return 1 | ||||||
|  |             fi | ||||||
|  |         fi | ||||||
|  |         # Run the distrobox assemble command | ||||||
|  |         distrobox assemble "$ACTION" --file "$FILE" --replace | ||||||
|  |         return $? | ||||||
|  |     else | ||||||
|  |         # Set distrobox name to provided name | ||||||
|  |         NAME="$3" | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     # If we do not want confirmations | ||||||
|  |     if [[ ! "$1" =~ ^noconfirm ]]; then | ||||||
|  |         # Ask the user if they really want to replace $NAME container | ||||||
|  |         echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n} the container ${b}$NAME${n}\nwith the one defined in ${b}$FILE${n}." | ||||||
|  |         CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||||
|  |         if [ "$CONFIRM" == "1" ]; then | ||||||
|  |             echo "Aborting..." | ||||||
|  |             return 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # Run the distrobox assemble command | ||||||
|  |     distrobox assemble "$ACTION" --file "$FILE" --name "$NAME" --replace | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to parse a distrobox.ini file and make a selectable list from it | ||||||
|  | ######## | ||||||
|  | ## Parse a distrobox.ini manifest and let user select which container to setup | ||||||
|  | # AssembleList "$HOME/distrobox.ini" create | ||||||
|  | ## Parse a distrobox.ini manifest and create ubuntu container without confirmation | ||||||
|  | # AssembleList "$HOME/distrobox.ini" noconfirmcreate ubuntu | ||||||
|  | function AssembleList (){ | ||||||
|  |     # Set defaults | ||||||
|  |     FILE="$1" | ||||||
|  |     ACTION="create" | ||||||
|  |     CHOICE="prompt" | ||||||
|  |  | ||||||
|  |     # If an ACTION is supplied | ||||||
|  |     if [ -n "$2" ]; then | ||||||
|  |         # Replace default action | ||||||
|  |         ACTION="$2" | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     # If a CHOICE is predefined | ||||||
|  |     if [ -n "$3" ]; then | ||||||
|  |         # Replace default choice | ||||||
|  |         CHOICE="$3" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If the choice is "prompt" then ask user what container they want | ||||||
|  |     if [ "$CHOICE" == "prompt" ]; then | ||||||
|  |         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||||
|  |         echo "${b}Pre-defined Containers${n}" | ||||||
|  |         echo "Please select a container to create" | ||||||
|  |         # Disable an irrelevant shellscheck for next line as we want word splitting | ||||||
|  |         # shellcheck disable=SC2086 | ||||||
|  |         CHOICE=$(Choose ALL $CONTAINERS) | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If choice is not empty by now (will be empty if escaped from Choice function) | ||||||
|  |     if [ -n "$CHOICE" ]; then | ||||||
|  |         # Assemble the selected container | ||||||
|  |         Assemble "$ACTION" "$FILE" "$CHOICE" | ||||||
|  |     fi | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								files/system/usr/lib/ujust/libformatting.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								files/system/usr/lib/ujust/libformatting.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # Disable shellchecks for things that do not matter for | ||||||
|  | # a sourceable file | ||||||
|  | # shellcheck disable=SC2034,SC2155 | ||||||
|  | ######## | ||||||
|  | ### Text Formating | ||||||
|  | ######## | ||||||
|  | declare -r bold=$'\033[1m' | ||||||
|  | declare -r b="$bold" | ||||||
|  | declare -r dim=$'\033[2m' | ||||||
|  | declare -r underline=$'\033[4m' | ||||||
|  | declare -r u="$underline" | ||||||
|  | declare -r blink=$'\033[5m' | ||||||
|  | declare -r invert=$'\033[7m' | ||||||
|  | declare -r highlight="$invert" | ||||||
|  | declare -r hidden=$'\033[8m' | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ### Remove Text Formating | ||||||
|  | ######## | ||||||
|  | declare -r normal=$'\033[0m' | ||||||
|  | declare -r n="$normal" | ||||||
|  | declare -r unbold=$'\033[21m' | ||||||
|  | declare -r undim=$'\033[22m' | ||||||
|  | declare -r nounderline=$'\033[24m' | ||||||
|  | declare -r unblink=$'\033[25m' | ||||||
|  | declare -r uninvert=$'\033[27m' | ||||||
|  | declare -r unhide=$'\033[28m' | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ### Special text formating | ||||||
|  | ######## | ||||||
|  | ## Function to generate a clickable link, you can call this using | ||||||
|  | # url=$(Urllink "https://ublue.it" "Visit the ublue website") | ||||||
|  | # echo "${url}" | ||||||
|  | function Urllink (){ | ||||||
|  |     URL=$1 | ||||||
|  |     TEXT=$2 | ||||||
|  |  | ||||||
|  |     # Generate a clickable hyperlink | ||||||
|  |     printf "\e]8;;%s\e\\%s\e]8;;\e\\" "$URL" "$TEXT${n}" | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								files/system/usr/lib/ujust/libfunctions.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								files/system/usr/lib/ujust/libfunctions.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # shellcheck disable=SC2154 | ||||||
|  | ######## | ||||||
|  | ## Useful functions we use a lot, if you want to use them, source libjust.sh | ||||||
|  | ## As it depends on libformatting.sh and libcolors.sh | ||||||
|  | ## They are not imported here to avoid attempting to redeclare readonly vars. | ||||||
|  | ######## | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to generate a choice selection and return the selected choice | ||||||
|  | ######## | ||||||
|  | # CHOICE=$(Choice option1 option2 "option 3") | ||||||
|  | # *user selects "option 3"* | ||||||
|  | # echo "$CHOICE" will return "option 3" | ||||||
|  | function Choose (){ | ||||||
|  |     CHOICE=$(ugum choose "$@") | ||||||
|  |     echo "$CHOICE" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to generate a confirm dialog and return the selected choice | ||||||
|  | ######## | ||||||
|  | # CHOICE=$(Confirm "Are you sure you want to do this?") | ||||||
|  | # *user selects "No"* | ||||||
|  | # echo "$CHOICE" will return "1" | ||||||
|  | # 0 = Yes | ||||||
|  | # 1 = No | ||||||
|  | function Confirm (){ | ||||||
|  |     ugum confirm "$@" | ||||||
|  |     echo $? | ||||||
|  | } | ||||||
							
								
								
									
										171
									
								
								files/system/usr/lib/ujust/libtoolbox.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								files/system/usr/lib/ujust/libtoolbox.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # shellcheck disable=SC2154 | ||||||
|  | ######## | ||||||
|  | ## Function to create a toolbox with standardized args | ||||||
|  | ######## | ||||||
|  | ## Create a debian toolbox toolbox named debian-unstable | ||||||
|  | # Toolbox create "quay.io/toolbx-images/debian-toolbox:unstable" "debian-unstable" | ||||||
|  | ## Create an ubuntu toolbox and provide an authfile to authenticate with the registry | ||||||
|  | # Toolbox create "ubuntu:22.04" --authfile "/path/to/file" | ||||||
|  | function Toolbox (){ | ||||||
|  |     # Get the action we want to do | ||||||
|  |     local ACTION="$1" | ||||||
|  |     # Get the "image" argument, we use this as an abstraction layer | ||||||
|  |     # To decide if it is an image registry or a distro+release image argument | ||||||
|  |     local IMAGE="$2" | ||||||
|  |  | ||||||
|  |     # Define local variables | ||||||
|  |     local DISTRORELEASE | ||||||
|  |  | ||||||
|  |     # If the ACTION is "replace" | ||||||
|  |     if [ "$1" == "replace" ]; then | ||||||
|  |         # Set ACTION to create | ||||||
|  |         ACTION="create" | ||||||
|  |  | ||||||
|  |         # Remove old image before continuing | ||||||
|  |         toolbox rm --force "${@:3}"  | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # Check if $IMAGE is an image registry url | ||||||
|  |     if [[ "$IMAGE" =~ / ]]; then | ||||||
|  |         # Create toolbox based on image from registry | ||||||
|  |         toolbox "$ACTION" --image "$IMAGE" "${@:3}" | ||||||
|  |     else | ||||||
|  |         # Split IMAGE string into an array | ||||||
|  |         # shellcheck disable=SC2206 | ||||||
|  |         DISTRORELEASE=(${IMAGE//:/ }) | ||||||
|  |         # Create toolbox with distro and release args | ||||||
|  |         toolbox "$ACTION" --distro "${DISTRORELEASE[0]}" --release "${DISTRORELEASE[1]}" "${@:3}"  | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to assemble pre-defined toolbox containers from manifest files | ||||||
|  | ######## | ||||||
|  | ## Assemble all containers defined in an ini file without confirmation | ||||||
|  | # ToolboxAssemble noconfirmcreate "/etc/toolbox/toolbox.ini" | ||||||
|  | # ToolboxAssemble noconfirmcreate "/etc/toolbox/toolbox.ini" ALL | ||||||
|  | ## Assemble ubuntu from default ini manifest, with confirmation | ||||||
|  | # ToolboxAssemble confirm "/etc/toolbox/toolbox.ini" ubuntu-toolbox-22.04 | ||||||
|  | ## Remove a container defined in the default ini manifest | ||||||
|  | # ToolboxAssemble rm "/etc/toolbox/toolbox.ini" ubuntu-toolbox-22.04 | ||||||
|  | function ToolboxAssemble (){ | ||||||
|  |     # Set defaults | ||||||
|  |     local ACTION="create" | ||||||
|  |     local FILE="/etc/toolbox/toolbox.ini" | ||||||
|  |     local NAME="" | ||||||
|  |  | ||||||
|  |     # Define local variables | ||||||
|  |     local CONTAINERS | ||||||
|  |     local IMAGE | ||||||
|  |     local CONFIRM | ||||||
|  |  | ||||||
|  |     # If an action is provided | ||||||
|  |     if [ -n "$1" ]; then | ||||||
|  |         # Set ACTION to the action specified | ||||||
|  |         # and remove "noconfirm" from $1 when assigning it to ACTION | ||||||
|  |         ACTION="${1/noconfirm/}" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If a filename is provided | ||||||
|  |     if [ -n "$2" ]; then | ||||||
|  |         # Set FILE to the provided filename | ||||||
|  |         FILE="$2" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If container name is ALL | ||||||
|  |     if [ "$3" == "ALL" ] || [ -z "$3" ]; then | ||||||
|  |         if [[ ! "$1" =~ ^noconfirm ]]; then | ||||||
|  |             # Ask user if they REALLY want to assemble all the containers | ||||||
|  |             echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n}\nALL containers defined in ${b}$FILE${n}." | ||||||
|  |             CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||||
|  |             if [ "$CONFIRM" == "1" ]; then | ||||||
|  |                 echo "Aborting..." | ||||||
|  |                 return 1 | ||||||
|  |             fi | ||||||
|  |         fi | ||||||
|  |         # Get all the containers | ||||||
|  |         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||||
|  |          | ||||||
|  |         # Run the toolbox assemble command | ||||||
|  |         #toolbox assemble "$ACTION" --file "$FILE" --replace | ||||||
|  |         for CONTAINER in $CONTAINERS | ||||||
|  |         do | ||||||
|  |             # Get the image for the container | ||||||
|  |             IMAGE=$(grep -A1 -P "\[$CONTAINER\]" "$FILE" | grep "image" | sed 's/image=//') | ||||||
|  |  | ||||||
|  |             # Replace the container | ||||||
|  |             Toolbox replace "$IMAGE" "$CONTAINER" | ||||||
|  |         done | ||||||
|  |         return $? | ||||||
|  |     else | ||||||
|  |         # Set toolbox name to provided name | ||||||
|  |         NAME="$3" | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     # If we do not want confirmations | ||||||
|  |     if [[ ! "$1" =~ ^noconfirm ]]; then | ||||||
|  |         # Ask the user if they really want to replace $NAME container | ||||||
|  |         echo -e "${b}WARNING${n}: This will assemble and ${u}replace${n} the container ${b}$NAME${n}\nwith the one defined in ${b}$FILE${n}." | ||||||
|  |         CONFIRM=$(Confirm "Are you sure you want to do this?") | ||||||
|  |         if [ "$CONFIRM" == "1" ]; then | ||||||
|  |             echo "Aborting..." | ||||||
|  |             return 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # Get the image for the container | ||||||
|  |     IMAGE=$(grep -A1 -P "\[$NAME\]" "$FILE" | grep "image" | sed 's/image=//') | ||||||
|  |  | ||||||
|  |     # Replace the toolbox container | ||||||
|  |     Toolbox replace "$IMAGE" "$NAME" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ######## | ||||||
|  | ## Function to parse a toolbox.ini file and make a selectable list from it | ||||||
|  | ######## | ||||||
|  | ## Parse a toolbox.ini manifest and let user select which container to setup | ||||||
|  | # ToolboxAssembleList "$HOME/toolbox.ini" create | ||||||
|  | ## Parse a toolbox.ini manifest and create ubuntu container without confirmation | ||||||
|  | # ToolboxAssembleList "$HOME/toolbox.ini" noconfirmcreate ubuntu-toolbox-22.04 | ||||||
|  | function ToolboxAssembleList (){ | ||||||
|  |     # Set defaults | ||||||
|  |     local FILE="$1" | ||||||
|  |     local ACTION="create" | ||||||
|  |     local CHOICE="prompt" | ||||||
|  |  | ||||||
|  |     # Define local variables | ||||||
|  |     local CONTAINERS | ||||||
|  |  | ||||||
|  |     # If an ACTION is supplied | ||||||
|  |     if [ -n "$2" ]; then | ||||||
|  |         # Replace default action | ||||||
|  |         ACTION="$2" | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     # If a CHOICE is predefined | ||||||
|  |     if [ -n "$3" ]; then | ||||||
|  |         # Replace default choice | ||||||
|  |         CHOICE="$3" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If the choice is "prompt" then ask user what container they want | ||||||
|  |     if [ "$CHOICE" == "prompt" ]; then | ||||||
|  |         CONTAINERS=$(grep -P "\[.+\]" "$FILE" | sed -E 's/\[(.+)\]/\1/') | ||||||
|  |         echo "${b}Pre-defined Containers${n}" | ||||||
|  |         echo "Please select a container to create" | ||||||
|  |         # Disable an irrelevant shellscheck for next line as we want word splitting | ||||||
|  |         # shellcheck disable=SC2086 | ||||||
|  |         CHOICE=$(Choose ALL $CONTAINERS) | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # If choice is not empty by now (will be empty if escaped from Choice function) | ||||||
|  |     if [ -n "$CHOICE" ]; then | ||||||
|  |         # If ACTION is create | ||||||
|  |         if [ "$ACTION" == "create" ]; then | ||||||
|  |             ACTION="replace" | ||||||
|  |         fi | ||||||
|  |         # Assemble the selected container | ||||||
|  |         ToolboxAssemble "$ACTION" "$FILE" "$CHOICE" | ||||||
|  |     fi | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								files/system/usr/lib/ujust/ujust.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								files/system/usr/lib/ujust/ujust.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | # shellcheck source=/dev/null | ||||||
|  | # Import color formatting | ||||||
|  | source /usr/lib/ujust/libcolors.sh | ||||||
|  | # Import text formatting | ||||||
|  | source /usr/lib/ujust/libformatting.sh | ||||||
|  | # Import functionality for just | ||||||
|  | source /usr/lib/ujust/libfunctions.sh | ||||||
|  | # Import functionality related to distrobox | ||||||
|  | source /usr/lib/ujust/libdistrobox.sh | ||||||
|  | # Import functionality related to toolbox | ||||||
|  | source /usr/lib/ujust/libtoolbox.sh | ||||||
							
								
								
									
										95
									
								
								files/system/usr/libexec/luks-disable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										95
									
								
								files/system/usr/libexec/luks-disable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## disable auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others | ||||||
|  | set -euo pipefail | ||||||
|  |  | ||||||
|  | [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} | ||||||
|  |  | ||||||
|  | echo "This script utilizes systemd-cryptenroll for removing tpm2 auto-unlock." | ||||||
|  | echo "You can review systemd-cryptenroll's manpage for more information." | ||||||
|  | echo "This will modify your system and disable TPM2 auto-unlock of your LUKS partition!" | ||||||
|  | read -p "Are you sure are good with this and want to disable TPM2 auto-unlock? (y/N): " -n 1 -r | ||||||
|  | echo | ||||||
|  | if [[ ! $REPLY =~ ^[Yy]$ ]]; then | ||||||
|  |   [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Inspect Kernel Cmdline for rd.luks.uuid | ||||||
|  | RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" | ||||||
|  |  | ||||||
|  | # Check to make sure cmdline rd.luks.uuid exists | ||||||
|  | if [[ -z ${RD_LUKS_UUID:-} ]]; then | ||||||
|  |   printf "LUKS device not defined on Kernel Commandline.\n" | ||||||
|  |   printf "This is not supported by this script.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check to make sure that the specified cmdline uuid exists. | ||||||
|  | if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then | ||||||
|  |   printf "LUKS device not listed in block devices.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Cut off the luks- | ||||||
|  | LUKS_PREFIX="luks-" | ||||||
|  | if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then | ||||||
|  |   DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} | ||||||
|  | else | ||||||
|  |   echo "LUKS UUID format mismatch." | ||||||
|  |   echo "Exiting..." | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Specify Crypt Disk by-uuid | ||||||
|  | CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" | ||||||
|  |  | ||||||
|  | # Check to make sure crypt disk exists | ||||||
|  | if [[ ! -L "$CRYPT_DISK" ]]; then | ||||||
|  |   printf "LUKS device not listed in block devices.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Restore the crypttab | ||||||
|  | cp -a /etc/crypttab /etc/crypttab.working-before-disable-tpm2 | ||||||
|  | if [ -f /etc/crypttab.known-good ]; then | ||||||
|  |   echo "Restoring /etc/crypttab.known-good to original /etc/crypttab" | ||||||
|  |   mv /etc/crypttab.known-good /etc/crypttab | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Wipe luks slot | ||||||
|  | if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then | ||||||
|  |   echo "Wiping systemd-tpm2 from LUKS on $CRYPT_DISK" | ||||||
|  |   systemd-cryptenroll --wipe-slot=tpm2 "$CRYPT_DISK" | ||||||
|  | else | ||||||
|  |   echo "No systemd-tpm2 found in LUKS to wipe" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Disable initramfs | ||||||
|  | if rpm-ostree initramfs | grep tpm2 > /dev/null; then | ||||||
|  |   echo "WARNING: if you configured initramfs for anything other than TPM2, this wipes that too..." | ||||||
|  |   echo "here's a printout:" | ||||||
|  |   rpm-ostree initramfs | ||||||
|  |   echo | ||||||
|  |   echo "Disabling rpm-ostree initramfs..." | ||||||
|  |   rpm-ostree initramfs --disable | ||||||
|  | else | ||||||
|  |   echo "TPM2 is not configured in 'rpm-ostree initramfs'..." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo "TPM2 auto-unlock disabled..." | ||||||
							
								
								
									
										123
									
								
								files/system/usr/libexec/luks-enable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								files/system/usr/libexec/luks-enable-tpm2-autounlock
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | # Copyright 2024 Universal Blue | ||||||
|  | # | ||||||
|  | # This file includes code that is licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software distributed under the License is | ||||||
|  | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and limitations under the License. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## setup auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others | ||||||
|  | set -eou pipefail | ||||||
|  |  | ||||||
|  |  | ||||||
|  | [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} | ||||||
|  |  | ||||||
|  | echo "WARNING: Do NOT use this if your CPU is vulnerable to faulTPM!" | ||||||
|  | echo "All AMD Zen2 and Zen3 Processors are known to be affected!" | ||||||
|  | echo "All AMD Zen1 processors are also likely affected, with Zen4 unknown!" | ||||||
|  | echo "If you have an AMD CPU, you likely shouldn't use this!" | ||||||
|  | echo "----------------------------------------------------------------------------" | ||||||
|  | echo "This script uses systemd-cryptenroll to enable TPM2 auto-unlock." | ||||||
|  | echo "You can review systemd-cryptenroll's manpage for more information." | ||||||
|  | echo "This script will modify your system." | ||||||
|  | echo "It will enable TPM2 auto-unlock of your LUKS partition for your root device!" | ||||||
|  | echo "It will bind to PCR 7 and 14 which is tied to your secureboot and moklist state." | ||||||
|  | read -p "Are you sure are good with this and want to enable TPM2 auto-unlock? (y/N): " -n 1 -r | ||||||
|  | echo | ||||||
|  | if [[ ! $REPLY =~ ^[Yy]$ ]]; then | ||||||
|  |   [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Inspect Kernel Cmdline for rd.luks.uuid | ||||||
|  | RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" | ||||||
|  |  | ||||||
|  | # Check to make sure cmdline rd.luks.uuid exists | ||||||
|  | if [[ -z ${RD_LUKS_UUID:-} ]]; then | ||||||
|  |   printf "LUKS device not defined on Kernel Commandline.\n" | ||||||
|  |   printf "This is not supported by this script.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check to make sure that the specified cmdline uuid exists. | ||||||
|  | if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then | ||||||
|  |   printf "LUKS device not listed in block devices.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Cut off the luks- | ||||||
|  | LUKS_PREFIX="luks-" | ||||||
|  | if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then | ||||||
|  |   DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} | ||||||
|  | else | ||||||
|  |   echo "LUKS UUID format mismatch." | ||||||
|  |   echo "Exiting..." | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | SET_PIN_ARG="" | ||||||
|  | read -p "Would you like to set a PIN? (y/N): " -n 1 -r | ||||||
|  | echo | ||||||
|  | if [[ $REPLY =~ ^[Yy]$ ]]; then | ||||||
|  |   SET_PIN_ARG=" --tpm2-with-pin=yes " | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Specify Crypt Disk by-uuid | ||||||
|  | CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" | ||||||
|  |  | ||||||
|  | # Check to make sure crypt disk exists | ||||||
|  | if [[ ! -L "$CRYPT_DISK" ]]; then | ||||||
|  |   printf "LUKS device not listed in block devices.\n" | ||||||
|  |   printf "Exiting...\n" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then | ||||||
|  |   KEYSLOT=$(cryptsetup luksDump "$CRYPT_DISK"|grep -A29 systemd-tpm2|grep Keyslot|awk '{print $2}') | ||||||
|  |   echo "TPM2 already present in LUKS keyslot $KEYSLOT of $CRYPT_DISK." | ||||||
|  |   read -p "Wipe it and re-enroll? (y/N): " -n 1 -r | ||||||
|  |   echo | ||||||
|  |   if [[ $REPLY =~ ^[Yy]$ ]]; then | ||||||
|  |     systemd-cryptenroll --wipe-slot=tpm2 "$CRYPT_DISK" | ||||||
|  |   else | ||||||
|  |     echo | ||||||
|  |     echo "Either clear the existing TPM2 keyslot before retrying, else choose 'y' next time." | ||||||
|  |     echo "Exiting..." | ||||||
|  |     [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 | ||||||
|  |   fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Run crypt enroll | ||||||
|  | echo "Enrolling TPM2 unlock requires your existing LUKS2 unlock password" | ||||||
|  | systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+14 $SET_PIN_ARG "$CRYPT_DISK" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if lsinitrd 2>&1 | grep -q tpm2-tss > /dev/null; then | ||||||
|  |   ## add tpm2-tss to initramfs | ||||||
|  |   if rpm-ostree initramfs | grep tpm2 > /dev/null; then | ||||||
|  |     echo "TPM2 already present in rpm-ostree initramfs config." | ||||||
|  |     rpm-ostree initramfs | ||||||
|  |     echo "Re-running initramfs to pickup changes above." | ||||||
|  |   fi | ||||||
|  |   rpm-ostree initramfs --enable --arg=--force-add --arg=tpm2-tss | ||||||
|  | else | ||||||
|  |   ## initramfs already containts tpm2-tss | ||||||
|  |   echo "TPM2 already present in initramfs." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | ## Now reboot | ||||||
|  | echo | ||||||
|  | echo "TPM2 LUKS auto-unlock configured. Reboot now." | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # References: | ||||||
|  | #  https://www.reddit.com/r/Fedora/comments/uo4ufq/any_way_to_get_systemdcryptenroll_working_on/ | ||||||
|  | #  https://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html | ||||||
							
								
								
									
										2
									
								
								files/system/usr/share/ublue-os/just/60-custom.just
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								files/system/usr/share/ublue-os/just/60-custom.just
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | # vim: set ft=make : | ||||||
|  | # This file can be modified downstream to add custom just commands | ||||||
							
								
								
									
										10
									
								
								files/system/usr/share/ublue-os/justfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								files/system/usr/share/ublue-os/justfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | set allow-duplicate-recipes := true | ||||||
|  | set ignore-comments := true | ||||||
|  |  | ||||||
|  | _default: | ||||||
|  |     #!/usr/bin/bash | ||||||
|  |     source /usr/lib/ujust/libformatting.sh | ||||||
|  |     /usr/bin/ujust --list --list-heading $'Available commands:\n' --list-prefix $' - ' | ||||||
|  |  | ||||||
|  | # Imports | ||||||
|  | import "/usr/share/ublue-os/just/60-custom.just" | ||||||
| @@ -2,31 +2,18 @@ modules: | |||||||
|     - type: script |     - type: script | ||||||
|       scripts: |       scripts: | ||||||
|         - createautostartdir.sh |         - createautostartdir.sh | ||||||
|     - type: containerfile |  | ||||||
|       snippets: |  | ||||||
|         - RUN rpm-ostree install just powerstat |  | ||||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-udev-rules.noarch.rpm / |  | ||||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-update-services.noarch.rpm / |  | ||||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-signing.noarch.rpm / |  | ||||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-luks.noarch.rpm / |  | ||||||
|         - COPY --from=ghcr.io/ublue-os/config:latest /rpms/ublue-os-just.noarch.rpm / |  | ||||||
|         - RUN rpm -q ublue-os-udev-rules || rpm -ivh /ublue-os-udev-rules.noarch.rpm |  | ||||||
|         - RUN rpm -q ublue-os-update-services || rpm -ivh /ublue-os-update-services.noarch.rpm |  | ||||||
|         - RUN rpm -q ublue-os-signing || rpm -ivh /ublue-os-signing.noarch.rpm |  | ||||||
|         - RUN rpm -q ublue-os-luks || rpm -ivh /ublue-os-luks.noarch.rpm |  | ||||||
|         - RUN rpm -q ublue-os-just || rpm -ivh /ublue-os-just.noarch.rpm |  | ||||||
|     - type: script |     - type: script | ||||||
|       scripts: |       scripts: | ||||||
|         - installrpmfusion.sh |         - installrpmfusion.sh | ||||||
|     - from-file: common/common-packages.yml |     - from-file: common/common-packages.yml | ||||||
|     - type: justfiles |  | ||||||
|       validate: true |  | ||||||
|     - type: files |     - type: files | ||||||
|       files: |       files: | ||||||
|         - source: system/usr |         - source: system/usr | ||||||
|           destination: /usr |           destination: /usr | ||||||
|         - source: system/etc |         - source: system/etc | ||||||
|           destination: /etc |           destination: /etc | ||||||
|  |     - type: justfiles | ||||||
|  |       validate: true | ||||||
|     - from-file: common/common-scripts.yml |     - from-file: common/common-scripts.yml | ||||||
|     - type: script |     - type: script | ||||||
|       scripts: |       scripts: | ||||||
|   | |||||||
| @@ -7,5 +7,4 @@ scripts: | |||||||
|   - createmissingdirectories.sh |   - createmissingdirectories.sh | ||||||
|   - removesuid.sh |   - removesuid.sh | ||||||
|   - disablegeoclue.sh |   - disablegeoclue.sh | ||||||
|   - hardencontainerpolicy.sh |  | ||||||
|   - enablesecurebluefirstrun.sh |   - enablesecurebluefirstrun.sh | ||||||
|   | |||||||
| @@ -8,4 +8,3 @@ scripts: | |||||||
|   - disablemodemmanager.sh |   - disablemodemmanager.sh | ||||||
|   - disablenfsdaemons.sh |   - disablenfsdaemons.sh | ||||||
|   - disablesssd.sh |   - disablesssd.sh | ||||||
|   - justfilehardening.sh |  | ||||||
		Reference in New Issue
	
	Block a user
	 RoyalOughtness
					RoyalOughtness