Files
pass/pass
2026-03-28 05:39:40 +00:00

94 lines
2.5 KiB
Bash
Executable File

#!/bin/sh
# posix password manager - developed by acidvegas (https://github.com/acidvegas/pass)
umask 077
export GPG_TTY=$(tty)
GPG_ID="acidvegas" # change me
GPG_OPTS="-q --yes --compress-algo=none --no-encrypt-to --batch"
PASS_DIR=$HOME/.secrets
if [ -z $EDITOR ]; then
export EDITOR=nano
fi
mkdir -p $PASS_DIR
edit() {
template="pw.XXXXXXXXXXXXX"
if [ -d /dev/shm ] && [ -w /dev/shm ] && [ -x /dev/shm ]; then
tmp=$(mktemp /dev/shm/$template)
elif [ ! -z $PREFIX ] && [ -d $PREFIX/tmp ]; then
tmp=$(mktemp $PREFIX/usr/tmp/$template) # For users on Termux
else
echo "warning: /dev/shm does not exist or is missing permissions required for temporary files (using insecure fallback to /tmp directory)"
tmp=$(mktemp /tmp/$template)
fi
rm_tmp() {
rm -rf "$tmp"
}
trap rm_tmp EXIT
if [ -f $PASS_DIR/$1.gpg ]; then
gpg -d -o $tmp $GPG_OPTS $PASS_DIR/$1.gpg || exit 1
$EDITOR $tmp
if [ ! "$(gpg -d $GPG_OPTS $PASS_DIR/$1.gpg)" = "$(cat $tmp)" ]; then
gpg -e -r $GPG_ID -o $PASS_DIR/$1.gpg $GPG_OPTS $tmp
fi
else
$EDITOR $tmp
if [ -f $tmp ]; then
mkdir -p $(dirname $PASS_DIR/$1)
gpg -e -r $GPG_ID -o $PASS_DIR/$1.gpg $GPG_OPTS $tmp
fi
fi
}
generate() {
case ${1#[-+]} in
*[!0-9]* | '') echo "error: invalid number" ;;
*) cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $1 | head -n 1 ;;
esac
}
otp() {
if [ -f $PASS_DIR/$1.gpg ]; then
otp_uri=$(gpg -d $GPG_OPTS $PASS_DIR/$1.gpg | tail -n 1) || exit 1
if [ "$(echo $otp_uri | head -c 10)" = "otpauth://" ]; then
secret=$(echo "$otp_uri" | sed 's/.*secret=//' | cut -f1 -d'&')
oathtool -b --totp $secret
else
echo "error: OTP URI invalid or not found for '$1'"
fi
else
echo "error: '$1' does not exist"
fi
}
show() {
if [ -d $PASS_DIR/$1 ]; then
echo $1
tree -NCl --noreport $PASS_DIR/$1 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
elif [ -f $PASS_DIR/$1.gpg ]; then
gpg -d $GPG_OPTS $PASS_DIR/$1.gpg
else
echo "error: '$1' does not exist"
fi
}
# Main
command -v gpg >/dev/null || { echo "error: missing required package 'gpg'"; exit 1; }
command -v tree >/dev/null || { echo "error: missing required package 'tree'"; exit 1; }
if [ "$#" = '1' ]; then
show $1
elif [ "$#" = '2' ]; then
if [ "$1" = 'edit' ]; then
edit $2
elif [ "$1" = 'gen' ]; then
generate $2
elif [ "$1" = 'otp' ]; then
command -v oathtool >/dev/null || { echo "error: missing required package 'oathtool'"; exit 1; }
otp $2
fi
else
tree -NCl --noreport $PASS_DIR 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
fi