Page MenuHome GnuPG

Better message than "Inappropriate ioctl for device" for tty pinentries
Open, NormalPublic

Description

Importing the secret key like this used to work in up until gnupg 2.0.22:

$ gpg2 --import < admin_secure.asc

In newer versions, this fails with the following confusing messages:

gpg: key DFF515D9AD9B2D90/DFF515D9AD9B2D90: error sending to agent: Inappropriate ioctl for device
gpg: error building skey array: Inappropriate ioctl for device
gpg: error reading '[stdin]': Inappropriate ioctl for device
gpg: import from '[stdin]' failed: Inappropriate ioctl for device

The simple workaround is to provide --batch, which passes the agent the information that the import should be unattended and will not attempt to ask for the passphrase on stdin. Other option is to use gpg --import admin_secure.asc, which will use the correct FD to ask for passphrase (at least in case of curses or tty pinentry).

Given that this worked before, would it be possible to capture this combination (secret key from stdin and no --batch) and warn user rather than failing with this cryptic message?

Details

Version
master

Event Timeline

Please run with option -v to see what's wrong with pinentry.

the -v does not show more useful info on the gpg side:

# gpg2 --quick-gen-key admin
About to create a key for:
    "admin"

Continue? (Y/n) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 9E052C7ABF0B7505 marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/80CF647EB158C32039A560979E052C7ABF0B7505.rev'
public and secret key created and signed.

pub   rsa3072 2022-03-18 [SC] [expires: 2024-03-17]
      80CF647EB158C32039A560979E052C7ABF0B7505
uid                      admin
sub   rsa3072 2022-03-18 [E]

$ gpg2 --export-secret-keys > admin_secure.asc
$ export GNUPGHOME=$PWD
$ gpg2 -v --import < admin_secure.asc
gpg: Note: RFC4880bis features are enabled.
gpg: keybox '/root/pubring.kbx' created
gpg: sec  rsa3072/9E052C7ABF0B7505 2022-03-18  admin
gpg: /root/trustdb.gpg: trustdb created
gpg: using pgp trust model
gpg: key 9E052C7ABF0B7505: public key "admin" imported
gpg: no running gpg-agent - starting '/usr/bin/gpg-agent'
gpg: waiting for the agent to come up ... (5s)
gpg: connection to the agent established
gpg: pinentry launched (9351 curses 1.1.1 - xterm-256color - - 0/0 0)
gpg: key 9E052C7ABF0B7505/9E052C7ABF0B7505: error sending to agent: Inappropriate ioctl for device
gpg: error building skey array: Inappropriate ioctl for device
gpg: error reading '[stdin]': Inappropriate ioctl for device
gpg: import from '[stdin]' failed: Inappropriate ioctl for device
gpg: Total number processed: 0
gpg:               imported: 1
gpg:       secret keys read: 1

With --debug-all there is a bit more about the communication with agent, but not much:

gpg: DBG: chan_4 <- OK Pleased to meet you, process 9367
gpg: DBG: connection to the gpg-agent established
gpg: DBG: chan_4 -> RESET
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> OPTION ttytype=xterm-256color
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> OPTION putenv=XDG_SESSION_TYPE=tty
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> GETINFO version
gpg: DBG: chan_4 <- D 2.3.3
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> OPTION allow-pinentry-notify
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> OPTION agent-awareness=2.1.0
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> KEYWRAP_KEY --import
gpg: DBG: chan_4 <- [ 44 20 fd 52 70 8f 35 8e 56 09 12 1c 9c 5a ca 6d ...(2 byte(s) skipped) ]
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> SETKEYDESC Please+enter+the+passphrase+to+import+the+OpenPGP+secret+key:%0A%22admin%22%0A3072-bit+RSA+key,+ID+9E052C7ABF0B7505,%0Acreated+2022-03-18.%0A
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> IMPORT_KEY --timestamp=20220318T133613
gpg: DBG: chan_4 <- INQUIRE KEYDATA
gpg: DBG: chan_4 -> [ 44 20 62 12 96 a9 2b 58 1d da ba 2c e9 10 e5 25 ...(982 byte(s) skipped) ]
gpg: DBG: chan_4 -> [ 44 20 2b ce 82 cc b9 92 a6 76 cf be e3 d0 27 46 ...(566 byte(s) skipped) ]
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 9369 curses 1.1.1 - xterm-256color - - 0/0 0
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- ERR 83918950 Inappropriate ioctl for device <Pinentry>
gpg: key 9E052C7ABF0B7505/9E052C7ABF0B7505: error sending to agent: Inappropriate ioctl for device
gpg: error building skey array: Inappropriate ioctl for device

The gpg-agent logs show a bit more info with --debug-all, but also nothing clear as far as I understand it:

gpg-agent[9404]: starting a new PIN Entry
gpg-agent[9404]: DBG: connection to PIN entry established
gpg-agent[9404]: DBG: chan_9 -> INQUIRE PINENTRY_LAUNCHED 9407 curses 1.1.1 - xterm-256color - - 0/0 0
gpg-agent[9404]: DBG: chan_9 <- END
gpg-agent[9404]: DBG: agent_cache_housekeeping
gpg-agent[9404]: DBG: error calling pinentry: Inappropriate ioctl for device <Pinentry>
gpg-agent[9404]: command 'IMPORT_KEY' failed: Inappropriate ioctl for device <Pinentry>
gpg-agent[9404]: DBG: chan_9 -> ERR 83918950 Inappropriate ioctl for device <Pinentry>
gpg-agent[9404]: DBG: chan_9 <- [eof]

Is your GPG_TTY set so that pinentry can find the right tty?

Adding

GPG_TTY=$(tty)
export GPG_TTY

makes this working so thank you for the pointer.

But I still do not think this is the best error message we could get for a user going from older gnupg version, which did not require this to newer one.

I see that agent or pinentry is trying to figure out the tty when the environment variable is not available (and it does it pretty well in most of the cases).

werner renamed this task from gpg --import of secret key from stdin fails confusingly to Better message than "Inappropriate ioctl for device" for tty pinentries.Mar 25 2022, 1:30 PM
werner triaged this task as Normal priority.
werner edited projects, added pinentry, Feature Request; removed Bug Report.