From eacb4ff7affb29acffa6f7187c49c324606cac96 Mon Sep 17 00:00:00 2001 From: AluminumTank Date: Fri, 27 Mar 2020 22:55:38 -0400 Subject: [PATCH] add script and README --- README.md | 31 +++++++++++++++++++++ wofi-pass | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 README.md create mode 100755 wofi-pass diff --git a/README.md b/README.md new file mode 100644 index 0000000..e0eede1 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# wofi-pass +Since `wofi` isn't a drop-in replacement for `rofi`, I couldn't use +[rofi-pass](https://github.com/carnager/rofi-pass) anymore. So, I just made a +version of `passmenu` that accomplishes everything I needed from `rofi-pass`. + +## What does it do? +This script uses [wofi](https://hg.sr.ht/~scoopta/wofi) and +[ydotool](https://github.com/ReimuNotMoe/ydotool) to provide a completely +Wayland-native way to conveniently use [pass](https://www.passwordstore.org/). +It provides the same search that `passmenu` does, but shows a second dialogue +that lets the user choose which field to copy/print. + +It also assumes that [pass-otp](https://github.com/tadfisher/pass-otp) is +installed if an `otpauth://...` string is present in a password file. + +The script assumes several things: +1. The password is on the first line; +2. The rest of the lines are formatted as key:value pairs. + +See the following example: + +``` +Th3Gr3at3stPassw0rd +username: JohnDoe +email: john@example.com +otpauth://totp/example?secret=ABCDCBABCDCBABCD +pin: 1234 +``` + +I know this script needs some work; it was mostly hacked together in an +afternoon to get the minimum functionality I needed. diff --git a/wofi-pass b/wofi-pass new file mode 100755 index 0000000..71e41ea --- /dev/null +++ b/wofi-pass @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +shopt -s nullglob globstar + +_trim() { + local var="$*" + # remove leading whitespace characters + var="${var#"${var%%[![:space:]]*}"}" + # remove trailing whitespace characters + var="${var%"${var##*[![:space:]]}"}" + printf '%s' "$var" +} + +_parse_fields() { + IFS=$'\n' + fields="$(pass show $password | tail -n +2 | cut -d: -f1 -s)" + if [[ $typeit -eq 1 ]]; then + printf "autotype\n" + fi + printf "password\n" + for line in $fields; do + if [[ $line == "otpauth" ]]; then + printf "OTP\n" + else + printf "$line\n" + fi + done + unset IFS +} + +_pass_field() { + IFS=$'\n' + plaintext="$(pass show $password | tail -n +2)" + for line in $plaintext; do + if [[ $line == $1:* ]]; then + printf "$(_trim "$(printf "$line" | cut -d: -f2 -s)")" + fi + done + unset IFS +} + +_pass_get() { + if [[ $1 == "password" ]]; then + pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } + elif [[ $1 == "OTP" ]]; then + pass otp "$password" | tail -n1 | { IFS= read -r pass; printf %s "$pass"; } + else + printf "$(_pass_field $1)" + fi +} + +typeit=0 +if [[ $1 == "--type" ]]; then + typeit=1 + shift +fi + +prefix=${PASSWORD_STORE_DIR-~/.password-store} +password_files=( "$prefix"/**/*.gpg ) +password_files=( "${password_files[@]#"$prefix"/}" ) +password_files=( "${password_files[@]%.gpg}" ) + +password=$(printf '%s\n' "${password_files[@]}" | wofi -i --dmenu "$@") +[[ -n $password ]] || exit +field_list="$(_parse_fields)" +field=$(printf "$field_list" | wofi -i --dmenu) +echo $field + +if [[ $typeit -eq 0 ]]; then + wl-copy "$(_pass_get $field)" +else + if [[ $field == "autotype" ]]; then + _pass_get "username" | ydotool type --file - + printf "\t" | ydotool type --file - + _pass_get "password" | ydotool type --file - + printf "\n" | ydotool type --file - + else + _pass_get $field | ydotool type --file - + fi +fi