Add sekrit

This commit is contained in:
Lucas 2019-12-04 10:52:17 +00:00
parent 024b065d3b
commit 63edc5f58d
3 changed files with 310 additions and 1 deletions

View File

@ -14,7 +14,8 @@
PREFIX= $(HOME)
BIN= ZZZ browser credentials fetch imgresize invidious rfcopen screenshot \
tor-browser w3m-copy-link xsekrit
sekrit tor-browser w3m-copy-link xsekrit
MAN1= sekrit.1
all: $(BIN)
@ -25,6 +26,9 @@ install: all
mkdir -p $(PREFIX)/bin
cp -f $(BIN) $(PREFIX)/bin
cd $(PREFIX)/bin && chmod 555 $(BIN)
mkdir -p $(PREFIX)/share/man/man1
cp -f $(MAN1) $(PREFIX)/share/man/man1
cd $(PREFIX)/share/man/man1 && chmod 444 $(MAN1)
uninstall:
cd $(PREFIX)/bin && rm -f $(BIN)

138
bin/sekrit.1 Normal file
View File

@ -0,0 +1,138 @@
.\"
.\" sekrit.1
.\" Written in 2018 by Lucas
.\" CC0 1.0 Universal/Public domain - No rights reserved
.\"
.\" To the extent possible under law, the author(s) have dedicated all
.\" copyright and related and neighboring rights to this software to the
.\" public domain worldwide. This software is distributed without any
.\" warranty. You should have received a copy of the CC0 Public Domain
.\" Dedication along with this software. If not, see
.\" <http://creativecommons.org/publicdomain/zero/1.0/>.
.\"
.Dd September 25, 2018
.Dt SEKRIT 1
.Os
.Sh NAME
.Nm sekrit
.Nd Secret files manager
.Sh SYNOPSIS
.Nm sekrit
.Cm add
.Ar key
.Op Ar value ...
.Nm sekrit
.Cm gen
.Op Fl l Ar length
.Op Ar chars
.Nm sekrit
.Cm get
.Ar key
.Nm sekrit
.Cm has
.Ar key
.Nm sekrit
.Cm ls
.Op Ar keys ...
.Sh DESCRIPTION
.Nm
is a small shell script for managing encrypted files.
It leverages
.Xr gpg2 1
to create and read encrypted files,
and can generate random data to populate them.
.Pp
Because of this,
.Nm
can be used as an account credentials manager,
or as a general-purpose key-value store of encrypted information.
.Bl -tag -width Ds
.It Nm Cm add Ar key Op Ar value ...
Adds a value to
.Ar key .
.Ar value
is inserted as is, without any extra modifications.
If no
.Ar value
is specified on command line,
.Cm add
will read the value from standard input.
.Cm add
will fail if
.Ar key
already has a value.
.It Nm Cm gen Oo Fl l Ar length Oc Op Ar chars
Outputs a randomly generated sequence.
The generated sequence consist of characters
.Ar chars .
Defaults to
.Ar +/0-9A-Za-z .
If
.Fl l Ar length
is provided, the randomly generated sequence will be
.Ar length
characters long.
Defaults to 43.
.It Nm Cm get Ar key
Decrypts the value associated with
.Ar key
and prints it to standard output.
Fails if
.Ar key
doesn't have a value associated with it.
.It Nm Cm has Ar key
Returns success if
.Ar key
has a value associated with it.
Fails otherwise.
.It Nm Cm ls Op Ar keys ...
For each
.Ar key
given as argument,
list all the registered keys under that hierarchy.
If no
.Ar key
is given, list all the registeres keys.
.El
.Sh ENVIRONMENT
.Bl -tag -width SEKRIT_GPG_ID
.It Ev SEKRIT_DIR
Secret files base directory.
Defaults to
.Pa ~/keep/sekrit .
.It Ev SEKRIT_GPG_ID
The recipient to whom encrypt the files.
Defaults to
.Ar myself .
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
To use
.Nm
as an account credentials manager, you can run
.Bd -literal -offset indent
sekrit add accounts/example.com/user myuser
sekrit gen accounts/example.com/pass
.Ed
.Pp
Then, to retrieve credentials to login as
.Ar myuser
in
.Ar example.com
you can run
.Bd -literal -offset indent
sekrit get accounts/example.com/user | xclip -l 1 -sel clip -q
sekrit get accounts/example.com/pass | xclip -l 1 -sel clip -q
.Ed
.Sh AUTHORS
.An Lucas
.Sh LICENSE
.Nm
is in the public domain.
.Pp
To the extent possible under law, the author(s) have dedicated all
copyright and related and neighboring rights to this software to the
public domain worldwide.
.Pp
.Lk http://creativecommons.org/publicdomain/zero/1.0/

167
bin/sekrit.sh Normal file
View File

@ -0,0 +1,167 @@
#!/bin/sh
# sekrit
# Written in 2018-2019 by Lucas
# CC0 1.0 Universal/Public domain - No rights reserved
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any
# warranty. You should have received a copy of the CC0 Public Domain
# Dedication along with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.
# sekrit is a relatively small shell script for writing and reading
# encrypted files, aimed to deal mostly with accounts credentials, but
# general enough to deal with any content. It can populate each key
# with random data or with fixed data, reading either command-line
# arguments or stdin.
#
# To be used as a password manager, it's recommended to pair it with
# xclip(1). For example, for username, password and optional second
# factor:
#
# sekrit get account/user | xclip -r -l 1 -sel clip -q
# sekrit get account/pass | xclip -r -l 1 -sel clip -q
# sekrit has account/2fa && sekrit get account/2fa \
# | $program_for_totp | xclip -r -l 1 -sel clip -q
usage()
{
cat - <<. >&2
Usage:
${0##*/} add key [value ...]
${0##*/} gen [-l length] [chars]
${0##*/} get key
${0##*/} has key
${0##*/} ls [keys ...]
If no value was provided on command line, add reads from stdin.
.
exit 1
}
err()
{
printf "%s: %s\n" "${0##*/}" "$*" >&2
exit 1
}
check_key()
{
[ "$1" = "${1%/}" ] || err "Key can not end in a slash."
}
to_number()
{
printf "%u" "$*" 2>/dev/null
}
sekrit_add()
{
[ $# -eq 1 ] && [ -n "$1" ] || usage
key=$1
check_key "$key"
shift
f=$SEKRIT_DIR/$key.gpg
mkdir -p "${f%/*}"
[ -f "$f" ] && err "Key \"$key\" already exists."
if [ $# -ne 0 ]; then
printf "%s\n" "$*"
else
cat -
fi | gpg2 -qae -r "$SEKRIT_GPG_ID" >"$f"
# make it read-only
chmod -- 400 "$f"
}
sekrit_gen()
{
len=43
OPTIND=1
while getopts l: flag; do
case "$flag" in
l) len=$(to_number "$OPTARG") ||
err "Invalid password length."
;;
[?]) usage
;;
esac
done
shift $(($OPTIND - 1))
[ $# -le 1 ] || usage
chars=+/0-9A-Za-z
if [ $# -eq 1 ]; then
[ -n "$1" ] || usage
chars=$1
fi
tr -cd -- "$chars" </dev/urandom | dd bs=1 count="$len" 2>/dev/null &&
printf "\n"
}
sekrit_get()
{
[ $# -eq 1 ] || usage
key=$1
check_key "$1"
shift
f=$SEKRIT_DIR/$key.gpg
[ ! -f "$f" ] && err "No data for key \"$key\"."
gpg2 -qd "$f"
}
sekrit_has()
{
[ $# -eq 1 ] || usage
key=$1
check_key "$1"
shift
[ -f "$SEKRIT_DIR/$key.gpg" ]
}
ls_key()
{
d=$SEKRIT_DIR$1
find "$d" -type f -name "*.gpg" | sort | cut -c $((${#d} + 1))- |
sed "s/\.gpg$//"
}
sekrit_ls()
{
if [ $# -eq 0 ]; then
ls_key /
else
for key; do
printf "%s:\n" "$key"
ls_key /"$key"/ | sed "s/^/ /"
printf "\n"
done
fi
}
set -e
[ $# -ge 1 ] || usage
cmd=$1
shift
umask 077
: ${SEKRIT_DIR:=~/keep/sekrit}
: ${SEKRIT_GPG_ID:=myself}
mkdir -p "$SEKRIT_DIR"
case "$cmd" in
add) sekrit_add "$@";;
gen) sekrit_gen "$@" ;;
get) sekrit_get "$@" ;;
has) sekrit_has "$@" ;;
ls) sekrit_ls "$@" ;;
*) usage ;;
esac