dmenupass

X11 username/password autotyper with dmenu selection
git clone git://git.deurzen.net/dmenupass
Log | Files | Refs | LICENSE

commit 23b72bbf0c3207846e210df6a137921225ef4218
Author: deurzen <max@deurzen.net>
Date:   Wed, 25 May 2022 05:15:45 +0200

initial commit

Diffstat:
ALICENSE | 27+++++++++++++++++++++++++++
Admenupass | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2022, Max van Deurzen <max@deurzen.net> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dmenupass b/dmenupass @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +set -Eeo pipefail + +arg="$1" +if [[ $arg == "--copy" ]]; then + prompt="Copy:" + copy=1 +elif [[ $arg == "--print" ]]; then + prompt="Print:"; + print=1 +else + prompt="Autotype:" + autotype=1 +fi + +shopt -s nullglob globstar + +username_delim='user' +password_delim='pass' + +username_field_delim='user:' +password_field_delim='pass:' +sequence_field_delim='dpseq:' +url_field_delim='url:' + +default_sequence='user :tab pass :enter' + + +__init__() { + prefix=${PASSWORD_STORE_DIR:-~/.password-store} + password_itemlist=( "$prefix"/**/*.gpg ) + password_itemlist=( "${password_itemlist[@]#"$prefix"/}" ) + password_itemlist=( "${password_itemlist[@]%.gpg}" ) + password_item=$(printf '%s\n' "${password_itemlist[@]}" | dmenu -p "$prompt" "$@") + [[ -n $password_item ]] || exit + [ ! -z "$copy" ] && { __copy__ 2>/dev/null; exit; } + [ ! -z "$print" ] && { __print__ 2>/dev/null; exit; } + password_itemfile="$prefix/${password_item}.gpg" + + while IFS= read -r line + do + key=$(awk '{print $1;}' <<< "$line") + value=${line##$key } + case "$key" in + "${username_field_delim}") + username="$value" + ;; + "${password_field_delim}") + password="$value" + ;; + "${sequence_field_delim}") + sequence="$value" + ;; + "${url_field_delim}") + url="$value" + ;; + *);; + esac + done < <(pass "$password_item" || kill -HUP $$;) +} + +__run__() { + for token in ${sequence:-${default_sequence}} + do + case "$token" in + "${username_delim}") + xdotool type --clearmodifiers "$username" + ;; + "${password_delim}") + xdotool type --clearmodifiers "$password" + ;; + ':wait') + sleep 0.2 + ;; + ':pause') + sleep 1 + ;; + ':input') + xdotool key semicolon key t + sleep 0.1 + xdotool key a + ;; + ':tab') + xdotool key Tab + ;; + ':enter') + xdotool key KP_Enter + ;; + *);; + esac + done + + unset -v username + unset -v password + unset -v sequence + unset -v url +} + +__copy__() { + password=$(pass $password_item | grep ^$password_delim | awk '{print $2}') + if type xclip >/dev/null 2>&1; then + echo -n "$password" | xclip -selection c + elif type xsel >/dev/null 2>&1; then + echo -n "$password" | xsel -b + fi + unset -v password +} + +__print__() { + password=$(pass $password_item | grep ^$password_delim | awk '{print $2}') + echo -n "$password" + unset -v password +} + +__init__ 2>/dev/null +__run__ 2>/dev/null