try install recipe
[hband-tools.git] / half-baked / cred
blobe9f3e13c71cbecc1c6031a9309572c4a43afe531
1 #!/bin/bash
3 # need to set these shell options before they are relied upon when bash parses the big { ... } block later down.
4 shopt -s nocasematch
5 shopt -s expand_aliases
6 # aliases in non-interactive bash script are not evaluated in the same scope where they are defined,
7 # but they are in the big { ... } block below.
8 alias set_site='if [ -z "${site:-}" ]; then set_site_func "${1:-}"; shift; fi;'
11 set -eE
12 set -o pipefail
13 set -u
15 . /usr/lib/tool/bash-utils
16 . /usr/lib/tool/ansi-codes
18 TAB=$'\t'
20 print_traceback()
22 local i stack_size=${#FUNCNAME[@]}
23 for (( i=1; i<stack_size; i++ )); do
24 local func="${FUNCNAME[$i]}"
25 [[ $func = "" ]] && func=MAIN
26 local linen="${BASH_LINENO[$(( i - 1 ))]}"
27 local src="${BASH_SOURCE[$i]}"
28 [[ "$src" = "" ]] && src=non_file_source
30 echo -n "$ANSI_bold$ANSI_fg_black"
31 echo " function: $func"
32 echo " file: $src (line $linen)"
33 echo -n "$ANSI_reset"
35 local line_number_text_sep='| '
36 nl -ba -w ${#linen} -s " $line_number_text_sep" "$src" | grep -C 2 -E "^\s*$linen " |\
37 prefixlines " " |\
38 sed -e "s/^\(\s*$linen\) \(.\{${#line_number_text_sep}\}\)\(.*\)/\1-\2$ANSI_italic\3$ANSI_normal/" |\
39 sd '^' "$ANSI_bold$ANSI_fg_black" | sd '$' "$ANSI_reset"
40 done
43 trap 'print_traceback >&2' ERR
45 set_site_func()
47 local param=$1
48 if [ -z "$1" ]
49 then
50 errx 1 "Enter site name or directory!"
51 elif [ -d "$param" ]
52 then
53 site=`basename "$param"`
54 else
55 site=$1
59 is_secret()
61 [[ $1 =~ password|key|cvc|secret|pin ]]
64 do_clip()
66 xclip -i -selection clipboard
70 basedir=~/cred
71 site=''
74 if [ "${1:-}" = site ]
75 then
76 shift || true
77 set_site
80 subcmd=${1:-}
81 shift || true
85 case "$subcmd" in
86 (dump)
87 set_site
88 options=("$@")
91 cd "$basedir/$site"
92 GLOBIGNORE=${GLOBIGNORE:-}${GLOBIGNORE:+:}".:..:.[!/.]*:..[!/]*:-*"
93 for file in *
95 if [ ! -f "$file" ]
96 then
97 continue
99 if is_secret "$file"
100 then
101 if in_list reveal-secrets "${options[@]}"
102 then
103 true
104 elif in_list hash-secrets "${options[@]}"
105 then
106 hash=`cat "$file" | md5sum | cut -c 1-32`
107 echo "$file$TAB$hash$TAB""hash-algo=md5"
108 continue
109 else
110 echo "$file"$'\t'"*****"
111 continue
115 grep . "$file" | prefixlines "$file"$'\t'
116 done
118 site=${site%/}
119 if [[ $site =~ / ]]
120 then
121 parent=${site%/*}
122 cred dump "$parent" "${options[@]}"
126 (password)
127 set_site
128 cat "$basedir/$site/PASSWORD"
130 (list-sites)
131 find -L "$basedir" -path "$basedir/${1:-}*" -type d -printf "%P\n"
133 (prop|clip)
134 set_site
135 prop=${1:?'enter property name!'}
136 shift
137 if [ $# = 0 ]
138 then
139 case "$subcmd" in
140 (prop)
141 if is_secret "$prop"
142 then
143 warnx "$prop is a secret."
144 warnx "enter 'cred [...] prop [...] $prop show' explicitely, or"
145 warnx "more preferably 'cred [...] prop [...] $prop clip' to copy to the clipboard!"
146 false
147 else
148 cat "$basedir/$site/$prop"
151 (clip)
152 cat "$basedir/$site/$prop" | do_clip
154 esac
155 elif [ "$subcmd" = prop ]
156 then
157 case "$1" in
158 (set)
159 shift
160 val=$*
161 mkdir -p "$basedir/$site"
162 printf '%s' "$val" > "$basedir/$site/$prop"
164 (edit)
165 mkdir -p "$basedir/$site"
166 "${EDITOR:-$VISUAL}" "$basedir/$site/$prop"
168 (del)
169 rm "$basedir/$site/$prop"
171 (show)
172 cat "$basedir/$site/$prop"
174 (clip)
175 cat "$basedir/$site/$prop" | do_clip
178 false "invalid argument"
180 esac
183 (list-props)
184 set_site
185 find "$basedir/$site" -type f -printf "%P\n"
187 (renew-password)
188 set_site
189 newpwd=$(pwgen -y 8 1)$(pwgen -y 8 1)
190 [ -n "$newpwd" ]
191 pwdfile=$basedir/$site/PASSWORD
192 mkdir -p "$basedir/$site"
193 if [ -s "$pwdfile" ]
194 then
195 cur_pwd=`cat "$pwdfile"`
196 atime=`stat -c %x "$pwdfile"`
197 now=`date +'%F %T.%N %z'`
198 echo "$atime $now $cur_pwd" >> "$basedir/$site/OLDPASSWORDS"
200 printf '%s' "$newpwd" > "$pwdfile"
202 (compscript)
203 cat <<'EOF'
204 _autocomplete_cred() {
205 local compreply
206 local curr_word=${COMP_WORDS[$COMP_CWORD]}
207 local prev_word=${COMP_WORDS[$[COMP_CWORD - 1]]}
208 local site_subcmds="list-sites dump renew-password list-props prop clip"
210 case $COMP_CWORD in
212 compreply="compscript site $site_subcmds"
215 local site=$curr_word; site=${site/#'~/'/$HOME/}
216 compreply=`cred list-sites "$site"`
219 local subcmd=${COMP_WORDS[1]}
220 local site=${COMP_WORDS[2]}; site=${site/#'~/'/$HOME/}
221 local cword_idx=$COMP_CWORD
222 if [ "$subcmd" = site ]
223 then
224 if [ $COMP_CWORD = 3 ]
225 then
226 compreply="$site_subcmds"
227 else
228 subcmd=${COMP_WORDS[3]}
229 let cword_idx-=1
232 case "$subcmd" in
233 (prop)
234 case $cword_idx in
236 compreply=`cred list-props "$site"`
239 compreply="set edit del show clip"
241 esac
243 (clip)
244 compreply=`cred list-props "$site"`
246 (dump)
247 case $cword_idx in
249 compreply="reveal-secrets mask-secrets hash-secrets"
251 esac
252 esac
254 esac
255 COMPREPLY=($(compgen -W "$compreply" -- "${COMP_WORDS[$COMP_CWORD]}"))
256 return 0
258 complete -F _autocomplete_cred cred
259 # use this in your bash session by eg: eval "$(cred compscript)"
263 warnx 'Use tab-completion!'
264 warnx 'Example: eval "$(cred compscript)"'
265 false
267 esac
269 exit