[pass] [PATCH] Add support for displaying QR codes.

Patrick Burroughs (Celti) celticmadman at gmail.com
Fri Jun 20 02:23:38 CEST 2014


This patch adds support for displaying passwords as QR codes for easy transfer
to any device that can read them, rendered in the terminal with ANSI escape
sequences via qrencode.

---
 man/pass.1            | 10 ++++++++--
 src/password-store.sh | 37 ++++++++++++++++++++++++-------------
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/man/pass.1 b/man/pass.1
index 8ac8ecf..4d44f8a 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -86,12 +86,15 @@ List names of passwords inside the tree that match \fIpass-names\fP by using the
 .BR tree (1)
 program. This command is alternatively named \fBsearch\fP.
 .TP
-\fBshow\fP [ \fI--clip\fP, \fI-c\fP ] \fIpass-name\fP
+\fBshow\fP [ \fI--clip\fP, \fI-c\fP | \fI--qr\fP, \fI-q\fP ] \fIpass-name\fP
 Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP
 is specified, do not print the password but instead copy the first line to the
 clipboard using
 .BR xclip (1)
 and then restore the clipboard after 45 (or \fIPASSWORD_STORE_CLIP_TIME\fP) seconds.
+If \fI--qr\fP or \fI-q\fP is specified, do not print the password but instead display the first line as a QR code
+encoded using
+.BR qrencode (1).
 .TP
 \fBinsert\fP [ \fI--echo\fP, \fI-e\fP | \fI--multiline\fP, \fI-m\fP ] [ \fI--force\fP, \fI-f\fP ] \fIpass-name\fP
 Insert a new password into the password store called \fIpass-name\fP. This will
@@ -110,7 +113,7 @@ ensure that temporary files are created in \fI/dev/shm\fP in order to avoid writ
 difficult-to-erase disk sectors. If \fI/dev/shm\fP is not accessible, fallback to
 the ordinary \fITMPDIR\fP location, and print a warning.
 .TP
-\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--clip\fP, \fI-c\fP ] [ \fI--in-place\fP, \fI-i\fP | \fI--force\fP, \fI-f\fP ] \fIpass-name pass-length\fP
+\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--clip\fP, \fI-c\fP | \fI--qr\fP, \fI-q\fP ] [ \fI--in-place\fP, \fI-i\fP | \fI--force\fP, \fI-f\fP ] \fIpass-name pass-length\fP
 Generate a new password using
 .BR pwgen (1)
 of length \fIpass-length\fP and insert into \fIpass-name\fP. If \fI--no-symbols\fP or \fI-n\fP
@@ -119,6 +122,9 @@ If \fI--clip\fP or \fI-c\fP is specified, do not print the password but instead
 it to the clipboard using
 .BR xclip (1)
 and then restore the clipboard after 45 (or \fIPASSWORD_STORE_CLIP_TIME\fP) seconds.
+If \fI--qr\fP or \fI-q\fP is specified, do not print the password but instead display the first line as a QR code
+encoded using
+.BR qrencode (1).
 Prompt before overwriting an existing password,
 unless \fI--force\fP or \fI-f\fP is specified. If \fI--in-place\fP or \fI-i\fP is
 specified, do not interactively prompt, and only replace the first line of the password
diff --git a/src/password-store.sh b/src/password-store.sh
index e68384b..75b451b 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -126,7 +126,10 @@ check_sneaky_paths() {
 		[[ $path =~ /\.\.$ || $path =~ ^\.\./ || $path =~ /\.\./ || $path =~ ^\.\.$ ]] && die "Error: You've attempted to pass a sneaky path to pass. Go home."
 	done
 }
-
+qr_encode() {
+	echo "Displaying $2 as QR code."
+	echo -n "$1" | qrencode --8bit --type=ANSI
+}
 #
 # END helper functions
 #
@@ -222,8 +225,8 @@ cmd_usage() {
 	        List passwords.
 	    $PROGRAM find pass-names...
 	    	List passwords that match pass-names.
-	    $PROGRAM [show] [--clip,-c] pass-name
-	        Show existing password and optionally put it on the clipboard.
+	    $PROGRAM [show] [--clip,-c | --qr,-q] pass-name
+	        Show existing password and optionally put it on the clipboard or display it as a QR code.
 	        If put on the clipboard, it will be cleared in $CLIP_TIME seconds.
 	    $PROGRAM grep search-string
 	        Search for password files containing search-string when decrypted.
@@ -233,9 +236,9 @@ cmd_usage() {
 	        overwriting existing password unless forced.
 	    $PROGRAM edit pass-name
 	        Insert a new password or edit an existing password using ${EDITOR:-vi}.
-	    $PROGRAM generate [--no-symbols,-n] [--clip,-c] [--in-place,-i | --force,-f] pass-name pass-length
+	    $PROGRAM generate [--no-symbols,-n] [--clip,-c | --qr,-q] [--in-place,-i | --force,-f] pass-name pass-length
 	        Generate a new password of pass-length with optionally no symbols.
-	        Optionally put it on the clipboard and clear board after 45 seconds.
+	        Optionally put it on the clipboard and clear board after $CLIP_TIME seconds, or display it as a QR code.
 	        Prompt before overwriting existing password unless forced.
 	        Optionally replace only the first line of an existing file with a new password.
 	    $PROGRAM rm [--recursive,-r] [--force,-f] pass-name
@@ -294,27 +297,32 @@ cmd_init() {
 }
 
 cmd_show() {
-	local opts clip=0
-	opts="$($GETOPT -o c -l clip -n "$PROGRAM" -- "$@")"
+	local opts clip=0 qr=0
+	opts="$($GETOPT -o cq -l clip,qr -n "$PROGRAM" -- "$@")"
 	local err=$?
 	eval set -- "$opts"
 	while true; do case $1 in
 		-c|--clip) clip=1; shift ;;
+		-q|--qr) qr=1; shift ;;
 		--) shift; break ;;
 	esac done
 
-	[[ $err -ne 0 ]] && die "Usage: $PROGRAM $COMMAND [--clip,-c] [pass-name]"
+	[[ $err -ne 0 ]] && die "Usage: $PROGRAM $COMMAND [--clip,-c | --qr,-q] [pass-name]"
 
 	local path="$1"
 	local passfile="$PREFIX/$path.gpg"
 	check_sneaky_paths "$path"
 	if [[ -f $passfile ]]; then
-		if [[ $clip -eq 0 ]]; then
+		if [[ $clip -eq 0 && $qr -eq 0 ]]; then
 			exec $GPG -d "${GPG_OPTS[@]}" "$passfile"
 		else
 			local pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | head -n 1)"
 			[[ -n $pass ]] || exit 1
-			clip "$pass" "$path"
+			if [[ $clip -eq 1 ]]; then
+				clip "$pass" "$path"
+			elif [[ $qr -eq 1 ]]; then
+				qr_encode "$pass" "$path"
+			fi
 		fi
 	elif [[ -d $PREFIX/$path ]]; then
 		if [[ -z $path ]]; then
@@ -435,12 +443,13 @@ cmd_edit() {
 
 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" -- "$@")"
+	opts="$($GETOPT -o ncqif -l no-symbols,clip,qr,in-place,force -n "$PROGRAM" -- "$@")"
 	local err=$?
 	eval set -- "$opts"
 	while true; do case $1 in
 		-n|--no-symbols) symbols=""; shift ;;
 		-c|--clip) clip=1; shift ;;
+		-q|--qr) qr=1; shift ;;
 		-f|--force) force=1; shift ;;
 		-i|--in-place) inplace=1; shift ;;
 		--) shift; break ;;
@@ -474,10 +483,12 @@ cmd_generate() {
 	[[ $inplace -eq 1 ]] && verb="Replace"
 	git_add_file "$passfile" "$verb generated password for ${path}."
 
-	if [[ $clip -eq 0 ]]; then
+	if [[ $clip -eq 0 && $qr -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
+	elif [[ $clip -eq 1 ]]; then
 		clip "$pass" "$path"
+	elif [[ $qr -eq 1 ]]; then
+		qr_encode "$pass" "$path"
 	fi
 }
 
-- 
2.0.0



More information about the Password-Store mailing list