172
/* Lock the agent spawning process. The caller needs to provide the
173
address of a variable to store the lock information. */
175
lock_agent_spawning (lock_agent_t *lock, const char *homedir)
177
#ifdef HAVE_W32_SYSTEM
180
(void)homedir; /* Not required. */
182
*lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel");
185
log_error ("failed to create the spawn_agent mutex: %s\n",
187
return gpg_error (GPG_ERR_GENERAL);
190
waitrc = WaitForSingleObject (*lock, 5000);
191
if (waitrc == WAIT_OBJECT_0)
194
if (waitrc == WAIT_TIMEOUT)
195
log_info ("error waiting for the spawn_agent mutex: timeout\n");
197
log_info ("error waiting for the spawn_agent mutex: "
198
"(code=%d) %s\n", waitrc, w32_strerror (-1));
199
return gpg_error (GPG_ERR_GENERAL);
200
#else /*!HAVE_W32_SYSTEM*/
205
fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL);
207
return gpg_error_from_syserror ();
209
*lock = create_dotlock (fname);
212
return gpg_error_from_syserror ();
214
/* FIXME: We should use a timeout of 5000 here - however
215
make_dotlock does not yet support values other than -1 and 0. */
216
if (make_dotlock (*lock, -1))
217
return gpg_error_from_syserror ();
220
#endif /*!HAVE_W32_SYSTEM*/
224
/* Unlock the spawning process. */
226
unlock_agent_spawning (lock_agent_t *lock)
230
#ifdef HAVE_W32_SYSTEM
231
if (!ReleaseMutex (*lock))
232
log_error ("failed to release the spawn_agent mutex: %s\n",
235
#else /*!HAVE_W32_SYSTEM*/
236
destroy_dotlock (*lock);
237
#endif /*!HAVE_W32_SYSTEM*/
161
243
/* Try to connect to the agent via socket or fork it off and work by
162
244
pipes. Handle the server's initial greeting. Returns a new assuan
163
245
context at R_CTX or an error code. */
177
259
of the pipe based server for the lifetime of the process. */
178
260
static int force_pipe_server = 0;
181
263
char *infostr, *p;
182
264
assuan_context_t ctx;
268
err = assuan_new (&ctx);
271
log_error ("error allocating assuan context: %s\n", gpg_strerror (err));
187
276
infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
188
277
if (!infostr || !*infostr)
192
284
/* First check whether we can connect at the standard
194
286
sockname = make_filename (homedir, "S.gpg-agent", NULL);
195
rc = assuan_socket_connect (&ctx, sockname, 0);
287
err = assuan_socket_connect (ctx, sockname, 0, 0);
199
291
/* With no success start a new server. */
210
302
log_error ("error flushing pending output: %s\n",
211
303
strerror (errno));
212
304
xfree (sockname);
305
assuan_release (ctx);
216
309
if (!agent_program || !*agent_program)
217
310
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
219
#ifdef HAVE_W32_SYSTEM
221
/* Under Windows we start the server in daemon mode. This
222
is because the default is to use the standard socket
223
and thus there is no need for the GPG_AGENT_INFO
224
envvar. This is possible as we don't have a real unix
225
domain socket but use a plain file and thus there is no
226
need to care about non-local file systems. */
229
argv[0] = "--daemon";
230
argv[1] = "--use-standard-socket";
233
rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
235
log_debug ("failed to start agent `%s': %s\n",
236
agent_program, gpg_strerror (rc));
239
/* Give the agent some time to prepare itself. */
241
/* Now try again to connect the agent. */
242
rc = assuan_socket_connect (&ctx, sockname, 0);
245
#else /*!HAVE_W32_SYSTEM*/
249
int no_close_list[3];
252
if ( !(pgmname = strrchr (agent_program, '/')))
253
pgmname = agent_program;
258
argv[1] = "--server";
262
if (log_get_fd () != -1)
263
no_close_list[i++] = log_get_fd ();
264
no_close_list[i++] = fileno (stderr);
265
no_close_list[i] = -1;
267
/* Connect to the agent and perform initial handshaking. */
268
rc = assuan_pipe_connect (&ctx, agent_program, argv,
271
#endif /*!HAVE_W32_SYSTEM*/
312
argv[0] = "--use-standard-socket-p";
314
err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid);
316
log_debug ("starting `%s' for testing failed: %s\n",
317
agent_program, gpg_strerror (err));
318
else if ((err = gnupg_wait_process (agent_program, pid, &excode)))
321
log_debug ("running `%s' for testing failed: %s\n",
322
agent_program, gpg_strerror (err));
327
/* If the agent has been configured for use with a
328
standard socket, an environment variable is not
329
required and thus we we can savely start the agent
333
argv[0] = "--daemon";
334
argv[1] = "--use-standard-socket";
337
if (!(err = lock_agent_spawning (&lock, homedir))
338
&& assuan_socket_connect (ctx, sockname, 0, 0))
340
err = gnupg_spawn_process_detached (agent_program, argv,NULL);
342
log_error ("failed to start agent `%s': %s\n",
343
agent_program, gpg_strerror (err));
349
log_info (_("waiting %d seconds for the agent "
351
for (i=0; i < 5; i++)
354
err = assuan_socket_connect (ctx, sockname, 0, 0);
361
unlock_agent_spawning (&lock);
365
/* If using the standard socket is not the default we
366
start the agent as a pipe server which gives us most
367
of the required features except for passphrase
370
int no_close_list[3];
373
if ( !(pgmname = strrchr (agent_program, '/')))
374
pgmname = agent_program;
379
argv[1] = "--server";
383
if (log_get_fd () != -1)
384
no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
385
no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
386
no_close_list[i] = -1;
388
/* Connect to the agent and perform initial handshaking. */
389
err = assuan_pipe_connect (ctx, agent_program, argv,
390
no_close_list, NULL, NULL, 0);
273
393
xfree (sockname);
314
log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
434
log_error ("can't connect to the agent: %s\n", gpg_strerror (err));
435
assuan_release (ctx);
315
436
return gpg_error (GPG_ERR_NO_AGENT);
319
440
log_debug ("connection to agent established\n");
321
rc = assuan_transact (ctx, "RESET",
442
err = assuan_transact (ctx, "RESET",
322
443
NULL, NULL, NULL, NULL, NULL, NULL);
324
rc = send_pinentry_environment (ctx, errsource,
445
err = send_pinentry_environment (ctx, errsource,
325
446
opt_lc_ctype, opt_lc_messages,
329
assuan_disconnect (ctx);
450
assuan_release (ctx);