-
Notifications
You must be signed in to change notification settings - Fork 1
/
get2fa
executable file
·137 lines (117 loc) · 2.88 KB
/
get2fa
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/bash
#
# Return a 2fa token, without re-use.
#
# Requires oath-toolkit homebrew package
#
# Optional configuration environment variables - $DIR_2FA (default is ~)
#
# Optional positional command line argument is name of file to load from $DIR_2FA/
# (default is .secret_2fa)
# (unless script is invoked with argv[0]!="get2fa" in which case filename is "${DIR_2fa}/.${basename"}
#
# if passed with "-r" argument will restore to the clipboard the value from the previous invocation
#
#
# Default is TOTP but if "#HOTP:TRUE" exists on a line in the file, HOTP will be used instead
set -o nounset
#set -o verbose
#set -o pipefail
#set -o errexit
if [ ! "${DIR_2FA:-}" ]
then
DIR_2FA=~
fi
CLIPBOARD_BACKUP=$DIR_2FA/".2fa-clipboard.txt"
if [ "${1:-}" = "-r" ]
then
if [ -e "$CLIPBOARD_BACKUP" ]
then
# restore clipboard
pbcopy < "$CLIPBOARD_BACKUP"
echo "Clipboard restored"
exit 0
else
echo "No clipboard file ($CLIPBOARD_BACKUP)"
exit 2
fi
fi
basename=$(basename "$0")
if [ "${1:-}" ]
then
KEYFILE="$DIR_2FA/${1:-}"
elif [ "$basename" != "get2fa" ]
then
#
#
# DO WEIRD substitutions so symlinked executable names can be a wide range of things that will still map to a sane name for the
# key file - "aws devops" or "beyondid 2fa" or "aws-swe" or "gsuite" or many others
#
basename=$(echo "$basename" | sed 's/ 2fa//' | sed 's/2fa //' | sed 's/ /-/g')
KEYFILE="$DIR_2FA/.$basename"
else
KEYFILE="$DIR_2FA/.secret_2fa"
fi
echo "basename: $basename">&2
echo "KEYFILE: $KEYFILE">&2
if [ ! -e "$KEYFILE" ]
then
echo "File not found: $KEYFILE"
exit 3
fi
if file --brief "$KEYFILE" | grep -q PGP
then
SECRET_2FA="$(gpg --decrypt < "$KEYFILE" | grep -v ^\# | tr -d \ )"
else
SECRET_2FA="$(grep -v ^\# "$KEYFILE" | tr -d \ )"
fi
echo "basename: $basename">&2
echo "KEYFILE: $KEYFILE">&2
LAST_ENTRY_FILE=~/".2fa-last-${1:-}.txt"
LAST_COUNTER_FILE=$DIR_2FA/".2fa-counter-${1:-}.txt"
HOTP=""
if grep -qx \#HOTP:TRUE "$KEYFILE"
then
HOTP="true"
fi
if [ -e "$LAST_ENTRY_FILE" ]
then
last_entry=$(cat $LAST_ENTRY_FILE)
echo "Found last entry:">&2
echo "$last_entry">&2
else
last_entry=""
fi
if [ -e "$LAST_COUNTER_FILE" ]
then
last_counter=$(cat $LAST_COUNTER_FILE)
echo "Found last counter:">&2
echo "$last_counter">&2
else
last_counter="-1"
fi
new_counter=$last_counter
new_entry=""
echo -n "Generating new 2fa password">&2
while [[ "$new_entry" == "$last_entry" || ! "$new_entry" ]]
do
new_counter=$(expr $new_counter + 1)
echo -n ".">&2
if [ ! -z "$HOTP" ]
then
new_entry=$(oathtool --hotp -b $SECRET_2FA -c $new_counter)
else
new_entry=$(oathtool --totp -b $SECRET_2FA)
fi
done
echo>&2
if which pbpaste > /dev/null 2>&1
then
pbpaste > "$CLIPBOARD_BACKUP"
echo $new_entry | pbcopy
fi
echo $new_entry
touch "$LAST_ENTRY_FILE"
touch "$LAST_COUNTER_FILE"
echo "$new_entry" > "$LAST_ENTRY_FILE"
echo "$new_counter" > "$LAST_COUNTER_FILE"