Release: 1.9.20
Description
Access to pinentry is serialized so that there will only be one pinentry box on the screen at the same time. However, it would be even better if the code that calls agent_askpim() or agent_get_passphrase() were serialized. Or, in better words: When there is already a pinentry in progress, wait until it's done and check if the requested passphrase is now in the cache. What happens now is that if there are many programs simultaneously needing the same same passphrase, you will need to enter it many times, because the the later threads will be waiting in start_pinentry() and they will not know that the passphrase has been cached.
How To Repeat
Use gpg-agent as ssh-agent (--enable-ssh-support).
Start an X session with many ssh connections, for example a bunch of KDE apps in which you have opened files using fish (the ssh ioslave). You will have to enter the password for your ssh key once for every file.
Fix
This may require a bit of a design change to fix, but the problem isn't big except maybe with ssh keys. I have two possible solutions to that part:
- Add a mutex to unprotect() in findkey.c. Acquire it after checking the cache, then check the cache again. If the password is still not there, call agent_askpin(). Finally release the mutex.
- Add hexgrip and cache_mode fields to struct try_unprotect_arg_s; have agent_askpin() call pininfo->check_cb with pininfo->pin = NULL first; when that happens, try_unprotect_cb() rechecks the cache.