Page MenuHome GnuPG

gpg-agent works for gpg, but not ssh with pinentry-tty
Closed, ResolvedPublic

Description

Ok, the title is not very informative, but I could not formulate this better. Here is the actual problem:

I followed an Arch guide to set up gpg-agent to work as ssh-agent. My system is Archlinux and my gpg and other packages are up-to-date. I have one master key in my gpg and different subkeys for signing and authentication. When I have pinentry-program /usr/bin/pinentry-qt in my gpg-agent.conf then everything works fine for both signing git commits with sign key and ssh-ing to github with auth key - in both cases I get a qt pinentry window that asks my password and everything works as expected. So I presume my setup actually works.

However, when I use pinentry-program /usr/bin/pinentry-tty or pinentry-program /usr/bin/pinentry-curses then signing commits with gpg sign key works (I get either a simple or curses password prompt in my terminal and it works as expected), but ssh-ing breaks for some mysterious reason:

❯ ssh -T git@github.com
sign_and_send_pubkey: signing failed for RSA "(none)" from agent: agent refused operation
git@github.com: Permission denied (publickey).

Here is the relevant config options. GPG_TTY and other env variables are set to correct values:

❯ echo $GPG_TTY      
/dev/pts/0

❯ stat $GPG_TTY      
  File: /dev/pts/0
  Size: 0         	Blocks: 0          IO Block: 1024   character special file
Device: 0,24	Inode: 3           Links: 1     Device type: 136,0
Access: (0620/crw--w----)  Uid: ( 1001/     tng)   Gid: (    5/     tty)
Access: 2023-05-04 09:44:41.961348669 +0200
Modify: 2023-05-04 09:44:41.961348669 +0200
Change: 2023-05-04 09:28:53.961348669 +0200
 Birth: -

❯ echo $SSH_AGENT_PID


❯ echo $SSH_AUTH_SOCK 
/run/user/1001/gnupg/S.gpg-agent.ssh

These are my config files:

❯ cat ~/.ssh/config          
Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

❯ cat ~/.gnupg/gpg-agent.conf
default-cache-ttl 60480000
max-cache-ttl 60480000
pinentry-program /usr/bin/pinentry-tty

❯ cat ~/.zshenv.common 
export GPG_TTY=$(tty)
unset SSH_AGENT_PID
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
...

Here is the debug log of gpg-agent when trying ssh:

2023-05-02 17:20:01 gpg-agent[1889] gpg-agent (GnuPG) 2.2.41 starting in supervised mode.
2023-05-02 17:20:01 gpg-agent[1889] using fd 3 for browser socket (/run/user/1001/gnupg/S.gpg-agent.browser)
2023-05-02 17:20:01 gpg-agent[1889] using fd 4 for ssh socket (/run/user/1001/gnupg/S.gpg-agent.ssh)
2023-05-02 17:20:01 gpg-agent[1889] using fd 5 for std socket (/run/user/1001/gnupg/S.gpg-agent)
2023-05-02 17:20:01 gpg-agent[1889] using fd 6 for extra socket (/run/user/1001/gnupg/S.gpg-agent.extra)
2023-05-02 17:20:01 gpg-agent[1889] listening on: std=5 extra=6 browser=3 ssh=4
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK Pleased to meet you, process 1886
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- RESET
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION ttyname=not a tty
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION ttytype=foot
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=WAYLAND_DISPLAY=wayland-1
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=XDG_SESSION_TYPE=wayland
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=QT_QPA_PLATFORM=wayland;xcb
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION lc-ctype=en_US.UTF-8
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- OPTION lc-messages=en_US.UTF-8
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- UPDATESTARTUPTTY
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:01 gpg-agent[1889] DBG: chan_10 <- [eof]
2023-05-02 17:20:02 gpg-agent[1889] ssh handler 0x7f6608fff6c0 for fd 10 started
2023-05-02 17:20:02 gpg-agent[1889] ssh request 27 is not supported
2023-05-02 17:20:02 gpg-agent[1889] ssh request handler for request_identities (11) started
2023-05-02 17:20:02 gpg-agent[1889] no running SCdaemon - starting it
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- OK GNU Privacy Guard's Smartcard server ready
2023-05-02 17:20:02 gpg-agent[1889] DBG: first connection to SCdaemon established
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 -> GETINFO socket_name
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- D /run/user/1001/gnupg/S.scdaemon
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: additional connections at '/run/user/1001/gnupg/S.scdaemon'
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 -> OPTION event-signal=12
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 -> SERIALNO
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- ERR 100696144 No such device <SCD>
2023-05-02 17:20:02 gpg-agent[1889] ssh request handler for request_identities (11) ready
2023-05-02 17:20:02 gpg-agent[1889] ssh request handler for sign_request (13) started
2023-05-02 17:20:02 gpg-agent[1889] DBG: agent_get_cache 'C84288706F425E23C8E0D0192494457311942F37'.0 (mode 4) ...
2023-05-02 17:20:02 gpg-agent[1889] DBG: ... miss
2023-05-02 17:20:02 gpg-agent[1889] starting a new PIN Entry
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK Pleased to meet you, process 1889
2023-05-02 17:20:02 gpg-agent[1889] DBG: connection to PIN entry established
2023-05-02 17:20:02 gpg-agent[1889] DBG: pinentry: atfork used setenv(WAYLAND_DISPLAY,wayland-1)
2023-05-02 17:20:02 gpg-agent[1889] DBG: pinentry: atfork used setenv(XDG_SESSION_TYPE,wayland)
2023-05-02 17:20:02 gpg-agent[1889] DBG: pinentry: atfork used setenv(QT_QPA_PLATFORM,wayland;xcb)
2023-05-02 17:20:02 gpg-agent[1889] DBG: pinentry: atfork used setenv(DBUS_SESSION_BUS_ADDRESS,unix:path=/run/user/1001/bus)
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION no-grab
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION ttyname=not a tty
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION ttytype=foot
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION lc-ctype=en_US.UTF-8
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION lc-messages=en_US.UTF-8
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION allow-external-password-cache
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-ok=_OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-cancel=_Cancel
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-yes=_Yes
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- ERR 83886254 Unknown option <Pinentry>
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-no=_No
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- ERR 83886254 Unknown option <Pinentry>
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-prompt=PIN:
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-pwmngr=_Save in password manager
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-cf-visi=Do you really want to make your passphrase visible on the screen?
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-tt-visi=Make passphrase visible
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION default-tt-hide=Hide passphrase
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION touch-file=/run/user/1001/gnupg/S.gpg-agent
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> OPTION owner=1885 drybalka-linux
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> GETINFO flavor
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- D curses
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> GETINFO version
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- D 1.2.1
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> GETINFO ttyinfo
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- D not a tty foot - ? 1001/1001 0
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> GETINFO pid
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- D 1896
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> SETKEYINFO s/C84288706F425E23C8E0D0192494457311942F37
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> SETDESC Please enter the passphrase for the ssh key%0A  MD5:c0:41:a8:86:4a:ad:5d:6d:03:15:4f:6b:8a:4b:f2:2c%0A
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> SETPROMPT Passphrase:
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> [[Confidential data not shown]]
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- [[Confidential data not shown]]
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 <- [[Confidential data not shown]]
2023-05-02 17:20:02 gpg-agent[1889] DBG: error calling pinentry: No such file or directory <Pinentry>
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_12 -> BYE
2023-05-02 17:20:02 gpg-agent[1889] failed to unprotect the secret key: No such file or directory
2023-05-02 17:20:02 gpg-agent[1889] failed to read the secret key
2023-05-02 17:20:02 gpg-agent[1889] ssh sign request failed: No such file or directory <Pinentry>
2023-05-02 17:20:02 gpg-agent[1889] ssh request handler for sign_request (13) ready
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 -> RESTART
2023-05-02 17:20:02 gpg-agent[1889] DBG: chan_11 <- OK
2023-05-02 17:20:02 gpg-agent[1889] ssh handler 0x7f6608fff6c0 for fd 10 terminated
2023-05-02 17:20:05 gpg-agent[1889] DBG: agent_cache_housekeeping
2023-05-02 17:20:09 gpg-agent[1889] DBG: agent_cache_housekeeping

And here is the log when I try gpg signing with the same config:

2023-05-02 17:20:37 gpg-agent[1889] DBG: agent_cache_housekeeping
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK Pleased to meet you, process 2261
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- RESET
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION ttyname=/dev/pts/0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION ttytype=foot
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=WAYLAND_DISPLAY=wayland-1
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=XDG_SESSION_TYPE=wayland
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=QT_QPA_PLATFORM=wayland;xcb
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION lc-ctype=en_US.UTF-8
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION lc-messages=en_US.UTF-8
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- GETINFO version
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> D 2.2.41
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION allow-pinentry-notify
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- OPTION agent-awareness=2.1.0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- HAVEKEY EAB4212CE2AE63DE236389209A4934E03BAA40D1 5D25DA5709E064910ED678C14B6D3D5194D6B42B 03FB6F4934096C3210150CE4BE3266E8E1B24EC0 C84288706F425E23C8E0D0192494457311942F37
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- HAVEKEY 03FB6F4934096C3210150CE4BE3266E8E1B24EC0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- KEYINFO 03FB6F4934096C3210150CE4BE3266E8E1B24EC0
2023-05-02 17:20:39 gpg-agent[1889] DBG: agent_get_cache '03FB6F4934096C3210150CE4BE3266E8E1B24EC0'.0 (mode 2) ...
2023-05-02 17:20:39 gpg-agent[1889] DBG: ... miss
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> S KEYINFO 03FB6F4934096C3210150CE4BE3266E8E1B24EC0 D - - - P - - -
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- RESET
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- SIGKEY 03FB6F4934096C3210150CE4BE3266E8E1B24EC0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- SETKEYDESC Please+enter+the+passphrase+to+unlock+the+OpenPGP+secret+key:%0A%22Denys+Rybalka+<denys.rybalka@gmail.com>%22%0A4096-bit+RSA+key,+ID+C485756FE62D1371,%0Acreated+2023-05-01+(main+key+ID+3F84364E8D26CDF2).%0A
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- SETHASH 8 927C984BA8A8188672C643E3832686AAF8E77D779D9849FEA96B3C9BFCD6B707
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- PKSIGN
2023-05-02 17:20:39 gpg-agent[1889] DBG: agent_get_cache '03FB6F4934096C3210150CE4BE3266E8E1B24EC0'.0 (mode 2) ...
2023-05-02 17:20:39 gpg-agent[1889] DBG: ... miss
2023-05-02 17:20:39 gpg-agent[1889] starting a new PIN Entry
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK Pleased to meet you, process 1889
2023-05-02 17:20:39 gpg-agent[1889] DBG: connection to PIN entry established
2023-05-02 17:20:39 gpg-agent[1889] DBG: pinentry: atfork used setenv(WAYLAND_DISPLAY,wayland-1)
2023-05-02 17:20:39 gpg-agent[1889] DBG: pinentry: atfork used setenv(XDG_SESSION_TYPE,wayland)
2023-05-02 17:20:39 gpg-agent[1889] DBG: pinentry: atfork used setenv(QT_QPA_PLATFORM,wayland;xcb)
2023-05-02 17:20:39 gpg-agent[1889] DBG: pinentry: atfork used setenv(DBUS_SESSION_BUS_ADDRESS,unix:path=/run/user/1001/bus)
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION no-grab
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION ttyname=/dev/pts/0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION ttytype=foot
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION lc-ctype=en_US.UTF-8
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION lc-messages=en_US.UTF-8
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION allow-external-password-cache
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-ok=_OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-cancel=_Cancel
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-yes=_Yes
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- ERR 83886254 Unknown option <Pinentry>
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-no=_No
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- ERR 83886254 Unknown option <Pinentry>
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-prompt=PIN:
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-pwmngr=_Save in password manager
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-cf-visi=Do you really want to make your passphrase visible on the screen?
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-tt-visi=Make passphrase visible
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION default-tt-hide=Hide passphrase
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION touch-file=/run/user/1001/gnupg/S.gpg-agent
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> OPTION owner=2261 drybalka-linux
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> GETINFO flavor
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- D curses
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> GETINFO version
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- D 1.2.1
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> GETINFO ttyinfo
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- D /dev/pts/0 foot - 20620/1001/5 1001/1001 0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> GETINFO pid
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- D 2263
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 -> INQUIRE PINENTRY_LAUNCHED 2263 curses 1.2.1 /dev/pts/0 foot - 20620/1001/5 1001/1001 0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_10 <- END
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> SETKEYINFO n/03FB6F4934096C3210150CE4BE3266E8E1B24EC0
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> SETDESC Please enter the passphrase to unlock the OpenPGP secret key:%0A%22Denys Rybalka <denys.rybalka@gmail.com>%22%0A4096-bit RSA key, ID C485756FE62D1371,%0Acreated 2023-05-01 (main key ID 3F84364E8D26CDF2).%0A
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> SETPROMPT Passphrase:
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 <- OK
2023-05-02 17:20:39 gpg-agent[1889] DBG: chan_12 -> [[Confidential data not shown]]
2023-05-02 17:20:41 gpg-agent[1889] DBG: agent_cache_housekeeping
2023-05-02 17:20:42 gpg-agent[1889] DBG: chan_12 <- [[Confidential data not shown]]
2023-05-02 17:20:42 gpg-agent[1889] DBG: chan_12 <- [[Confidential data not shown]]
2023-05-02 17:20:43 gpg-agent[1889] DBG: chan_12 -> BYE
2023-05-02 17:20:43 gpg-agent[1889] DBG: agent_put_cache '03FB6F4934096C3210150CE4BE3266E8E1B24EC0'.0 (mode 2) requested ttl=0
2023-05-02 17:20:43 gpg-agent[1889] DBG: skey: (private-key 
2023-05-02 17:20:43 gpg-agent[1889] DBG:        (rsa 
...

and it goes on with the actual key.

Judging from the logs the ttyname and ttyinfo are wrong when using ssh, but my $GPG_TTY variable is set correctly in my zsh shell and it works for gpg signing.

Strangely enough when testing pinentry programs directly from my terminal I also get problems for tty and curses, but not qt (even though pinentry works correctly when invoked while gpg-signing):

❯ echo GETPIN | pinentry-curses
OK Pleased to meet you
S ERROR curses.isatty 83918950 
ERR 83918950 Inappropriate ioctl for device <Pinentry>

❯ echo GETPIN | pinentry-tty   
OK Pleased to meet you
ERR 83886179 Operation cancelled <Pinentry>

❯ echo GETPIN | pinentry-qt 
OK Pleased to meet you
CapsLockWatcher was compiled without support for Wayland
Checking for Caps Lock not possible on unsupported platform: "wayland"
D 1234
OK

Details

Version
gpg (GnuPG) 2.2.41

Event Timeline

On a terminal, please invoke:
$ gpg-connect-agent UPDATESTARTUPTTY /bye

Then, gpg-agent can update its startup environment variable.

In a case for gpg, it can pass the session variable to gpg-agent, so having GPG_TTY works.
In a case for ssh, there is no such a way from ssh to gpg-agent to tell which TTY should be used, so, startup environment variable matters.

Thank you, your suggestion inspired me to experiment a bit further and I found the problem - I needed in fact to delete the line from my ssh config, no idea why:

Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

Now I update startup tty only on terminal start and it seems to be working. Still a bit strange.

drybalka claimed this task.