-
Notifications
You must be signed in to change notification settings - Fork 1
/
pass
executable file
Β·136 lines (127 loc) Β· 3.96 KB
/
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/sh
# posix password manager - developed by acidvegas (https://git.acid.vegas/pass)
umask 077
export GPG_TTY=$(tty)
GPG_ID="acidvegas" # change me
GPG_OPTS="-q --yes --compress-algo=none --no-encrypt-to --batch"
METHOD="type"
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
}
menu() {
cwd=$PASS_DIR
while :
do
if [ $cwd = $PASS_DIR ]; then
cmd=$(ls -p $cwd | sed 's/\.gpg$//' | dmenu -l 5 "$@")
else
cmd=$({ echo ".."; ls -p $cwd | sed 's/\.gpg$//'; } | dmenu -l 5 "$@")
fi
if [ -z $cmd ]; then
break
elif [ $cmd = '..' ]; then
cwd=$(dirname $cwd)
elif [ -d $cwd/$cmd ]; then
cwd=$cwd/$cmd
elif [ -f $cwd/$cmd ]; then
if [ $METHOD = "copy" ]; then
export PINENTRY_USER_DATA="dmenu" | gpg -d $GPG_OPTS $cwd/$cmd | dmenu "$@" | xclip -selection clipboard
sleep 3 && xclip -selection clipboard /dev/nul
elif [ $METHOD = "type" ]; then
export PINENTRY_USER_DATA="dmenu" | gpg -d $GPG_OPTS $cwd/$cmd | dmenu "$@" | xdotool type --delay 3 "$D"
fi
break
fi
done
}
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
if [ $1 = 'menu' ]; then
command -v dmenu >/dev/null || { echo "error: missing required package 'dmenu'"; exit 1; }
command -v pinentry >/dev/null || { echo "error: missing required package 'pinentry'"; exit 1; }
command -v pinentry-dmenu >/dev/null || { echo "error: missing required package 'pinentry-dmenu'"; exit 1; }
if [ $METHOD = "copy" ]; then
command -v dmenu >/dev/null || { echo "error: missing required package 'xclip'"; exit 1; }
elif [ $METHOD = 'type' ]; then
command -v xdotool >/dev/null || { echo "error: missing required package 'xdotool'"; exit 1; }
else
echo "error: invalid menu method (must be 'copy' or 'type')"
exit 1
fi
menu
else
show $1
fi
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