chore(gnupg): add script to manage GPG master key from USB drive

This commit is contained in:
Yorick Barbanneau 2025-04-07 00:32:56 +02:00
parent e376634d06
commit 031be01d70
2 changed files with 139 additions and 0 deletions

View file

@ -51,5 +51,7 @@ in
programs.password-store = { programs.password-store = {
enable = cfg.pass; enable = cfg.pass;
}; };
home.file.".local/bin/gpg-attach-key".source = ./files/gpg-attach-key.sh;
}; };
} }

View file

@ -0,0 +1,137 @@
#!/usr/bin/env bash
UUID="1429a4c6-78f5-4f46-98bc-894106b52399"
mountpoint=""
usage() {
cat <<EOF >&2
Attach GPG master key
---
$0 [action] [--debug] [--help]
mount or unmount encrypted device based on UUID and attach GnuPG private keys
to private key directory. Actions can be
- 'mount' to mount USB device and attach keys
- 'unmount' to remove private keys attached and unmount USB device
EOF
}
error() {
local message
printf -v message "\e[31mERROR:\e[0m %s\n" "$1"
>&2 printf "%b" "${message}"
show_stack_trace
}
show_stack_trace() {
if [[ $DEBUG -eq 1 ]]; then
local message
message="└─ \e[1mStack trace\e[0m:\n"
for ((i = 2; i < ${#FUNCNAME[@]} - 1; i++)); do
if [[ $i = $((${#FUNCNAME[@]} - 2)) ]]; then
message="${message}"
else
message="${message}"
fi
message="${message}─ source:\e[3;34m${BASH_SOURCE[$i]}\e[0m"
message="${message} function:\e[3;34m${FUNCNAME[$i]}\e[0m"
message="${message} line:\e[3;34m${BASH_LINENO[$i - 1]}\e[0m\n"
done
>&2 printf "%b" "${message}"
fi
}
debug() {
local message
if [[ $DEBUG -eq 1 ]]; then
printf -v message "\e[3;34mDEBUG:\e[0m %s\n" "$*"
>&2 printf "%b" "$message"
show_stack_trace
fi
}
# shellcheck disable=SC2317
process_args() {
while :; do
case $1 in
-h | --help)
usage
exit 0
;;
m | mount)
action="mount"
;;
u | umount | unmount)
action="unmount"
;;
-d | --debug)
DEBUG=1
;;
*)
break
;;
esac
shift
done
}
main() {
if [ ! -L "/dev/disk/by-uuid/${UUID}" ]; then
error "disk with UUID ${UUID} not found"
exit 10
fi
if [ -z "${GNUPGHOME}" ]; then
error "GNUPGHOME env variable not set, can't determine gnuph home directory"
exit 11
fi
key_destination="${GNUPGHOME}/private-keys-v1.d"
case "$action" in
"mount")
debug "Mount encryted key"
if ! udisksctl unlock -b /dev/disk/by-uuid/${UUID}; then
error "Unlock disk ${UUID} failed"
exit 10
fi
mountpoint=$(udisksctl mount -b /dev/mapper/luks-${UUID} | awk '{print $4}')
while read -r key_file; do
debug "Create symlink for ${key_file}"
base=$(basename "$key_file")
#create symlink to key file if not exist
if [ ! -e "${key_destination}/${base}" ]; then
ln -s "$key_file" "${key_destination}/${base}"
fi
done < <(find "${mountpoint%.}/.gpg_master/" -type f -name "*.key")
;;
"unmount")
debug "unmount encrypted key"
while read -r key_file; do
debug "Remove key \`${key_file}\`"
rm "$key_file"
done < <(find "${key_destination}" -type l -name "*.key")
if ! udisksctl unmount -b /dev/mapper/luks-${UUID} 2 &>/dev/null; then
error "Can't unmount volume \`luks-${UUID}\`"
fi
if ! udisksctl lock -b /dev/disk/by-uuid/${UUID} 2 &>/dev/null; then
error "Can't lock device \`${UUID}\`"
fi
;;
*)
error "What do you want, mount or unmount:"
usage
exit 1
;;
esac
}
process_args "$@"
main
exit 0