dotfiles/bin/factotum

112 lines
2.4 KiB
Plaintext
Raw Permalink Normal View History

2024-06-23 19:39:49 +02:00
#!/bin/bash -pe
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright 2024, Gerrit-John Los <los@lugons.org>
prog="${0##*/}"
default_timeout=5s
secstore=~/opt/etc/"$prog"
cd "$secstore"
show_usage() {
cat <<-EOT 1>&2
usage: $prog [-q|-e|-r|-l] [-C] [-t TIMEOUT] SECLABEL
$prog {h|-l}
-h: show this help
-l: list configured SECLABELs
-q: query SECLABEL
-e: add or edit a SECLABEL
-r: remove SECLABEL
-C: work around a chrome bug for query mode
-t: set timeout for xclip (default: $default_timeout)
EOT
}
show_help() {
show_usage
cat <<-EOT 1>&2
A SECLABEL is an encrypted file containing lines with credential
data, with an optional leading tag. The first empty tag is assumed to
be 'user', the second 'password'.
In query mode (the default) credentials are placed in turn into a one-time
paste buffer while the tag is shown on stdout. If the data isn't pasted
within the timeout '$prog' aborts.
To abort editing a SECLABEL exit the editor with the tmpfile empty.
Chrome has trouble to count to one, and reads the cut-buffer twice to
get at its content. Use '-C' to enable a workaround for this broken
behaviour.
EOT
}
usage() { show_usage ; exit 1 ; }
timeout=$default_timeout
list=false
mode=''
workaround=''
while getopts "hlaert:C" opt ;do
case "$opt" in
h) show_help ;;
l) list=true ;;
q) mode=query ;;
a|e) mode=edit ;;
r) mode=remove ;;
t) timeout="$OPTARG" ;;
C) workaround=chrome ;;
--) break ;;
*) usage ;;
esac
done
shift $((OPTIND-1))
if $list ;then
ls "${secstore}"
if [ -z "$mode" -a $# -eq 0 ] ;then
exit 0
fi
fi
[ -n "$mode" ] || mode=query
[ $# -eq 1 ] || usage
SECLABEL="$1"
[[ "$SECLABEL" != */* ]] || usage
case "$mode" in
edit)
passfile="${secstore}/$SECLABEL"
trap "rm -f '${passfile}.tmp' || true" EXIT
[ ! -e "${passfile}" ] || cp "${passfile}" "${passfile}.tmp"
vi "${passfile}.tmp"
if [ -s "${passfile}.tmp" ] ;then
mcrypt "${passfile}.tmp" ||
mcrypt "${passfile}.tmp" &&
mv "${passfile}.tmp.nc" "${passfile}"
fi
;;
query)
: <"$secstore/$SECLABEL"
case "$workaround" in
chrome) xclip_opts=(-C -t "$timeout") ;;
*) xclip_opts=(-t "$timeout") ;;
esac
echo -n "$1: "
{
mcrypt -q -d <"$secstore/$1" ||
mcrypt -q -d <"$secstore/$1"
} |xclip-credentials "${xclip_opts[@]}"
;;
remove)
rm -v "$secstore/$SECLABEL"
;;
*)
echo "${0##/}: $mode: not implemented yet" 1>&2
exit 1
;;
esac