8 cred - Credentials and secrets management in command line
12 cred I<SUBCOMMAND> I<SITE> [I<ARGUMENTS>]
14 cred site I<SITE> I<SUBCOMMAND> [I<ARGUMENTS>]
18 I<SITE> is a container of one or more properties, most often a website name.
19 It is represented in a directory in the credentials base dir.
20 You may also enter a directory path on the filesystem for I<SITE>.
21 You don't need to create a I<SITE>: it's created automatically when you write in it.
29 Output a bash script to setup tab-completion for the C<cred> command.
30 Use it by eg: C<eval "$(cred compscript)">
34 =item dump [reveal-secrets | mask-secrets | hash-secrets]
36 Display all properties (and their values) of a given site.
37 Optional parameter is how secrets are displayed:
38 B<mask-secrets> is the default and replaces a secret string's characters by asterisk (C<*>).
39 B<hash-secrets> replaces secrets by a hash and the checksum algorithm' name
40 is appended to the hash with a tab, like: <TAB>B<hash-algo=>I<NAME>.
41 Finally B<reveal-secrets> displays secret strings in clear text just like ordinary properties.
43 =item generate-password
45 Generate a new password and put in B<PASSWORD> property.
46 And append its old value to the B<OLDPASSWORDS> property.
50 =item prop I<PROPERTY> [set I<NEW-VALUE> | edit | read | del | show | clip]
52 Manage properties of a given site.
53 The B<edit> instruction opens up the B<$EDITOR> (falling back to B<$VISUAL>) to edit the given property's value.
54 B<read> reads the new value from the STDIN (readline is supported if bash does support it, see C<help read> in bash(1)).
55 Secrets are read in no-echo mode.
56 The B<clip> instruction does the same as B<clip> subcommand, see below.
58 =item clip I<PROPERTY>
60 By B<clip> you may copy the value to the clipboard.
61 If you use CopyQ(1), secrets are prevented to get to CopyQ's clipboard items history.
63 =item fill-form I<PROPERTY> [I<PROPERTY> [...]]
65 Takes one or more property names and types their values to the window accessible by pressing Alt+Tab on your desktop.
66 Also presses <TAB> after each string, but does not press <RETURN>.
67 Obviously it's useful only with a B<$DESKTOP>.
68 Depends on xdotool(1).
74 Hardcoded credentials' directory is F<~/cred>.
88 # need to set these shell options before they are relied upon when bash parses the big { ... } block later down.
90 shopt -s expand_aliases
91 # aliases in non-interactive bash script are not evaluated in the same scope where they are defined,
92 # but they are in the big { ... } block below.
93 alias set_site
='if [ -z "${site:-}" ]; then set_site_func "${1:-}"; shift; fi;'
100 .
/usr
/lib
/tool
/bash-utils
101 .
/usr
/lib
/tool
/ansi-codes
107 local i stack_size
=${#FUNCNAME[@]}
108 for (( i
=1; i
<stack_size
; i
++ )); do
109 local func
="${FUNCNAME[$i]}"
110 [[ $func = "" ]] && func
=MAIN
111 local linen
="${BASH_LINENO[$(( i - 1 ))]}"
112 local src
="${BASH_SOURCE[$i]}"
113 [[ "$src" = "" ]] && src
=non_file_source
115 echo -n "$ANSI_bold$ANSI_fg_black"
116 echo " function: $func"
117 echo " file: $src (line $linen)"
118 echo -n "$ANSI_reset"
120 local line_number_text_sep
='| '
121 nl -ba -w ${#linen} -s " $line_number_text_sep" "$src" |
grep -C 2 -E "^\s*$linen " |\
123 sed -e "s/^\(\s*$linen\) \(.\{${#line_number_text_sep}\}\)\(.*\)/\1-\2$ANSI_italic\3$ANSI_normal/" |\
124 sd
'^' "$ANSI_bold$ANSI_fg_black" | sd
'$' "$ANSI_reset"
128 trap 'print_traceback >&2' ERR
135 errx
1 "Enter site name or directory!"
138 site
=`basename "$param"`
146 [[ $1 =~ password|key|cvc|secret|pin
]]
152 if type copyq
1>/dev
/null
2>&1 && is_secret
"$prop"
154 copyq_monitoring
=`copyq monitoring`
155 if [ "$copyq_monitoring" = true
]
160 if [ "$copyq_monitoring" = true
]
165 xclip
-i -selection clipboard
174 if [ "${1:-}" = site
]
192 GLOBIGNORE
=${GLOBIGNORE:-}${GLOBIGNORE:+:}".:..:.[!/.]*:..[!/]*:-*"
201 if in_list reveal-secrets
"${options[@]}"
204 elif in_list hash-secrets
"${options[@]}"
206 hash=`cat "$file" | md5sum | cut -c 1-32`
207 echo "$file$TAB$hash$TAB""hash-algo=md5"
210 echo "$file"$
'\t'"*****"
215 grep .
"$file" | prefixlines
"$file"$
'\t'
222 cred dump
"$parent" "${options[@]}"
227 find -L "$basedir" -path "$basedir/${1:-}*" -type d
-printf "%P\n"
231 prop
=${1:?'enter property name!'}
239 warnx
"$prop is a secret."
240 warnx
"enter 'cred [...] prop [...] $prop show' explicitely, or"
241 warnx
"more preferably 'cred [...] prop [...] $prop clip' to copy to the clipboard!"
244 cat "$basedir/$site/$prop"
248 cat "$basedir/$site/$prop" | do_clip
"$prop"
251 elif [ "$subcmd" = prop
]
257 mkdir
-p "$basedir/$site"
258 printf '%s' "$val" > "$basedir/$site/$prop"
261 mkdir
-p "$basedir/$site"
262 "${EDITOR:-$VISUAL}" "$basedir/$site/$prop"
267 read -s -p "$prop: " -e val
269 read -p "$prop: " -e val
271 printf '%s' "$val" > "$basedir/$site/$prop"
274 rm "$basedir/$site/$prop"
277 cat "$basedir/$site/$prop"
280 cat "$basedir/$site/$prop" | do_clip
"$prop"
283 false
"invalid argument"
295 val
=`cat "$basedir/$site/$prop"`
296 strings="$strings$val"$
'\t'
298 xdotool key Alt
+Tab
type "$strings"
300 errx
1 "Enter property names in order to fill the form on the window brought to focus by Alt+Tab."
305 find "$basedir/$site" -type f
-printf "%P\n"
309 newpwd
=$
(pwgen
-y 8 1)$
(pwgen
-y 8 1)
311 pwdfile
=$basedir/$site/PASSWORD
312 mkdir
-p "$basedir/$site"
315 cur_pwd
=`cat "$pwdfile"`
316 atime
=`stat -c %x "$pwdfile"`
317 now
=`date +'%F %T.%N %z'`
318 echo "$atime $now $cur_pwd" >> "$basedir/$site/OLDPASSWORDS"
320 printf '%s' "$newpwd" > "$pwdfile"
324 _autocomplete_cred() {
326 local curr_word=${COMP_WORDS[$COMP_CWORD]}
327 local prev_word=${COMP_WORDS[$[COMP_CWORD - 1]]}
328 local site_subcmds="list-sites dump generate-password list-props prop clip fill-form"
332 compreply="compscript site $site_subcmds"
335 local site=$curr_word; site=${site/#'~/'/$HOME/}
336 compreply=`cred list-sites "$site"`
339 local subcmd=${COMP_WORDS[1]}
340 local site=${COMP_WORDS[2]}; site=${site/#'~/'/$HOME/}
341 local cword_idx=$COMP_CWORD
342 if [ "$subcmd" = site ]
344 if [ $COMP_CWORD = 3 ]
346 compreply="$site_subcmds"
348 subcmd=${COMP_WORDS[3]}
356 compreply=`cred list-props "$site"`
359 compreply="set edit read del show clip"
364 compreply=`cred list-props "$site"`
369 compreply="reveal-secrets mask-secrets hash-secrets"
375 COMPREPLY=($(compgen -W "$compreply" -- "${COMP_WORDS[$COMP_CWORD]}"))
378 complete -F _autocomplete_cred cred
379 # use this in your bash session by eg: eval "$(cred compscript)"
383 warnx
'Use tab-completion!'
384 warnx
'Example: eval "$(cred compscript)"'