initial commit
[askpass.sh.git] / askpass.sh
1 #!/bin/bash
2
3 # askpass.sh by Felix Kästner, GPL3
4
5
6 # in $* there could be the prompt-message (from an invoking program like sudo)
7 # delete any trailing space or colon and write it to stderr
8 promptmsg="enter password:"
9 [ "$*" != "" ] && promptmsg="${*% }"
10 echo -en "$0: ${promptmsg%:}: " >&2
11
12 pw=""
13 stars=0
14 cx='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' # chars that can be echoed as feedback for a keypress, there have been problems when using special chars
15
16 while :
17 do
18     # set IFS to newline and read a character
19     # -s silent, -r \ is taken literal, not as escape character, -n 1 only one char is read
20     IFS=$'\n' read -s -r -n 1 char
21     case "$char" in
22         "\7f")
23             # backspace was pressed
24             # deletes the last character from $pw and moves the cursor one char back, deleting this char, but don't delete more chars than available
25             pw="${pw%?}"
26             [ $stars -gt 0 ] && { ((stars--)); echo -en "\b \b" >&2; }
27         ;;
28         "\ 4")
29             # ctrl + d was pressed, this means abort/cancel
30             # delete all echoed characters, unset variables and exit
31             while [ $((stars--)) -gt 0 ]
32             do
33                 echo -en "\b \b" >&2
34             done
35             
36             unset pw char stars rnd cx
37             echo "cancelled " >&2
38             exit 1
39         ;;
40         ?)
41             # add the char to pw and echo some chars as visual feedback
42             pw="$pw$char"
43             ((rnd = RANDOM % 3 + 1)) # bash specific
44             ((stars += rnd))
45             # echos $rnd much of the characters from $cx
46             while [ $((rnd--)) -gt 0 ]
47             do
48                 echo -n "${cx:$(($RANDOM % ${#cx})):1}" >&2
49             done
50         ;;
51         "")
52             # no new character, so pw is completed
53             # delete the echoed characters
54             remain=$(($RANDOM % 4 + 6))
55             while [ $((stars--)) -gt $remain ]
56             do
57                 echo -en "\b \b" >&2
58             done
59             break
60         ;;
61     esac
62 done
63
64 # write a newline to stderr and the password to stdout
65 echo "" >&2
66 echo "$pw"
67 unset pw char stars rnd cx remain
68