Page MenuHome GnuPG

Pinentry-qt4 opens confirm dialog in the background
Closed, ResolvedPublic

Description

While the "enter passphrase" dialog is opened in the foreground confirm dialogs
like the "warning insecure passphrase" is opened in the background.

To reproduce:
Start key generation in kleopatra.
Enter passphrase 123
-> Warning about insecure passphrase is opened in the background.

I've added the ShowEvent / RaiseWindow combination to the pinentryconfirm dialog
but in case of the confirm message this function fails. It succeeds in the case
of get passphrase.

I've tried calling gnupg_allow_set_foregound_window in the agent after it
launched pinentry but it appears the the agent is also the wrong place for this.

In kleopatra I can not find an AllowSetForegroundWindow call at all. GnuPG
appears to allow this in common/get-passphrase.c but I am unsure if this is used
here where we try to obtain the passphrase over the gnupg agent. And even then
why does gnupg has the SetForegroundWindow right and not the agent.

Werner can you tell me how the ForegroundWindow forwarding is supposed to work
and who should ultimately call this? I think kleopatra would be responsible here
but I can't see how Kleopatra can get at the PID of the Pinentryconfirm dialog.

Details

Version
0.8.4

Event Timeline

It goes all the way back to GPGME via the assuan interface. grep for
_gpgme_allow_set_foreground_window. For GPG the assuan interface is not used.
We do it by passing our internal IOSPAWN_FLAG_ALLOW_SET_FG flag to the
gpgme-w32spawn.c helper which then uses this to call set foreground API.

Does Kleopatra always use gpgme?

BTW, gpgme 1.5.1 has a spawn interface which is better than to code your own in Qt.

Yes Kleopatra uses gpgme for key generation. Still I don't see how gpgme figures
into this sorry. Should gpgme start gpg-agent and ensure that it has the
setforeground window access right?

  1. The gpg-agent asks for a passphrase with pinentry -> set foreground window is

allowed.

  1. If that passphrase is weak it launches a new pinentry with a confirm dialog

-> set foreground window is not allowed.

And the agent does not have the right to call allowsetforegroundwindow. In the
first case I think this might be because another component gets the PID of the
pinentry and calls allowsetforeground window (have to do further debugging to
check this)

In the second case afaik only gpg-agent is involved and no one sets
allowsetforeground window on the pid of the second pinentry.

  1. The agent starts pinentry.
  2. The agent sends "getinfo pid" to the pinentry"
  3. The agents sends an "INQUIRE PINENTRY_LAUNCHED <pid>" to the caller.

4a. If the caller is gpg, gpg calls AllowSetForegroundWindow for the received
pid; gpg has been started via gpgme and gpgme has called ASFW for gpg.
4b. If the caller is gpgsm, it proxies the PINENTRY_LAUNCHED to gpgme which then
calls ASFG for the pid.

The different methods are required because gpg is a one-off process while gpgsm
may be used several times.

Ok, thanks I'll check what happens if

  1. The agent thinks that the passphrase entered is too weak
  2. The agent starts another pinentry
  3. The agent sends "getinfo pid" to the pinentry (this i can see)
  4. ?

What I described is done for all pinentries.

Thanks for the explanations.

Further analysis showed that the second call to AllowSetForeground window was
blocked by the ForegroundWindowLockTimeout. If you set this timeout to zero
everything worked as expected.

There is a discussion on this under:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/09fa16ba-c6ef-410d-bec2-a99a9b9a98d9/issue-with-foregroundlocktimeout-setforegroundwindow

Which suggests a solution of setting the foregroundlocktimeout to zero before
attempting to set the foreground window. I've found this solution not applicable
for our case as we run into the lock on "AllowSetForegroundWindow" and not when
actually setting the foreground Window.

Another workaround is to call AttachThreadInput on the current foreground thread
call SetForegroundWindow and then detach again. There might be problems with
this approach so it is just used as fallback. But it should resolve this problem
for now.

aheinecke removed a project: Restricted Project.