Hello, nice to meet you. This patch will integrate oathtool functionality, if 
oathtool is available in the user's environment. The intention is to init a 
subdirectory with it's own .git and .gpg-id, so the user can have a 2FA 
directory that is separated from ppasswords.

The introduced functionality is an --otp argument for cmd_show which when given 
the -o or --otp argument (additionally a token length) can show the generated 
token, clip will copy the generated token but qrcode will provides the qrcode 
of the original key so that it can be added to an authenticator app.

Having 2FA keys stored in pass suits my workflow so I imagine it might be 
helpful to others? If there is anything I can help with let me know. Thank you 
for your time.


---
 man/pass.1                |  8 +++++++-
 src/password-store.sh     | 32 ++++++++++++++++++++++++++------
 tests/t0020-show-tests.sh | 14 ++++++++++++++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/man/pass.1 b/man/pass.1
index 01a3fbe..73ce926 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -244,6 +244,11 @@ Copy existing password to clipboard
 .br
 Copied Email/[email protected] to clipboard. Will clear in 45 seconds.
 .TP
+Show existing password as OTP 2FA code
+.B zx2c4@laptop ~ $ pass -o 2FA/zx2c4.com
+.br
+398652
+.TP
 Add password to store
 .B zx2c4@laptop ~ $ pass insert Business/cheese-whiz-factory
 .br
@@ -466,7 +471,8 @@ The location of the text editor used by \fBedit\fP.
 .BR tr (1),
 .BR git (1),
 .BR xclip (1),
-.BR qrencode (1).
+.BR qrencode (1),
+.BR oathtool (1).

 .SH AUTHOR
 .B pass
diff --git a/src/password-store.sh b/src/password-store.sh
index d89d455..ffa80a1 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -11,6 +11,7 @@ GPG="gpg"
 export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null)}"
 which gpg2 &>/dev/null && GPG="gpg2"
 [[ -n $GPG_AGENT_INFO || $GPG == "gpg2" ]] && GPG_OPTS+=( "--batch" 
"--use-agent" )
+which oathtool &>/dev/null && OATHTOOL="oathtool"

 PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
 EXTENSIONS="${PASSWORD_STORE_EXTENSIONS_DIR:-$PREFIX/.extensions}"
@@ -348,33 +349,52 @@ cmd_init() {

 cmd_show() {
        local opts selected_line clip=0 qrcode=0
-       opts="$($GETOPT -o q::c:: -l qrcode::,clip:: -n "$PROGRAM" -- "$@")"
+       opts="$($GETOPT -o q::c::o:: -l qrcode::,clip::,otp:: -n "$PROGRAM" -- 
"$@")"
        local err=$?
        eval set -- "$opts"
        while true; do case $1 in
                -q|--qrcode) qrcode=1; selected_line="${2:-1}"; shift 2 ;;
+               -o|--otp) otp=1; otp_length="${2:-6}"; shift 2 ;;
                -c|--clip) clip=1; selected_line="${2:-1}"; shift 2 ;;
                --) shift; break ;;
        esac done

-       [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: 
$PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] 
[--qrcode[=line-number],-q[line-number]] [pass-name]"
+       [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 && $otp -eq 1 ) ]] && 
die "Usage: $PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] 
[--qrcode[=line-number],-q[line-number]] [--otp[=length]],-o[length]] 
[pass-name]"

+       if [[ $otp -eq 1 ]] ; then
+               [[ -z $OATHTOOL ]] && die "this feature requires oathtool"
+               [[ $otp_length =~ ^[6-8]$ ]] || die "OTP length must be 6, 7 or 
8 digits."
+       fi
+
        local pass
        local path="$1"
        local passfile="$PREFIX/$path.gpg"
        check_sneaky_paths "$path"
        if [[ -f $passfile ]]; then
                if [[ $clip -eq 0 && $qrcode -eq 0 ]]; then
-                       pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | 
$BASE64)" || exit $?
-                       echo "$pass" | $BASE64 -d
+                       if [[ $otp -eq 1 ]]; then
+                               pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile")" 
|| exit $?
+                               echo $($OATHTOOL --base32 --totp "$pass" -d 
$otp_length)
+                       else
+                               pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | 
$BASE64)" || exit $?
+                               echo "$pass" | $BASE64 -d
+                       fi
                else
                        [[ $selected_line =~ ^[0-9]+$ ]] || die "Clip location 
'$selected_line' is not a number."
                        pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | tail -n 
+${selected_line} | head -n 1)" || exit $?
                        [[ -n $pass ]] || die "There is no password to put on 
the clipboard at line ${selected_line}."
                        if [[ $clip -eq 1 ]]; then
-                               clip "$pass" "$path"
+                               if [[ $otp -eq 1 ]]; then
+                                       clip "$($OATHTOOL --base32 --totp 
"$pass" -d $otp_length)" "$path"
+                               else
+                                       clip "$pass" "$path"
+                               fi
                        elif [[ $qrcode -eq 1 ]]; then
-                               qrcode "$pass" "$path"
+                               if [[ $otp -eq 1 ]]; then
+                                       qrcode 
"otpauth://totp/?secret=$pass&issuer=$path" "$path"
+                               else
+                                       qrcode "$pass" "$path"
+                               fi
                        fi
                fi
        elif [[ -d $PREFIX/$path ]]; then
diff --git a/tests/t0020-show-tests.sh b/tests/t0020-show-tests.sh
index a4b782f..4139a10 100755
--- a/tests/t0020-show-tests.sh
+++ b/tests/t0020-show-tests.sh
@@ -19,4 +19,18 @@ test_expect_success 'Test "show" of nonexistant password' '
        test_must_fail "$PASS" show cred2
 '

+which oathtool &>/dev/null && OATHTOOL="oathtool"
+if [[ ! -z $OATHTOOL ]] ; then
+
+       test_expect_success 'Test "show" command with 6 digit otp' '
+               "$PASS" insert -e 
"2FA/Token6"<<<"QXXFF4RRTTIIT4MMZZXZ555WWWWQQQFF" &&
+               [[ $("$PASS" show "2FA/Token6" -o6) =~ ^[0-9]{6}$ ]]
+       '
+
+       test_expect_success 'Test "show" command with 8 digit otp' '
+               "$PASS" insert -e 
"2FA/Token8"<<<"QXXFF4RRTTIIT4MMZZXZ555WWWWQQQFF" &&
+               [[ $("$PASS" show "2FA/Token8" -o8) =~ ^[0-9]{8}$ ]]
+       '
+fi
+
 test_done
--
2.17.2


_______________________________________________
Password-Store mailing list
[email protected]
https://lists.zx2c4.com/mailman/listinfo/password-store

Reply via email to