diff --git a/gpgtool b/gpgtool index 3ae825e..1e30589 100755 --- a/gpgtool +++ b/gpgtool @@ -1,18 +1,142 @@ -#!/bin/bash +#!/usr/bin/env zsh +_dependencies=("echo" "gpg" "ln" "ls" "mktemp" "mkdir" "mv" "rm" "udisksctl") +_tempdir=/tmp/gpgtool.tempdir -######################## -# mount -# open -# extend -# close -# unmount -######################## +# Sets up GPGtool. Creates temporary GNUPG home directory, mounts key device if +# given, checks for key directory. +init () { + local dev + local mount + local opts + local keypath -( [[ $# -eq 2 ]] || [[ $1 -eq create ]] || [[ $@ -eq "list" ]] || [[ $@ -eq "unmount" ]] ) || exit 2 + # Check if already initialized: + if [[ -f "${_tempdir}" ]]; then + local dir="$(cat ${_tempdir})" + echo "GPGtool already initialized at ${dir}." + if [[ -f "${dir}/env" ]]; then + source "${dir}/env" + [[ ! -z "${dev}" ]] && echo -e "\tdevice: ${dev}" + [[ ! -z "${mountdev}" ]] && echo -e "\tmapped device: ${mountdev}" + [[ ! -z "${keypath}" ]] && echo -e "\tkey path: ${keypath}" + fi + exit 1 + fi -_dir=/run/media/daniel/keysafe -_dev=/dev/disk/by-label/keysafe -_pkdir=~/.gnupg/private-keys-v1.d + zparseopts -A opts -D -E -- d: p: -device: -path: + for opt in "${(@k)opts}"; do + case $opt in + -d|--device) + dev=$opts[$opt]; + ;; + -p|--path) + keypath=$opts[$opt]; + ;; + esac + done + + # If no device given, check for ENV: + [[ -z "${dev}" ]] && dev=${GPGTOOLKEYDEV} + + # If no path given, check for ENV: + [[ -z "${keypath}" ]] && keypath=${GPGTOOLKEYPATH} + + # Unlock device: + if [[ ! -z "${dev}" ]] && udisksctl info -b ${dev} | grep -q org.freedesktop.UDisks2.Encrypted; then + echo "Unlocking device ${dev} …" + local mountdev=$(udisksctl unlock -b "${dev}") + [[ $? != 0 ]] && echo "Error unlocking device ${dev}." && exit 1 + + mountdev="$(echo $mountdev | awk '{ print $4 }')" + mountdev=${mountdev:0:-1} + fi + + # Mount device: + [[ -z ${mountdev} ]] && mountdev=${dev} + if [[ ! -z ${mountdev} ]]; then + echo "Mounting device ${mountdev} …" + mountpath=$(udisksctl mount -b "${mountdev}") + [[ $? != 0 ]] && echo "Error mounting device ${mount}." && exit 1 + + mountpath="$(echo $mountpath | awk '{ print $4 }')" + fi + + # Finalize path: + [[ ! -z "${mountpath}" ]] && keypath=${mountpath}/${keypath} + + # Check if keypath actually exists: + [[ ! -d "${keypath}" ]] && echo "Key path ${keypath} is not a directory, aborting …" && exit 64 + + # Create temporary working directory: + local tempdir=$(mktemp -d --tmpdir) + mkdir ${tempdir}/gpghome + + # Save state: + cat > ${tempdir}/env << EOF +dev="${dev}" +mountdev="${mountdev}" +keypath="${keypath}" +EOF + echo -n "${tempdir}" > /tmp/gpgtool.tempdir + + echo "GPGtool initialized. Temporary working directory: ${tempdir}, key path ${keypath}." +} + +# Cleans up GPGtool. Clears the temp directory and closes the mounted volume. +clear () { + # Abort if not currently initialized: + [[ ! -f "${_tempdir}" ]] && echo "GPGtool not currently initialized, aborting …" && exit 1 + + local tempdir="$(cat /tmp/gpgtool.tempdir)" + + # Unmount device: + source "${tempdir}/env" + if [[ ! -z "${mountdev}" ]]; then + echo "Unmounting ${mountdev} …" + udisksctl unmount -b "${mountdev}" + fi + # Lock device: + if [[ "${dev}" != "${mountdev}" ]]; then + echo "Locking ${dev} …" + udisksctl lock -b "${dev}" + fi + + # Remove temporary working directory: + echo "Removing temporary working directory ${tempdir} …" + rm -rf "${tempdir}" + rm -f "${_tempdir}" +} + +# Prints usage information. +usage () { + echo FIXXME +} + +# Abort for missing dependencies: +for dep in ${_dependencies}; do + if ! command -v ${dep} >/dev/null 2>&1; then + [[ -z "${deps}" ]] && deps=${dep} || deps="${deps}, ${dep}" + fi +done +[[ ! -z "${deps}" ]] && echo "Missing dependencies: ${deps}." && exit 1 + +# Abort for no arguments: +[[ $# == 0 ]] && usage && exit 64 + +# Handle -h / --help / help and exit: +[[ "$1" =~ "(-h|--help|help)" ]] && usage && exit 0 + +# Source config file: +for dir in "$(dirname $0)" "${HOME}/.config/gpgtool" "${XDG_CONFIG_HOME}"; do + [[ -f "${dir}/gpgtool.conf" ]] && source "${dir}/gpgtool.conf" +done + +# Handle Subcommands: +[[ "$(type -w $1)" =~ "(.+\s+)?function" ]] \ + && $@ \ + || echo "Invalid command: $1. See \`$0 --help\`." >&2 && exit 64 + +#================================================== # gpgtools mount device mount () { @@ -25,7 +149,7 @@ unmount () { dev=${1} udisksctl unmount -b ${_dev} udisksctl lock -b ${dev} - sync ${dev} + sudo sync ${dev} } # gpgtools open keyid [keyid …] @@ -121,5 +245,3 @@ list () { ls -l ${_pkdir} | grep ^l | awk {'print $NF'} fi } - -$@