Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Trying to make a pinentry switcher through an env variable
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Gentoo Chat
View previous topic :: View next topic  
Author Message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Sat Jan 19, 2019 9:44 pm    Post subject: Trying to make a pinentry switcher through an env variable Reply with quote

Hey everyone,
I'm trying to make a rofi pinentry script but I seem to be running into some trouble.
I can't seem to find the answers online and was hoping someone here may know a bit about this topic.

First I'm trying to build a pinentry toggle which changes which pinentry it uses based on an environment variable.
I want it to not always use the rofi-pinentry script and only certain scripts should use it.
This stackexchange post mentions thats its possible with a script that they provide.
For now I modified the script to work with the gentoo symlink for pinentry so it looks something like this.
Code:

#!/bin/sh
# choose pinentry depending on PINENTRY_USER_DATA
# this *only works* with gpg 2
# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802020
 
case $PINENTRY_USER_DATA in
    qt)
        exec /usr/bin/pinentry-qt4 "$@"
        ;;
    none)
        exit 1 # do not ask for passphrase
        ;;
    *)
        exec /usr/bin/pinentry "$@"
        ;;
esac

So this checks $PINENTRY_USER_DATA to see which pinentry to use.
For now, this script should switch between using tty (what I have eselect set to) and pinentry-qt4.
However this doesn't seem to work when I run the program passwordstore, I get gpg:decryption failed: no secret key
Note, I also do have pinentry-program option set in gpg-agent.conf to use this script.

Thanks,
zamlz
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Sat Jan 19, 2019 11:13 pm    Post subject: Reply with quote

Add the line below to your pinentry script, just before the case statement:
Code:
echo "PINENTRY_USER_DATA=<${PINENTRY_USER_DATA}>, options=<$@>" >>/tmp/pinentry.log

Run passwordstore once and post the contents of the file /tmp/pinentry.log.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Sat Jan 19, 2019 11:38 pm    Post subject: Reply with quote

mike155 wrote:
Add the line below to your pinentry script, just before the case statement:
Code:
echo "PINENTRY_USER_DATA=<${PINENTRY_USER_DATA}>, options=<$@>" >>/tmp/pinentry.log

Run passwordstore once and post the contents of the file /tmp/pinentry.log.

Unfortunately, that file isn't even being created O_O
I double checked and made sure that the following line was there.
Code:
pinentry-program ~/lib/rofi/pinentry-toggler.sh

Furthermore, I can manually run the the script and it seem to work (i can call GETPIN, etc).

I'm really confused why password store seems to be having trouble here.

EDIT: Just tested editing my gpg key since it also uses pinentry. Turns out that doesn't work either. Guess its not a problem with password store but gnupg?
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Sat Jan 19, 2019 11:58 pm    Post subject: Reply with quote

Run passwordstore with strace
Code:
strace -f -o /tmp/strace.log passwordstore

Look at /tmp/strace.log and try to find out what passwordstore did. Search for 'exec'.
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Sun Jan 20, 2019 12:12 am    Post subject: Reply with quote

Does the program actually understand expanding ~ to a home directory? Your shell handles that in interactive mode. This tool may be treating that as a literal path, which would then fail.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Sun Jan 20, 2019 1:58 am    Post subject: Reply with quote

Hu wrote:
Does the program actually understand expanding ~ to a home directory? Your shell handles that in interactive mode. This tool may be treating that as a literal path, which would then fail.


WOW. I feel really dumb now lol. Thanks for the help though, that made the script work. I can now switch between qt and tty.

Now I need to figure out whats wrong with my rofi pinentry script.
Should I make a new forum post for that or continue it here?
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Sun Jan 20, 2019 1:59 am    Post subject: Reply with quote

Here is fine.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Sun Jan 20, 2019 2:27 am    Post subject: Reply with quote

Alright so remember the script I posted a couple posts ago?
I've added an option for my rofi script.

Code:
#!/bin/sh
# choose pinentry depending on PINENTRY_USER_DATA
# this *only works* with gpg 2
# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802020

echo "PINENTRY_USER_DATA=<${PINENTRY_USER_DATA}>, options=<$@>" >> \
    /tmp/pinentry.log

case $PINENTRY_USER_DATA in
    qt)
        exec /usr/bin/pinentry-qt4 "$@"
        ;;
    rofi)
        exec $HOME/lib/rofi/pinentry-rofi "$@"
        ;;
    none)
        exit 1 # do not ask for passphrase
        ;;
    *)
        exec /usr/bin/pinentry "$@"
        ;;
esac


when I set the variable to rofi, password store hangs. It doesn't actually output anything. I imagine for this I should use the strace command.
Here is the details of the pinentry-rofi script.

Code:
#!/bin/sh

rofi="rofi -dmenu -input /dev/null -password -lines 0"

echo "OK Please go ahead"
while read cmd rest; do

    if [ -z "$cmd" ]; then
        continue;
    fi

    case "$cmd" in
        \#*)
            echo "OK"
            ;;

        GETINFO)
            case "$rest" in
                flavor)
                    echo "D qt"
                    ;;
                pid)
                    echo "D $$"
                    ;;
            esac
            ;;

        SETDESC)
            rofi="$rofi -mesg '$rest'"
            echo "OK"
            ;;

        SETPROMPT)
            rofi="$rofi -p $rest"
            echo "OK"
            ;;

        GETPIN)
            _PP=$($rofi)
            if [ -z "$_PP" ]; then
                echo "ERR 83886179 Operation cancelled <rofi>"
            else
                echo "D $_PP"
            fi
            ;;

        BYE)
            echo "OK"
            exit 0
            ;;

        *)
            echo "OK"
            ;;
    esac
done

_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Sun Jan 20, 2019 2:48 am    Post subject: Reply with quote

Add some 'echo' statements to your script and try to understand what happens:

after line 3 ('rofi='):
Code:
echo "pinentry-rofi started" >>/tmp/pinentry-rofi.log

after 'while read cmd rest; do ':
Code:
echo "cmd=${cmd}" >>/tmp/pinentry-rofi.log

after 'GETPIN)'
Code:
echo "GETPIN, calling rofi: ${rofi}" >>/tmp/pinentry-rofi.log

after 'BYE)'
Code:
echo "BYE, exiting" >>/tmp/pinentry-rofi.log

after the last line:
Code:
echo "EOF, exiting" >>/tmp/pinentry-rofi.log

Then run passwordstore and post the file /tmp/pinentry-rofi.log. WARNING: before you post the file, look at it and replace sensitive data like usernames or passwords with XXXXXX!
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Mon Jan 21, 2019 12:14 am    Post subject: Reply with quote

Alright I've done what you've requested and here are the results.

Code:
pinentry-rofi started
cmd=OPTION pinentry-user-data=rofi
cmd=OPTION no-grab
cmd=OPTION ttyname=/dev/pts/0
cmd=OPTION ttytype=xterm-256color
cmd=OPTION lc-ctype=en_US.utf8
cmd=OPTION lc-messages=en_US.utf8
cmd=OPTION allow-external-password-cache
cmd=OPTION default-ok=_OK
cmd=OPTION default-cancel=_Cancel
cmd=OPTION default-yes=_Yes
cmd=OPTION default-no=_No
cmd=OPTION default-prompt=PIN:
cmd=OPTION default-pwmngr=_Save in password manager
cmd=OPTION default-cf-visi=Do you really want to make your passphrase visible on the screen?
cmd=OPTION default-tt-visi=Make passphrase visible
cmd=OPTION default-tt-hide=Hide passphrase
cmd=OPTION touch-file=/run/user/1000/gnupg/S.gpg-agent
cmd=OPTION owner=30149 andromeda
cmd=GETINFO flavor


It seems its just hanging at the GETINFO flavor command.
For that I am returning qt (no particular reason why). Should I not be doing that?

EDIT: I've tried with other flavors names (including rofi) and also removing the option for flavor. I don't see any changes in it's behavior.
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Mon Jan 21, 2019 12:49 am    Post subject: Reply with quote

The input field separator is wrong.

1) Replace the line
Code:
echo "cmd=${cmd}" >>/tmp/pinentry-rofi.log
with
Code:
echo "cmd=<${cmd}>, rest=<${rest}>" >>/tmp/pinentry-rofi.log

an re-run your program. You will see that the whole line is stored to cmd, and that variable rest is empty.

2) In order to fix that, add the line below after line 2
Code:
IFS=' '

Please remove /tmp/pinentry-rofi.log, rerun the program and post the output.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Mon Jan 21, 2019 1:26 am    Post subject: Reply with quote

I should have mentioned that I took some creative liberties in your instructions earlier.
I made,
Code:
echo "cmd=${cmd}" >>/tmp/pinentry-rofi.log

into
Code:
echo "cmd=${cmd} ${rest}" >>/tmp/pinentry-rofi.log

But I still had hope and tried your new edit as well.
Code:
echo "cmd=<${cmd}>, rest=<${rest}>" >>/tmp/pinentry-rofi.log


Unfortunately, it is correctly being stored in the $rest variable.

Code:
pinentry-rofi started
cmd=<OPTION> rest=<pinentry-user-data=rofi>
cmd=<OPTION> rest=<no-grab>
cmd=<OPTION> rest=<ttyname=/dev/pts/0>
cmd=<OPTION> rest=<ttytype=xterm-256color>
cmd=<OPTION> rest=<lc-ctype=en_US.utf8>
cmd=<OPTION> rest=<lc-messages=en_US.utf8>
cmd=<OPTION> rest=<allow-external-password-cache>
cmd=<OPTION> rest=<default-ok=_OK>
cmd=<OPTION> rest=<default-cancel=_Cancel>
cmd=<OPTION> rest=<default-yes=_Yes>
cmd=<OPTION> rest=<default-no=_No>
cmd=<OPTION> rest=<default-prompt=PIN:>
cmd=<OPTION> rest=<default-pwmngr=_Save in password manager>
cmd=<OPTION> rest=<default-cf-visi=Do you really want to make your passphrase visible o
cmd=<OPTION> rest=<default-tt-visi=Make passphrase visible>
cmd=<OPTION> rest=<default-tt-hide=Hide passphrase>
cmd=<OPTION> rest=<touch-file=/run/user/1000/gnupg/S.gpg-agent>
cmd=<OPTION> rest=<owner=11201 andromeda>
cmd=<GETINFO> rest=<flavor>


EDIT: OMG I figured it out. I wasn't printing OK on a newline after printing the flavor.
Odd, since the ruby script I was basing this on didn't do it either? In any case, It seems I'm onto something now. Its stuck on another GETINFO so now I just need to implement whatever the program wants.
I hope that'll fix it. I'll come back if anything new comes up.

Thanks for all the help so far!
_________________
AI/ML/Robotics/Linux - zamlz


Last edited by zamlz on Mon Jan 21, 2019 1:31 am; edited 1 time in total
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21489

PostPosted: Mon Jan 21, 2019 1:27 am    Post subject: Reply with quote

As a general tip, you should handle unexpected input values. In this case, if flavor is not on your expected list, you ignore the inquiry and do not send anything back to the peer. You should at least log it as an unexpected event, and if possible, respond to it. The appropriate response varies, but could be to send an error report back or to exit your script with an error status.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Mon Jan 21, 2019 2:18 am    Post subject: Reply with quote

alright I'm back again with some more weird stuff. Heres the current output.

Code:
pinentry-rofi started
cmd=<OPTION> rest=<pinentry-user-data=rofi>
cmd=<OPTION> rest=<no-grab>
cmd=<OPTION> rest=<ttyname=/dev/pts/0>
cmd=<OPTION> rest=<ttytype=xterm-256color>
cmd=<OPTION> rest=<lc-ctype=en_US.utf8>
cmd=<OPTION> rest=<lc-messages=en_US.utf8>
cmd=<OPTION> rest=<allow-external-password-cache>
cmd=<OPTION> rest=<default-ok=_OK>
cmd=<OPTION> rest=<default-cancel=_Cancel>
cmd=<OPTION> rest=<default-yes=_Yes>
cmd=<OPTION> rest=<default-no=_No>
cmd=<OPTION> rest=<default-prompt=PIN:>
cmd=<OPTION> rest=<default-pwmngr=_Save in password manager>
cmd=<OPTION> rest=<default-cf-visi=Do you really want to make your passphrase visible on the screen?>
cmd=<OPTION> rest=<default-tt-visi=Make passphrase visible>
cmd=<OPTION> rest=<default-tt-hide=Hide passphrase>
cmd=<OPTION> rest=<touch-file=/run/user/1000/gnupg/S.gpg-agent>
cmd=<OPTION> rest=<owner=22443 andromeda>
cmd=<GETINFO> rest=<flavor>
cmd=<GETINFO> rest=<version>
cmd=<GETINFO> rest=<ttyinfo>
cmd=<GETINFO> rest=<pid>
cmd=<SETKEYINFO> rest=<n/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX>
cmd=<SETDESC> rest=<Please enter the passphrase to unlock the OpenPGP secret key XXX XXX XXX XXX>
cmd=<SETPROMPT> rest=<Passphrase:>
cmd=<GETPIN> rest=<>
GETPIN, calling rofi: rofi -dmenu -input /dev/null -password -lines 0 -p Passphrase
cmd=<BYE> rest=<>
BYE, exiting


It doesn't even manage to open up rofi, but it gets through the whole script (weird).
Password store doesn't hang anymore, but instead I get this message printed to stdout

Code:
gpg: decryption failed: No secret key


I tried running just the rofi command that it produced to make sure there were no errors and it seems to work fine.

Code:
rofi -dmenu -input /dev/null -password -lines 0 -p Passphrase


Secondly, I tried running the pinentry-rofi program manually and entered the same commands to see if it worked and it did and it opened up rofi correctly.

So not sure why its not working with password store here.
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Mon Jan 21, 2019 3:37 am    Post subject: Reply with quote

1) Add the directory in which the rofi executable is installed to line 3 (I assume it's /usr/bin - change it if rofi is installed in a different directory)
Code:
rofi="/usr/bin/rofi -dmenu -input /dev/null -password -lines 0"

2) Your script won't work if the prompt or the description contains spaces or special characters. The generated rofi statement would look like:
Code:
/usr/bin/rofi -dmenu -input /dev/null -password -lines 0 -p this $is my prompt

Do you see the problem? Modify your script so that the parameters added to variable 'rofi' after SETDESC) and SETPROMPT) will be surrounded by quotes:
Code:
/usr/bin/rofi -dmenu -input /dev/null -password -lines 0 -p 'this $is my prompt'

While you're at it: what will happen if the calling program sends 2 SETPROMPT or SETDESC requests?

3) Add the line below directly after the rofi call ( _PP=$($rofi) ):
Code:
echo "rofi return values: ERC=<$?>, _PP=<${_PP}>" >>/tmp/pinentry-rofi.log

It will write the error return code and the passphrase to the log file.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Mon Jan 21, 2019 5:21 am    Post subject: Reply with quote

Alright I've done all the suggestions you've asked and here is the output.
Oh I also added a line to see if rofi prints anything useful as well, it turns out it does.
Code:
_PP=$( $rofi >> /tmp/pinentry-rofi.log 2>&1 )

Code:
pinentry-rofi started
cmd=<OPTION> rest=<pinentry-user-data=rofi>
cmd=<OPTION> rest=<no-grab>
cmd=<OPTION> rest=<ttyname=/dev/pts/2>
cmd=<OPTION> rest=<ttytype=xterm-256color>
cmd=<OPTION> rest=<lc-ctype=en_US.utf8>
cmd=<OPTION> rest=<lc-messages=en_US.utf8>
cmd=<OPTION> rest=<allow-external-password-cache>
cmd=<OPTION> rest=<default-ok=_OK>
cmd=<OPTION> rest=<default-cancel=_Cancel>
cmd=<OPTION> rest=<default-yes=_Yes>
cmd=<OPTION> rest=<default-no=_No>
cmd=<OPTION> rest=<default-prompt=PIN:>
cmd=<OPTION> rest=<default-pwmngr=_Save in password manager>
cmd=<OPTION> rest=<default-cf-visi=Do you really want to make your passphrase visible on the screen?>
cmd=<OPTION> rest=<default-tt-visi=Make passphrase visible>
cmd=<OPTION> rest=<default-tt-hide=Hide passphrase>
cmd=<OPTION> rest=<touch-file=/run/user/1000/gnupg/S.gpg-agent>
cmd=<OPTION> rest=<owner=2054 andromeda>
cmd=<GETINFO> rest=<flavor>
cmd=<GETINFO> rest=<version>
cmd=<GETINFO> rest=<ttyinfo>
cmd=<GETINFO> rest=<pid>
cmd=<SETKEYINFO> rest=<n/XXXXX>
cmd=<SETDESC> rest=<Please enter the passphrase to unlock the OpenPGP secret key:XXXXXXXX>
cmd=<SETPROMPT> rest=<Passphrase:>
cmd=<GETPIN> rest=<>
GETPIN, calling rofi: /usr/bin/rofi -dmenu -input /dev/null -password -lines 0 -p 'Passphrase'

(process:2067): X11Helper-WARNING **: 21:14:45.761: Failed to open display: (null)

(process:2067): Rofi-WARNING **: 21:14:45.761: Connection has error
ROFI : ERC=<1>, _PP=<>
cmd=<BYE> rest=<>
BYE, exiting


It seems like rofi is having trouble finding the display. So this is easy to fix if I just write this in the script.
Code:
export DISPLAY=":0"

But that is in no way a good solution. Is there a command that can give me the display value?
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Mon Jan 21, 2019 11:23 am    Post subject: Reply with quote

1) For educational purposes:

Add the lines below to your script, just in front of the first echo statement
Code:
echo "----- set -------" >>/tmp/pinentry.log
set >>/tmp/pinentry.log
echo "----- export ----" >>/tmp/pinentry.log
export >>/tmp/pinentry.log
echo "------------" >>/tmp/pinentry.log

remove /tmp/pinentry.log, run your script manually and copy /tmp/pinentry.log to /tmp/a.

remove /tmp/pinentry.log, run passwordstore and copy /tmp/pinentry.log to /tmp/b.

Use an editor or a diff tool (diff or diffuse) and compare /tmp/a and /tmp/b. Do you see the difference between a and b? Look especially at PATH and DISPLAY. Is DISPLAY really missing in /tmp/b?

2) I would try to find out why the DISPLAY environment variable isn't defined when the script is called from passwordstore.

I'm not aware of a trick that can recover a missing DISPLAY environment variable. As a workaround, you could add the code below to your script
Code:
if test -z "${DISPLAY}"
then
    DISPLAY=":0"
    export DISPLAY
fi

But it's important to find out where and why the DISPLAY environment variable gets lost.
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Mon Jan 21, 2019 9:22 pm    Post subject: Reply with quote

Wow alright thats intersting. So script A does has the DISPLAY variable set (makes sense as Im just running the script from my shell).
Script B does not and ts probably for the this reason.
The way I'm running my rofi-pass is through a keybind in my window manager.
Also all my exports and PATH variables are all messed up which makes sense since they come from zsh.
Intersting...

In any case, Thank you so much for all the help mike155!
I owe you a beer!
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
zamlz
n00b
n00b


Joined: 22 Jul 2017
Posts: 42

PostPosted: Fri Feb 01, 2019 6:29 am    Post subject: Reply with quote

Alright so I found out that it turns out this may not work as planned.
On an Ubuntu system I use, it turns out the display variable is set to ":1"

For now, my fix is,
Code:
if [ -z "${DISPLAY}" ]; then
    if [ -n "$(uname -v | grep -i "UBUNTU")" ]; then
        export DISPLAY=":1"
    else
        export DISPLAY=":0"
    fi
fi


There has to be a cleaner solution. This one just urks me the wrong way.
_________________
AI/ML/Robotics/Linux - zamlz
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Gentoo Chat All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum