[Question] Detecting that Yubikey is waiting for a touch via an external script
See original GitHub issueI have YubiKey 4 Nano and the blinking light is not always visible, so I often find myself missing a time window to touch Yubikey when there is a prompt “Please touch the device”. This happens for example when I begin some long-running task that will finish with a sudo command (e.g. build and install an app).
I’m writing a script that could detect when YubiKey is waiting for a touch. I have some partial success, and it looks like this:
Detection for gpg
and sudo
operations is very different, both methods are very hacky and have their downsides, so I want to describe how I made it and ask you for suggestions, maybe you can come up with some improvement ideas.
GPG:
I noticed that command gpg --card-status
normally returns instantly, but if YubiKey is waiting for a touch for another gpg
operation (like gpg --sign
), then gpg --card-status
will hang until I touch the device. So I implement detection in a following way:
- Every second or even less, try to call
gpg --card-status
. - If the command returns instantly, YubiKey is not waiting for a touch - repeat step 1
- Otherwise, mark that YubiKey is waiting for a touch and wait until the command returns.
- When it returns, mark that YubiKey is no longer waiting for a touch.
The problems with this approach:
- Lots of wasted CPU cycles (I want the detection to happen as fast as possible)
- The fact that YubiKey is always active, it has to respond to
gpg --card-status
a lot of times and thus the light indicator is always constantly on.
UPDATE: I came up with a yet another hack to drastically reduce the number of CPU cycles. Instead of always constantly running gpg --card-status
, I first use inotifywait
to monitor access to ~/.gnupg/pubring.kbx
(for sign
and encrypt
) and ~/.ssh/known_hosts
(for auth
), and only if any of these two files were opened, then I try gpg --card-status
in a loop within 5 seconds. The rest of the algorithm remains the same.
Any suggestions on how to better do this?
sudo (pam-u2f):
I opened a separate question about this topic on pam-u2f
repo, but I’ll describe it here as well, as here it is a different audience and most of links on ArchWiki point to this repo anyway.
Since to configure pam-u2f
it is needed to create ~/.config/Yubico/u2f_keys
file, it is obvious to assume that this file will be read every time Yubikey will be used. Good news, this does happen, so setting up a simple inotifywait
for OPEN
event for this file will instantly let me know when sudo
access is being requested. No wasted CPU cycles in this approach, I like it.
However, the problem that I was unable to solve so far is how to detect that YubiKey is stopped waiting for a touch (user touched the device, or timeout happened). With gpg
it was easy, but here I cannot find a way to detect this.
UPDATE: I made a fork of pam-u2f that allows to watch the event of completed authorization. It was not merged in the upstream, because that project is being rewritten, but hopefully this functionality will be present in the new project. But using the fork allows to monitor when ~/.config/Yubico/u2f_keys
was opened to indicate that authorization was completed.
Any better suggestions here?
Of course it would be awesome if one of the yubikey CLI tools provided such information out of the box, it is a really useful feature in my mind and I’ve seen other people requesting this. But I understand that it might be simply impossible to implement in a proper way.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:5 (1 by maintainers)
Top GitHub Comments
In case someone is interested, I created a standalone app for detecting when YubiKey is waiting for a touch. It is designed to be run as a background service and to be easily integrated with third-party apps that can use it to display a visible indicator.
https://github.com/maximbaz/yubikey-touch-detector
A big improvement comparing to what I described above is that now it can also detect when a physical touch is requested due to the use of
ssh
on a remote host with forwardedssh-agent
.Sorry, ykinfo is part of yubikey-personalization. There is an open request for this feature at https://github.com/Yubico/yubikey-personalization/issues/154