169
/* Send the XAUTHORITY variable. */
170
dft_xauthority = getenv ("XAUTHORITY");
171
if (opt_xauthority || dft_xauthority)
173
err = send_one_option (ctx, errsource, "xauthority",
174
opt_xauthority ? opt_xauthority : dft_xauthority);
175
if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
181
/* Send the PINENTRY_USER_DATA variable. */
182
dft_pinentry_user_data = getenv ("PINENTRY_USER_DATA");
183
if (opt_pinentry_user_data || dft_pinentry_user_data)
185
err = send_one_option (ctx, errsource, "pinentry-user-data",
186
opt_pinentry_user_data ?
187
opt_pinentry_user_data : dft_pinentry_user_data);
188
if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
198
/* Try to connect to the agent via socket or fork it off and work by
199
pipes. Handle the server's initial greeting. Returns a new assuan
200
context at R_CTX or an error code. */
202
start_new_gpg_agent (assuan_context_t *r_ctx,
203
gpg_err_source_t errsource,
205
const char *agent_program,
206
const char *opt_display,
207
const char *opt_ttyname,
208
const char *opt_ttytype,
209
const char *opt_lc_ctype,
210
const char *opt_lc_messages,
211
const char *opt_xauthority,
212
const char *opt_pinentry_user_data,
213
int verbose, int debug,
214
gpg_error_t (*status_cb)(ctrl_t, int, ...),
215
ctrl_t status_cb_arg)
217
/* If we ever failed to connect via a socket we will force the use
218
of the pipe based server for the lifetime of the process. */
219
static int force_pipe_server = 0;
223
assuan_context_t ctx;
228
infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
229
if (!infostr || !*infostr)
233
/* First check whether we can connect at the standard
235
sockname = make_filename (homedir, "S.gpg-agent", NULL);
236
rc = assuan_socket_connect (&ctx, sockname, 0);
240
/* With no success start a new server. */
242
log_info (_("no running gpg-agent - starting one\n"));
245
status_cb (status_cb_arg, STATUS_PROGRESS,
246
"starting_agent ? 0 0", NULL);
250
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
251
log_error ("error flushing pending output: %s\n",
257
if (!agent_program || !*agent_program)
258
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
260
#ifdef HAVE_W32_SYSTEM
262
/* Under Windows we start the server in daemon mode. This
263
is because the default is to use the standard socket
264
and thus there is no need for the GPG_AGENT_INFO
265
envvar. This is possible as we don't have a real unix
266
domain socket but use a plain file and thus there is no
267
need to care about non-local file systems. */
270
argv[0] = "--daemon";
271
argv[1] = "--use-standard-socket";
274
rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
276
log_debug ("failed to start agent `%s': %s\n",
277
agent_program, gpg_strerror (rc));
280
/* Give the agent some time to prepare itself. */
282
/* Now try again to connect the agent. */
283
rc = assuan_socket_connect (&ctx, sockname, 0);
286
#else /*!HAVE_W32_SYSTEM*/
290
int no_close_list[3];
293
if ( !(pgmname = strrchr (agent_program, '/')))
294
pgmname = agent_program;
299
argv[1] = "--server";
303
if (log_get_fd () != -1)
304
no_close_list[i++] = log_get_fd ();
305
no_close_list[i++] = fileno (stderr);
306
no_close_list[i] = -1;
308
/* Connect to the agent and perform initial handshaking. */
309
rc = assuan_pipe_connect (&ctx, agent_program, argv,
312
#endif /*!HAVE_W32_SYSTEM*/
321
infostr = xstrdup (infostr);
322
if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
324
log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
326
force_pipe_server = 1;
331
while (*p && *p != PATHSEP_C)
333
prot = *p? atoi (p+1) : 0;
336
log_error (_("gpg-agent protocol version %d is not supported\n"),
339
force_pipe_server = 1;
343
rc = assuan_socket_connect (&ctx, infostr, pid);
345
if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
347
log_info (_("can't connect to the agent - trying fall back\n"));
348
force_pipe_server = 1;
355
log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
356
return gpg_error (GPG_ERR_NO_AGENT);
360
log_debug ("connection to agent established\n");
362
rc = assuan_transact (ctx, "RESET",
363
NULL, NULL, NULL, NULL, NULL, NULL);
365
rc = send_pinentry_environment (ctx, errsource,
366
opt_display, opt_ttyname, opt_ttytype,
367
opt_lc_ctype, opt_lc_messages,
369
opt_pinentry_user_data);
372
assuan_disconnect (ctx);