pfr As it turns out, the geometry is not set using quirks and this setting is actually useless

Your config 😉
When I was using spectrwm, I'd assign a quirk simply to make the window floating.
Then I'd assign the geometry by appending it to the command in the binding.

So yes, what you wrote makes sense.

rvp post your WM's config file (relevant bits only) and passmenu.sh as they are now.

The only relevant lines from my ~/.spectrwm.conf

program[passmenu]       = ~/.config/spectrwm/./passmenu.sh $dmenu_bottom -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected
bind[passmenu]          = MOD+Shift+p
...
quirk[Pinentry:xterm]   = FLOAT + FOCUSPREV

The pass menu script:

#!/usr/bin/env bash
 
shopt -s nullglob globstar
 
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[@]}" | dmenu "$@")

[[ -n $password ]] || exit

if [[ $typeit -eq 0 ]]; then
        xterm -class Pinentry -e pass show -c "$password" 2>/dev/null
else
        pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } |
                xdotool type --clearmodifiers --file -
fi

And of course in my ~/.Xresources

! Passmenu Pinentry
Pinentry*faceName: xft:Pragmata:pixelsize=10
Pinentry*internalBorder: 7
Pinentry*geometry: 78x15
  • rvp replied to this.

    pfr

    program[passmenu]       = ~/.config/spectrwm/./passmenu.sh $dmenu_bottom -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected

    Use this instead and roll back to the original passmenu.sh in post #8:

    program[passmenu]       = xterm -class Pinentry -e $HOME/.config/spectrwm/passmenu.sh $dmenu_bottom -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected

    Thought, I don't understand who the trailing options are for. Some of them seem like they're for xterm, some not, and some don't make sense for it.

    They way I've written it now, all options apart from -e are passed to passmenu.sh (which doesn't use them--or, are they being consumed by dmenu?) as done before.

    • pfr replied to this.
    • pfr likes this.

      rvp
      Yeah, all the trailing options are just style options for dmenu which is necessary if I want the same fonts etc for passmenu

      Adding xterm -class Pinentry -e to the beginning of the program[passmenu] line wont work (actually, it doesn't work) as it begins the sequence with an xterm rather than beginning with passmenu.sh piped through dmenu.

      I need to first select which password I'd like to copy to my clipboard from dmenu, then, and only if necessary, open pinentry-curses for my passphrase. I say only if necessary because once I have entered my passphrase, it holds onto it (persists) for a minute or so, meaning I dont need to enter it each time I want to copy a password.
      That's why I've been trying to edit the passmenu script, because this works on my Linux machine with Gnome using gnome-keyring.

      If I could figure out at which point gnome-keyring is called, and by which program, then perhaps I could set it to call pinentry-cureses and specify xterm -class Pinentry -e [pinentry-curses].... etc..

      So where in the chain does pinentry get triggered? gpg-agent perhaps?

      • rvp replied to this.

        pfr Adding xterm -class Pinentry -e to the beginning of the program[passmenu] line wont work (actually, it doesn't work) as it begins the sequence with an xterm rather than beginning with passmenu.sh piped through dmenu.

        I'm afraid you've lost me. This should've worked as follows:

        1. MOD + Shift + p triggers xterm -e.
        2. xterm runs passmenu.sh inside a pseudo-tty--which is what's needed for pass to work.
        3. passmenu.sh gathers a list of .gpg files--which are site labels--belonging to pass and echoes them to dmenu.
        4. dmenu creates a menu from input read from stdin.
        5. You choose which site's password you want to extract.
        6. Site name is passed to pass which runs inside xterm.
        7. pass contacts gpg-agent to retrieve password (PIN) for decryption of chosen site.
        8. gpg-agent runs pinentry-curses to ask PIN for decryption. (All of this is running inside the xterm we've launched.)
        9. pinentry-curses creates a dialog box, reads PIN, hands back PIN to gpg-agent; which in turn sends it on to pass.
        10. pass uses PIN to decrypt site file which holds password; reads this password and either :
          a) copies this to the clipboard -- the -c option, or,
          b) writes password to xdotool, which simulates a user typing the password into some input box.

        Which step is failing here?

        If you want passmenu.sh to be run directly on MOD + Shift + p instead of via xterm you can do it by splitting the original passmenu.sh file into 2 pieces. Otherwise, the shell quoting needed to run pass inside xterm becomes a little hairy.

        This is piece one, passmenu.sh. Make it executable and call this without xterm -e:

        #!/usr/bin/env bash
        
        shopt -s nullglob globstar
        
        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[@]}" | dmenu "$@")
        
        [[ -n $password ]] || exit
        
        xterm -class Pinentry -e ~/bin/run-pass.sh "$typeit" "$password"

        Piece two, run-pass.sh, gets called from passmenu.sh. Put this file in ~/bin; make it executable chmod 755 ~/bin/run-pass.sh:

        #!/usr/bin/env bash
        
        if [[ $# -ne 2 ]]
        then	printf '%s: needs 2 arguments\n' $0 1>&2
        	exit 1
        fi
        
        typeit=$1
        password=$2
        
        if [[ $typeit -eq 0 ]]; then
        	pass show -c "$password" 2>/dev/null
        else
        	pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } |
        		xdotool type --clearmodifiers --file -
        fi

        This works slightly differently from what I've outlined above, but, you should be able to figure it out easily. See if this works.

        • pfr replied to this.
        • pfr likes this.

          rvp I'm afraid you've lost me.

          No I haven't, you've got it.
          I tried your 'split script' solution. This does launch passmenu but nothing pop's up after selecting a password and therefore nothing gets copied to the clipboard.

          I'm curious why I need to put it in ~/bin rather than /usr/local/bin Anyway, I created the directory /home/$USER/bin/ anyway (I actually tried both dir's, neither worked)

          • rvp replied to this.

            pfr This does launch passmenu but nothing pop's up after selecting a password

            1. Is the run-pass.sh script executable? chmod 755 ~/bin/run-pass.sh
            2. Splitting makes stand-alone testing possible. Test run-pass.sh on its own:
              xterm -class Pinentry -e ~/bin/run-pass.sh 0 DMENU_SITE_LABEL
              The above should copy the password to clipboard. (Make sure, that xclip(1) is installed, as the pass man-page for the -c option says.)
              xterm -class Pinentry -e ~/bin/run-pass.sh 1 DMENU_SITE_LABEL
              This one, OTOH, will simulate key input using xdotool. Make sure this is installed too.

            pfr I'm curious why I need to put it in ~/bin rather than /usr/local/bin

            You can put it where you want.

            • pfr replied to this.
            • pfr likes this.

              rvp
              Yes, run-pass.sh executable and yes, I have both xclip and xdotool installed. Also, I've moved the run-pass.sh script to /usr/local/bin/ which I prefer.

              Running run-pass.sh on its own with xterm -class Pinentry -e /usr/local/bin/run-pass.sh 0 DMENU_SITE_LABEL briefly opens an xterm then exits immediately.
              Running xterm -class Pinentry -e /usr/local/bin/run-pass.sh 1 DMENU_SITE_LABEL does the same. I'm unsure what is meant to be copied to the clipboard at this point without specifying a .gpg file

              • rvp replied to this.

                pfr briefly opens an xterm then exits immediately

                Use this as a debug run-pass.sh:

                #!/usr/bin/env bash
                
                if [[ $# -ne 2 ]]
                then	printf '%s: needs 2 arguments\n' $0 1>&2
                read x
                	exit 1
                fi
                
                typeit=$1
                password=$2
                
                if [[ $typeit -eq 0 ]]; then
                echo "pass show"
                	pass show -c "$password"
                else
                echo "pass type"
                	pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } |
                		xdotool type --clearmodifiers --file -
                fi
                read x

                It waits until enter is pressed.
                What does this display?

                Note: DMENU_SITE_LABEL should be the name of some .gpg file, minus the .gpg extension. (ie. Whatever dmenu shows.)

                  rvp
                  Ok, so getting a little closer.. The script above forces the xterm window (the one that opens with pinentry) to stay open and now show's the usual message 'Copied password to clipboard. will clear in 45 seconds'

                  While this window is open, my password is copied to xclip and I can paste it where needed. However, If I close this window, even before the 45 seconds is up, this somehow revokes it and clears the clipboard.

                    pfr However, If I close this window, even before the 45 seconds is up, this somehow revokes it and clears the clipboard.

                    That sounds like the correct behaviour. If you close the window, the program is terminated and it clears the clipboard before it dies.

                    If you want to be able to close the window, or, press ENTER and make the program disappear, and still retain the password for 45 secs, then that's a new feature, I think--one you'll have to request from the developer of pass. He'll have to add code to fork(2) a new background process to handle the clipboard clearing while the main instance exits on ENTER, or somesuch.

                    pfr The script above forces the xterm window (the one that opens with pinentry) to stay open and now show's the usual message 'Copied password to clipboard. will clear in 45 seconds'

                    Hmm. Are you saying that without the read x at the end, pass would've immediately exited? Doesn't it open an input box for the decryption PIN? I don't have pass installed, but, this behaviour doesn't make sense to me. I can understand it exiting (and the xterm window closing) after waiting for 45 seconds.

                    • pfr replied to this.

                      rvp If you want to be able to close the window, or, press ENTER and make the program disappear, and still retain the password for 45 secs, then that's a new feature, I think--one you'll have to request from the developer of pass. He'll have to add code to fork(2) a new background process to handle the clipboard clearing while the main instance exits on ENTER, or somesuch.

                      Ok, will see what I can do.

                      rvp Hmm. Are you saying that without the read x at the end, pass would've immediately exited? Doesn't it open an input box for the decryption PIN? I don't have pass installed, but, this behavior doesn't make sense to me. I can understand it exiting (and the xterm window closing) after waiting for 45 seconds.

                      Yes. Upon removing read x, on the first instance obviously, the pinentry window opens, but once you enter the passphrase the window closes, also clearing the clipboard. As opposed to having read x in the script, the window stays open until it is closed manually, and the password is kept on the clipboard for 45 seconds.

                      • rvp replied to this.

                        pfr Upon removing...the pinentry window opens, but once you enter the passphrase the window closes, also clearing the clipboard

                        Hm. This behaviour only makes sense if pass was doing something like what I outlined before; but, the clearing of the password doesn't make sense. I'll look into the source--when I get the time. For now, just keep the wndow around and press ENTER to close it.

                        BTW, since you're running under X, wouldn't it be easier to set ~/.gnupg/gpg-agent.conf to run pinentry-gtk and bypass all these minor irritations entirely?

                          rvp since you're running under X, wouldn't it be easier to set ~/.gnupg/gpg-agent.conf to run pinentry-gtk and bypass all these minor irritations entirely?

                          🙂

                          • pfr replied to this.

                            pfr As opposed to having read x in the script, the window stays open until it is closed manually,

                            Just realized: since both the scripts run under bash, you can change the unconditional read, read x to a read with timeout: read -t 45 x. The window will then close when the clipboard clears.

                            pfr /usr/pkg/share/themes
                            System wide configuration in /usr/pkg/share/gtk-2.0/gtkrc, user configuration ~/.gtkrc-2.0

                            • pfr likes this.

                            pfr Upon removing read x, on the first instance obviously, the pinentry window opens, but once you enter the passphrase the window closes, also clearing the clipboard.

                            Update: patched patch!
                            Turns out pass is written in bash (I had assumed C) and it wasn't too hard to go through it and find the problem. There is a bug in pass with non-interactive shells.

                            Patch:

                            --- pass.orig	2020-07-17 13:45:22.000000000 +0000
                            +++ pass	2020-10-06 23:08:41.159955217 +0000
                            @@ -157,6 +157,12 @@
                             	local sleep_argv0="password store sleep on display $DISPLAY"
                             	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5
                             	local before="$(xclip -o -selection "$X_SELECTION" 2>/dev/null | $BASE64)"
                            +	# Explicitly ignore SIGHUP because "disown" only works in interactive shells.
                            +	# Otherwise, in non-interactive cases like "xterm -e passmenu" or "xterm -e pass",
                            +	# which is needed to supply a terminal for pinentry when the script is called from
                            +	# a GUI, bash will kill xclip when the script finishes ie. before $CLIP_TIME has
                            +	# elapsed.
                            +	trap '' HUP
                             	echo -n "$1" | xclip -selection "$X_SELECTION" || die "Error: Could not copy data to the clipboard"
                             	(
                             		( exec -a "$sleep_argv0" bash <<<"trap 'kill %1' TERM; sleep '$CLIP_TIME' & wait" )
                            @@ -173,7 +179,7 @@
                             		qdbus org.kde.klipper /klipper org.kde.klipper.klipper.clearClipboardHistory &>/dev/null
                             
                             		echo "$before" | $BASE64 -d | xclip -selection "$X_SELECTION"
                            -	) >/dev/null 2>&1 & disown
                            +	) >/dev/null 2>&1 &
                             	echo "Copied $2 to clipboard. Will clear in $CLIP_TIME seconds."
                             }

                            You can either use the original passmenu.sh or the 2-piece version (both called via xterm -e ... as before to supply a terminal). They both do the same thing, just their aesthetics differ (with the first you get a blank screen before pinentry when selecting items; with the other you don't). You won't need the read x pauses now.

                            OK...back to sleep. (Woke up for a whizz and this started nagging, so I had to sit down and do something about it.)

                            • pfr replied to this.
                            • pfr likes this.