Why doesn't gpg-agent startup on first call?

I user this script to invoke the gpg-agent for the purpose of SSL login with my Nitrokey pro. I added the option “–verbose” but this did not give further information.

Often the gpg-agent won’t run afterwards. I get this:

task scdaemon.exe is running: False
gpg-agent down, trying to start...
gpg-connect-agent: Kein aktiver gpg-agent - `C:\Program Files (x86)\GnuPG\bin\gpg-agent.exe' wird gestartet
gpg-connect-agent: Warte bis der agent bereit ist ... (5s)
gpg-connect-agent: Warte bis der agent bereit ist ... (4s)
gpg-connect-agent: Warte bis der agent bereit ist ... (3s)
gpg-connect-agent: Warte bis der agent bereit ist ... (2s)
gpg-connect-agent: Warte bis der agent bereit ist ... (1s)
gpg-connect-agent: can't connect to the agent: IPC "connect" Aufruf fehlgeschlagen
gpg-connect-agent: Fehler beim Senden der Standardoptionen: Agent läuft nicht
task gpg-agent.exe is running: False
Startup failed...

If I immedialtely repeat the procedure, I get this:

task scdaemon.exe is running: False
gpg-agent down, trying to start...
gpg-connect-agent: Kein aktiver gpg-agent - `C:\Program Files (x86)\GnuPG\bin\gpg-agent.exe' wird gestartet
gpg-connect-agent: Warte bis der agent bereit ist ... (5s)
gpg-connect-agent: Verbindung zum agent aufgebaut
task gpg-agent.exe is running: True
Success...

Why does

gpg-connect-agent --verbose /bye

fail on first call?

Windows 10-1909 > gpg --version
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5

Different user ? The login procedure seems either not the path or rights to start the agent. Later when you repeat you do have the rights.,. I don’t say this IS the error, but may be …

I must admit that don’t understand the remark about the login. gpg-connect-agent should just start the gpg-agent. What happens is this:

  • The Nitrokey is not plugged in.
  • The script is carried out twice by the same user (my account).
  • My script first looks for process “scdaemon.exe” and then for “gpg-agent.exe”.
  • Both are not running.
  • Then the script executes “gpg-connect-agent --verbose /bye”.
  • This leads to the messages of “gpg-connect-agent” shown in my post.
  • Then again the script checks whether “gpg-agent.exe” is running and reports the result.

When I execute the script the first time, gpg-agent.exe could not be started. I then immediately execute the same script again. This time gpg-agent.exe is started quickly.

The login procedure may happen not before I plugin the Nitrokey and call putty.

Sorry, my misunderstanding: thought you use the script and key for login to your window system.
Are you starting the scdaemon first ? And if you need to start him, do you give him a grace time for startup before you look for the gpg-agent ?

Hello Peacekeeper,

the scdaemon is not running when I try to start the gpg-agent. scdaemon startup is always triggered by calling putty after having plugged in the Nitrokey. This of course only works after the gpg-agent was sucessfully launched. In the latter case SSH login also works.

My script only reports whether scdaemon is running or not. scdaemon should not have anything to do with the gpg-agent startup problem.

Meanwhile I updated from GnuPG 2.2.19 (from within latest gpg4win 3.1.11) to standalone GnuPG 2.2.20.
https://chocolatey.org/packages/gnupg
The behaviour is exactly the same (Program launch only on second trial).

This software is really, really difficult to use. :frowning:

Kind regards

Why are you using a script and not the simple method that NK describes [here] ?(https://www.nitrokey.com/de/documentation/applications#a:ssh-for-server-administration)

The challenge is, that Putty doesn’t support smart cards out-of-the-box. ssh supports smartcards via pkcs#11 shared lib and GnuPG through their own model.
The last has the advantage that they not only support PGP for email, also ssh through the gpg-agent to ensure that the single NK and device driver could coordinate the different requests.

Here is my thinking ( and it is theoretical only, as I am using FreeBSD and macOS): gpg-agent needs to open the scdaemon to determine, if you have a private key and needs to load it ( and normally ask you for the passkey for the NK ) or it waits until scdaemon reports a new key.

As you start the script with no key plugged in, the first time the agent could not start, as no scdaemon is running and will give up after timeout. The second time , the scdaemon is running and the agent could also start.

To verify this, you might want to review/diff the running tasks after the first start .

Hello,

there is a misunderstanding. I use the very same agent launch method as it is mentioned within the help article cited by you. My script is nothing but a wrapper around the command

"C:\Program Files (x86)\gnupg\bin\gpg-connect-agent.exe" /bye

from this help article with some more reporting end extra task checking. The command above does simply fail on first trial. The simple autorun method of the help artice fails since the underlying command fails.

In the beginning, I thought that there was a problem caused by the Windows sleep mode. Now I see that there must be another problem.

I filed a bug report: https://dev.gnupg.org/T4978

1 Like

For the moment, the cause of the gpg-connect-agent hang does not seem to be trackable. While the hang might be rare, it nevertheless does make sense to have at least a workaround in any case. For me it would also be very unsatisfactory if a thread ends without solution. I therefore present a workaround which consists in avoiding the inter-process communication between gpg-connect-agent and gpg-agent. While the gpg-agent may be started directly, it is necessary to detach it from the commandline window. This is done by the following Python script which also checks whether the agent is running. The script pauses in case of a failed startup. For me it runs very fast and hasn’t failed up to now.

#========================================================================
# Tested under Windows 10 with Python 3.8.3 (June 23, 2020).
#========================================================================
import os, subprocess
#========================================================================
# This standard windows shell command gives returncode 0 if TASK runs:
# tasklist /fi "imagename eq TASK" 2>NUL | find /I /N "TASK">NUL
#========================================================================
def is_task_running(taskname: str, output=False) -> bool:
  command = 'tasklist /fi "imagename eq ' + taskname + \
            '" 2>NUL | find /I /N "' + taskname + '">NUL'
  it_runs = os.system(command) == 0
  if output:
    print('task', taskname, 'is running:', it_runs)
  return it_runs
  
#========================================================================  
# Begin main script
#========================================================================
if is_task_running('gpg-agent.exe'):
  print('gpg-agent already running, killing...')
  os.system('gpgconf --kill gpg-agent')
  is_task_running('gpg-agent.exe', True)
else:
  print('gpg-agent not running...')
  
#------------------------------------------------------------------------
# Create a subprocess with gpg-agent running and detach it.
# Version with logfile:
# ['gpg-agent.exe', '-v', '--daemon', '--log-file', '/temp/gpg-agent.log']
#------------------------------------------------------------------------
print('starting gpg-agent...')
subprocess.Popen(
  ['gpg-agent.exe', '--daemon'], \
  creationflags=subprocess.DETACHED_PROCESS | \
  subprocess.CREATE_NEW_PROCESS_GROUP | \
  subprocess.CREATE_BREAKAWAY_FROM_JOB)

if is_task_running('gpg-agent.exe', True):
  print('...success')
else:
  print('...failed')
  os.system('pause')

Remark: Of course, the simple gpg-connect-agent one-liner from the Nitrokey help pages suffices as long as there are no startup problems.

Remark 2: Compiled Vanilla “Gnu Private Guard” is available for Windows with chocolatey (see above).

1 Like