From 55708bf1aa5dbe08fa1d37979dc290a737b2651b Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Wed, 4 Jan 2023 13:44:16 +0100 Subject: bin/secretmenu: make it a fully functional pw manager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- .config/mbsyncrc | 4 +-- bin/secretmenu | 83 ++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/.config/mbsyncrc b/.config/mbsyncrc index 828a075..7ac6444 100644 --- a/.config/mbsyncrc +++ b/.config/mbsyncrc @@ -3,7 +3,7 @@ IMAPAccount gnzler Host mail.gandi.net User robert@gnzler.io -PassCmd "pass email/gnzler.io | head -n1" +PassCmd "secretmenu -P1 gnzler.io | head -n1" SSLType IMAPS IMAPStore gnzler @@ -28,7 +28,7 @@ Expunge both IMAPAccount selfhosted Host localhost:1430 User postmaster@gnzler.de -PassCmd "pass email/postmaster@gnzler.io | head -n1" +PassCmd "secretmenu -P1 postmaster@gnzler.io | head -n1" SSLType None IMAPStore selfhosted diff --git a/bin/secretmenu b/bin/secretmenu index 1cbc1fc..0ba9754 100755 --- a/bin/secretmenu +++ b/bin/secretmenu @@ -6,29 +6,53 @@ set -eo pipefail ico=$(iconez -fs -n dialog-password-symbolic) trap '{ notify-send -a secretmenu -i "${ico}" -c error "secretmenu: failed :(" "pipefail"; exit 1; }' ERR -if [ "$1" = "-b" ] || command -v rbw >/dev/null 2>&1; then - secretmgr=rbw +secretmgr=rbw +printpass= +first= +while getopts bpP1h name; do + case ${name} in + b) secretmgr=rbw ;; + p) secretmgr=pass ;; + P) printpass=1 ;; + 1) first=1 ;; + h | ?) + echo "usage: secretmenu [-bp] [-P] [-1] [query]" + echo + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +if [ "$secretmgr" = "rbw" ] && command -v rbw >/dev/null 2>&1; then __list_secrets() { - rbw list + rbw list --fields user,name | tr '\t' '@' } __query_secret() { - rbw get --full "$1" 2>&1 + rbw get --full $(awk -F@ '{print $2 " " $1}' <<<"$1") 2>&1 } -else - secretmgr=pass +fi +if [ "$secretmgr" = "pass" ] && command -v pass >/dev/null 2>&1; then __list_secrets() { prefix=${PASSWORD_STORE_DIR-~/.password-store} prefix=$(readlink -f -- "${prefix}") - fd -e gpg . "${prefix}" | sed -e "s#${prefix}/##" -e 's#\.gpg$##' + fd -e gpg . "${prefix}" | + sed -e "s#${prefix}/##" -e 's#\.gpg$##' } __query_secret() { pass show "$1" 2>&1 } fi -__handle() { - awk 'NR==1 {system("wl-copy -n " $0);hit+=1} /^Username:/ {system("wl-copy -n -p " $2);hit+=1} END{if(hit==0) print("no secret found")}' -} +if [ -n "$printpass" ]; then + __handle() { + awk 'NR==1 {print $0;hit+=1} END{if(hit==0){print("no secret found") >/dev/stderr; exit(1);}}' + } +else + __handle() { + awk 'NR==1 {system("wl-copy -n " $0);hit+=1} /^Username:/ {system("wl-copy -n -p " $2);hit+=1} END{if(hit==0){print("no secret found") >/dev/stderr; exit(1);}}' + } +fi # check requirements for tool in bemenu fd fzf $secretmgr; do @@ -46,40 +70,45 @@ done # fi __menu() { - if [ ! -t 1 ]; then - MENU_PROMPT="󰌆 secret" menu - else - fzf + if [ -n "$first" ]; then + grep "$@" | head -n1 + return + fi + if [ -t 1 ]; then + echo "terminal mode not implemented" + exit 1 fi + MENU_PROMPT="󰌆 secret" menu --accept-single ${@:+--filter "$@"} } pw=$({ __list_secrets echo ">>pass" - echo ">>bw" -} | __menu "$@") + echo ">>rbw" +} | + __menu "$@") case "$pw" in "") exit 1 ;; -">>pass") exec "$0" ;; -">>bw") exec "$0" -b ;; +">>pass") exec "$0" -p ;; +">>rbw") exec "$0" -b ;; esac -err=$(__query_secret "$pw" | __handle) +__query_secret "$pw" | __handle # shellcheck disable=SC2181 -if [ "$?" -ne 0 ] || [ -n "$err" ]; then +if [ "$?" -eq 0 ]; then + notify-send \ + -a secretmenu \ + -i "${ico}" \ + 'secretmenu: secret copied' \ + 'will be removed after next paste' +else notify-send \ -a passmenu \ -i "${ico}" \ -c error \ 'secretmenu: failed :(' \ - "${err}" + "check stderr for details" exit 1 fi - -notify-send \ - -a secretmenu \ - -i "${ico}" \ - 'secretmenu: secret copied' \ - 'will be removed after next paste' -- cgit 1.4.1