112 lines
2.4 KiB
Bash
Executable file
112 lines
2.4 KiB
Bash
Executable file
#!/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
|
|
|