reliant-system/tools/reliant-mount

115 lines
3.6 KiB
Bash
Executable file

#!/usr/bin/sh
set -e
. /usr/local/share/scripts/reliant-common.sh
reliant_print_help() {
echo "usage: $0"
echo
echo "Opens the main Shufflecake device and mounts all volumes under /run."
}
# Must be run inside verified initramfs
if [ -z "$RELIANT_INITRAMFS" ] || [ "$RELIANT_INITRAMFS" -ne "$RELIANT_TRUE" ]; then
reliant_fail "$0 can only be used inside the early boot environment"
fi
if [ -z "$RELIANT_SECURE" ] || [ "$RELIANT_SECURE" -ne "$RELIANT_TRUE" ]; then
reliant_fail "running $0 within an unverified environment is forbidden"
fi
# No more variable checks needed
set -u
# Load the Shufflecake kernel module
modprobe dm-sflc
# Prompt the user for their password
while true; do
if plymouth ask-for-password --prompt="Auxillary password" | shufflecake open "$RELIANT_SECURE_DEVICE" &>/dev/null; then
plymouth display-message --text="Success"
break
else
plymouth display-message --text="Invalid password"
sleep 2
plymouth hide-message --text="Invalid password"
fi
done
# Check for the displayed volume limit in commandline arguments
# This is useful when booting in public to hide deniable qubes from the menu
dvl_required=$RELIANT_FALSE
for argument in $(cat /proc/cmdline); do
if [[ "$argument" == reliant.dvl=* ]]; then
dvl_id="${argument##*=}"
dvl_required=$RELIANT_TRUE
fi
done
# Set the displayed volume limit
if [ $dvl_required -eq $RELIANT_TRUE ]; then
dvl_device="/dev/mapper/sflc_0_$dvl_id"
# Notify the user so they know the limit has been detected
if [ -b "$dvl_device" ]; then
plymouth display-message --text="Displayed volumes limited"
sleep 1
plymouth hide-message --text="Displayed volumes limited"
else
while true; do
dvl_id=$(plymouth ask-question --prompt="Displayed volume limit is invalid. Provide a new one")
dvl_device="/dev/mapper/sflc_0_$dvl_id"
# Validate user input
if [ -b "$dvl_device" ]; then
plymouth display-message --text="Limit adjusted successfully"
sleep 1
plymouth hide-message --text="Limit adjusted successfully"
break
fi
done
fi
fi
# Create the volume root directory under /run
mkdir -m 750 /run/shufflecake
# Check if e2fsck has been enabled
if grep -q reliant.e2fsck /proc/cmdline; then
reliant_e2fsck=$RELIANT_TRUE
else
reliant_e2fsck=$RELIANT_FALSE
fi
# Mount each volume
find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | sort | while read -r device; do
# IMPORTANT: Seal it
blockdev --setro "$device" || exit 1
# Determine the name and mountpoint
name="${device##*/}"
mountpoint="/run/shufflecake/$name"
# Mount in /run/shufflecake
mkdir -m 750 "$mountpoint"
if ! mount -o ro,noatime,nodiratime "$device" "$mountpoint" &>/dev/null && [ $reliant_e2fsck -eq $RELIANT_TRUE ]; then
# If e2fsck is enabled, we get a second chance
# However, the device MUST be temporarily made writeable to fix the filesystem
blockdev --setrw "$device" &>/dev/null || true
e2fsck -p "$device" &>/dev/null || true
# Now do the standard readonly mount
blockdev --setro "$device" &>/dev/null || true
mount -o ro,noatime,nodiratime "$device" "$mountpoint" &>/dev/null || true
fi
# Apply the displayed volume limit if required
if [ $dvl_required -eq $RELIANT_TRUE ] && [ "$device" = "$dvl_device" ]; then
break
fi
done
# Set up the volatile image pool
mkdir -m 750 /run/volatile
mkdir -m 750 /run/volatile/appvms
for path in '/sysroot/var/lib/qubes/appvms/'*; do
name="${path##*/}"
mkdir -m 750 "/run/volatile/appvms/$name"
done