dotfiles/.local/bin/vault-toggle

101 lines
2 KiB
Shell
Executable file

#!/bin/sh
# Mount or unmount the `gocryptfs` ~/Vault synced via the ~/Cloud
#
# Triggered by <Super><Control>v
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
#
# The password is taken from the secret service (e.g., GNOME Keyring)
# and, if not stored there, asked for with a GUI prompt
#
# Store the password once with:
# secret-tool store --label='gocryptfs ~/Vault' gocryptfs vault
#
# Requires:
# - gocryptfs
# - libnotify-bin
# - libsecret-tools
# - zenity
set -eu
CIPHER_DIR="$HOME/Cloud/Misc/Vault.enc"
MOUNT_POINT="$HOME/Vault"
_command_exists() {
command -v "$1" 1>/dev/null 2>&1
}
_notify() {
_command_exists notify-send || return 0
notify-send 'Vault' "$1"
}
# Print the password to stdout,
# instead of storing it in a variable
_password() {
if _command_exists secret-tool \
&& secret-tool lookup gocryptfs vault 2>/dev/null; then
return 0
fi
zenity --password --title='Unlock the Vault' 2>/dev/null
}
_unmount() {
if _command_exists fusermount3; then
fusermount3 -u "$MOUNT_POINT"
else
fusermount -u "$MOUNT_POINT"
fi
}
# Unmount if mounted
if mountpoint -q "$MOUNT_POINT"; then
if _unmount 2>/dev/null; then
_notify 'Locked'
exit 0
fi
# Most likely a shell or an app still has a file open inside
_notify 'Still in use => Close all files and shells inside first'
exit 1
fi
# Mount otherwise
if [ ! -f "$CIPHER_DIR/gocryptfs.conf" ]; then
_notify "No vault found at $CIPHER_DIR"
exit 1
fi
# Nextcloud does not sync mode bits
# => Enforce owner-only access on every client,
# which `gocryptfs` also shows as the mode of the mount point
chmod 700 "$CIPHER_DIR"
mkdir -p "$MOUNT_POINT"
# `gocryptfs` reads the password from stdin if that is not a terminal
if _password | gocryptfs -idle 1h -quiet -sharedstorage "$CIPHER_DIR" "$MOUNT_POINT"; then
_notify 'Unlocked'
else
_notify 'Not unlocked (wrong or no password?)'
exit 1
fi