gopass icon indicating copy to clipboard operation
gopass copied to clipboard

Pinentry error `ERR 83918950 Inappropriate ioctl for device`

Open kfken opened this issue 3 years ago • 17 comments

Summary

When setting up a new age backend on Kali Linux 2021.1 with gopass init --crypto age I get:

Error: Failed to initialize store: failed to read user input: pinentry Error: unexpected response: ERR 83918950 Inappropriate ioctl for device <Pinentry>

Steps To Reproduce

gopass init --crypto age Follow setup prompts Enter password for your new keypair: Retype password for your new keypair: ⏳ This can take a long time. If you get impatient see https://github.com/gopasspw/gopass/b lob/master/docs/entropy.md Continue? [Y/n/q]: 🔑 Please enter your passphrase to unlock the age keyring 2021/03/25 11:24:59 failed to create new private key: failed to create new private key: pin entry Error: unexpected response: ERR 83918950 Inappropriate ioctl for device <Pinentry>

Expected behavior

Accepts PIN and creates new gopass store

Environment

  • OS: Kali Linux 2021.1
  • OS version: Linux kali 5.10.0-kali3-amd64 #1 SMP Debian 5.10.13-1kali1 (2021-02-08) x86_64 GNU/Linux
  • gopass Version: 1.12.4
  • Installation method: Downloaded amd64 tar.tz from Releases

Additional context

From the debug log:

2021/03/25 11:25:32.636902 age/keyring.go:43    age.(*Age).genKey       No native age key found. Generating ... 
2021/03/25 11:25:32.637016 age/keyring.go:85    age.(*Age).loadKeyring  no password callback found, redirecting to askPass                                            
2021/03/25 11:25:32.637069 age/keyring.go:94    age.(*Age).loadKeyring  can't decrypt keyring at /root/.config/gopass/age-keyring.age: open /root/.config/gopass/age-keyring.age: no such file or directory                                                                      
2021/03/25 11:25:32.637107 age/keyring.go:66    age.(*Age).generateIdentity     failed to load existing keyring from /root/.config/gopass/age-keyring.age: open /root/.config/gopass/age-keyring.age: no such file or directory                                                  
2021/03/25 11:25:32.637143 age/keyring.go:70    age.(*Age).generateIdentity     no existing keyring, creating new one                                                                 
2021/03/25 11:25:32.637212 age/keyring.go:118   age.(*Age).saveKeyring  no password callback found, redirecting to askPass                                                            
2021/03/25 11:25:32.637303 age/askpass.go:63    age.(*askPass).Passphrase       Value for /root/.config/gopass/age-keyring.age not found in cache                                     
2021/03/25 11:25:32.637400 gpgconf/gpgconf.go:20        gpgconf.Path    /usr/bin/gpgconf [gpgconf]                                                                                    
2021/03/25 11:25:32.680771 pinentry/pinentry.go:130     pinentry.(*Client).GetPin       message: "S ERROR curses.isatty 83918950 "                                                    
2021/03/25 11:25:32.681314 action/errors.go:59  action.ExitError        failed to read user input: pinentry Error: unexpected response: ERR 83918950 Inappropriate ioctl for device <Pinentry> - stacktrace: %!v(MISSING)  

Using ncurses pinentry, however thought this shouldn't matter since the fallback GetPin() would takeover if there was an error.

update-alternatives --config pinentry
There are 2 choices for the alternative pinentry (providing /usr/bin/pinentry).

Selection    Path                      Priority   Status
  0            /usr/bin/pinentry-gnome3   90        auto mode
* 1            /usr/bin/pinentry-curses   50        manual mode
  2            /usr/bin/pinentry-gnome3   90        manual mode

kfken avatar Mar 25 '21 15:03 kfken

This is the same (useless) error I've been seeing on MacOS with a recent pinentry-curses.

dominikschulz avatar Mar 25 '21 15:03 dominikschulz

@kfken Could you please provide the output of gpgconf? Unfortunately we don't seem to log that in the debug log.

dominikschulz avatar Mar 25 '21 16:03 dominikschulz

Also: did you set export GPG_TTY=$(tty)?

dominikschulz avatar Mar 25 '21 16:03 dominikschulz

FYI: the cli fallback will only be used if pinentry fails to initialize (usually due to the binary not being available). But this error happens when calling the GetPin method.

dominikschulz avatar Mar 25 '21 16:03 dominikschulz

Btw. I can reproduce the error when manually changing my pinentry (with update-alternatives --config pinentry) to pinentry-curses. With pinentry-gnome3 it all works.

Using the gpg backend with pinentry-curses works. With pinentry-gnome3 both gpg and age work for me.

dominikschulz avatar Mar 25 '21 16:03 dominikschulz

Using the gpg backend with pinentry-curses works. With pinentry-gnome3 both gpg and age work for me.

Same here. I didn't want to use gnome for other reasons, so I had set curses. After removing the pinentry symlink, the fallback to GetPin() worked and I was able to create the store successfully.

I did have export GPG_TTY=$(tty) and pinentry:Passphrase Entry:/usr/bin/pinentry in gpgconf.

For the time being, that workaround is good for me, although would be nice to not have to rely on gnome for age backend.

Thanks again (and awesome work on this project)!

kfken avatar Mar 25 '21 17:03 kfken

Thanks!

I'd really like to figure out if this is a gopass / pinentry client issue or another strange gpg issue, but for the time being I'm out of ideas.

Let's keep this open in case anyone else encounters the same issue or has some idea what's going on.

dominikschulz avatar Mar 25 '21 18:03 dominikschulz

Ran into a similar-seeming issue:

  • Using yubikey-agent (which relies on gopass's pinentry functionality under the hood)
  • With either pinentry-tty or pinentry-curses as the selected pinentry executable.

The problem is that pinentry tries to treat something that's not a TTY as a TTY:

# strace -f yubikey-agent with pinentry-tty
<mountains of output ...>
[pid 10429] ioctl(0, TCGETS <unfinished ...>       
[pid 10259] futex(0x7810d8, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>                            
[pid 10429] <... ioctl resumed>, 0x7ffea979f870) = -1 ENOTTY (Inappropriate ioctl for device)
<more output ...>
# strace -f yubikey-agent, with pinentry-curses
<mountains of output ...>
[pid 12914] ioctl(0, TCGETS, 0x7ffecb3e04c0) = -1 ENOTTY (Inappropriate ioctl for device)    
[pid 12914] write(4, "S ERROR curses.isatty 83918950 ", 31) = 31
<more output ...>

Note that the bad ioctls pertain to fd 0 / stdin, and that both pinentry-tty and pinentry-curses assume that they should use stdin as the TTY to interact with if the --ttyname command-line option is absent and the client didn't provide OPTION ttyname=/path/to/tty. Presumably, the not-a-TTY stream in question is the pipe that gopass sets up as pinentry's stdin.

Note also that I (unsurprisingly) don't hit an ioctl issue when using pinentry-gtk2, pinentry-qt, and other graphical pinentry implementations.

tomeon avatar Jul 06 '21 22:07 tomeon

Summary

I can reproduce the error already at the first prompt for a password.

Steps To Reproduce

$ gopass init --crypto age
[...]
No existing age identities found. Do you want to generate a new one? [Y/n/q]: y
Please enter your passphrase to unlock the age keyring

Error: Failed to initialize store: failed to read user input: pinentry (/usr/local/bin/pinentry) error: unexpected response: ERR 83918950 Inappropiate ioctl for device <Pinentry>

Environment

OS: OpenBSD 7.0 -current gopass Version: gopass 1.12.7 go1.17 openbsd amd64 Installation method: Installed from ports

huhndev avatar Sep 24 '21 19:09 huhndev

I get the same error on Arch Linux:

$ gopass init --crypto age
🍭 Initializing a new password store ...
🔑 Searching for usable private Keys ...
⚠ Hint: Use 'gopass init <subkey> to use subkeys!'
🔑 No existing age identities found. Do you want to generate a new one? [Y/n/q]: 
🔑 Please enter your passphrase to unlock the age keyring

Error: Failed to initialize store: failed to read user input: pinentry (/usr/bin/pinentry) error: unexpected response: ERR 83918950 Inappropriate ioctl for device <Pinentry>
$ paru -Q pinentry gopass
pinentry 1.1.1-1
gopass 1.12.8-1

Also, how should one specify an existing age key?

Mrfiregem avatar Oct 18 '21 01:10 Mrfiregem

Specifying an existing age key isn't support yet (I think). But I think this is something the age backend should eventually support. I'd be happy to accept a PR for that.

dominikschulz avatar Oct 30 '21 09:10 dominikschulz

FTR: Keybase seems to have a similar issue, open since 2016 😢

dominikschulz avatar Jan 18 '22 11:01 dominikschulz

And they also have another issue where the solution seems to really "just" be to have export GPG_TTY=$(tty)

AnomalRoil avatar Jan 18 '22 11:01 AnomalRoil

$ cat .kshrc                                                                                                                                                                                                             
[...]
export GPG_TTY=$(tty)
[..]
$ env                 
[...]
GPG_TTY=/dev/ttyp2
[...]
$ gopass init --crypto age
🍭 Initializing a new password store ...
🔑 Searching for usable private Keys ...
⚠ Hint: Use 'gopass init <subkey> to use subkeys!'
🔑 No existing age identities found. Do you want to generate a new one? [Y/n/q]: Y

Error: Failed to initialize store: failed to read user input: pinentry (/usr/local/bin/pinentry) error: unexpected response: ERR 83918950 Inappropriate ioctl for device <Pinentry>

Environment

OS: OpenBSD 7.0 -current gopass version: gopass 1.13.0 go1.17.5 openbsd amd64 pinentry version: pinentry-1.1.1 Installation method: Installed from OpenBSD ports

huhndev avatar Jan 18 '22 14:01 huhndev

I got the same issue, i'm on a clean install on WSL and the GUI to ask the passphrase is only show when I use pinentry-qt

$GPG_TTY is exported.

❯ echo $GPG_TTY
/dev/pts/4

SirMishaa avatar Oct 27 '22 11:10 SirMishaa

After updating export GPG_TTY=$(tty) one must tell GPG agent about it with gpg-connect-agent updatestartuptty /bye. So, pinentry will pop up on this tty.

andy-shev avatar Aug 25 '23 03:08 andy-shev

Same issue on a fresh install of Ubuntu 22.04.3 LTS. installed gopass through apt-get from https://packages.gopass.pw/repos/gopass source. Using only age crypto backend. export GPG_TTY=$(tty) solved the issue. Not sure why though, I am not using the gpg backend.

r3mi avatar Jan 21 '24 14:01 r3mi