[pass] [Add passphrase feature 1/4] add new command 'passphrase'

Joschka Tillmanns joschka at tillmanns.me
Thu Apr 28 02:11:25 CEST 2016


PASSPHRASE generates a series of words which are seperated by a single
whitespace character and stores them in pass-name. The behavior of this
function is therefor similar to GENERATE. --clip,-c as well as
--force,-c behave the same. --words,-w lets the user define how many
words the passphrase should contain, --max,-m defines the maximum word
length. Choosing a maximum of 8 mostly yields simple enough words which
serve the purpose. The aspell-en database contains 404000 words in the
range of 4 and 8 characters. Thus a maximum word length of 8 is the
default setting.

PASSPHRASE utilizes the aspell utility to retrieve a word list. This
also means that pass has to accept aspell as an additional dependency.

The idea behind this patch is this famous xkcd strip

    http://xkcd.com/936/

which depicts the strength of passwords containing standard
words. Furthermore this blog post

     http://www.baekdal.com/insights/password-security-usability

elaborates on this idea. While these references point out that word
based passwords are easier to remember I had a further motivation for
this patch. Altough pass is easy to use on android or other mobile
devices it's still often more convenient to just type in the password
you just generated. Having a word based passphrase simplifies this
procedure a lot. Another scenario would be if you have to verbally share
your password with a coworker who is sitting at another
workstation. Having to spell out 8-16 character long passwords can be
extremely exhausting while communicating 4-6 words comes pretty natural.
---
 src/password-store.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/password-store.sh b/src/password-store.sh
index 63be840..d57634e 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -430,6 +430,58 @@ cmd_edit() {
 	git_add_file "$passfile" "$action password for $path using ${EDITOR:-vi}."
 }
 
+cmd_passphrase() {
+	local opts clip=0 force=0 max=8 words=4
+	opts="$($GETOPT -o cm:w:f -l clip,max:,words:,force, -n "$PROGRAM" -- "$@")"
+	local err=$?
+	eval set -- "$opts"
+	while true; do case $1 in
+		   -c|--clip) clip=1; shift ;;
+		   -m| --max) max="$2"; echo $max; shift 2 ;;
+		   -w| --words) words="$2"; shift 2 ;;
+		   -f| --force) force=1; shift ;;
+		   --) shift; break ;;
+	esac done
+
+	[[ $err -ne 0 || ( $# -ne 2 && $# -ne 1 ) || ( $force -eq 1 && $inplace -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip,-c] [--max,-m] [--words,-w] [--force,-f]  pass-name"
+	[[ ! $max =~ ^[0-9]+$ ]] && die "Error: maximum word length \"$max\" must be a number."
+	[[ ! $words =~ ^[0-9]+$ ]] && die "Error: word count \"$words\" must be a number."
+	local path="$1"
+	check_sneaky_paths "$path"
+	mkdir -p -v "$PREFIX/$(dirname "$path")"
+	set_gpg_recipients "$(dirname "$path")"
+	local passfile="$PREFIX/$path.gpg"
+
+	[[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?"
+
+	local tmp_wordlist=$(mktemp)
+	local min=4
+	aspell -d en dump master | grep -v "'s$" | grep -v "^[A-Z]" | awk "length>=$min && length<=$max" > $tmp_wordlist
+	local wc=$(cat $tmp_wordlist | wc -l)
+
+	local pass=""
+	local r=""
+	for i in $(seq 1 $words); do
+		r=$(od -An -N4 -tu4 < /dev/urandom | sed 's/ //g')
+		r=$(expr $r % $wc)
+		r=$(sed -n "$r p" $tmp_wordlist)
+		pass="$r $pass"
+	done
+
+	pass=$(echo $pass | sed 's/ $//')
+	[[ -n $pass ]] || exit 1
+	$GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" <<<"$pass" || die "Password encryption aborted."
+
+	local verb="Add"
+	git_add_file "$passfile" "$verb generated password for ${path}."
+
+	if [[ $clip -eq 0 ]]; then
+	    printf "\e[1m\e[37mThe generated password for \e[4m%s\e[24m is:\e[0m\n\e[1m\e[93m%s\e[0m\n" "$path" "$pass"
+	else
+		clip "$pass" "$path"
+	fi
+}
+
 cmd_generate() {
 	local opts clip=0 force=0 symbols="-y" inplace=0
 	opts="$($GETOPT -o ncif -l no-symbols,clip,in-place,force -n "$PROGRAM" -- "$@")"
@@ -588,6 +640,7 @@ case "$1" in
 	insert|add) shift;		cmd_insert "$@" ;;
 	edit) shift;			cmd_edit "$@" ;;
 	generate) shift;		cmd_generate "$@" ;;
+	passphrase) shift;              cmd_passphrase "$@" ;;
 	delete|rm|remove) shift;	cmd_delete "$@" ;;
 	rename|mv) shift;		cmd_copy_move "move" "$@" ;;
 	copy|cp) shift;			cmd_copy_move "copy" "$@" ;;
-- 
2.8.0



More information about the Password-Store mailing list