aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/ChangeLog17
-rw-r--r--agent/agent.h14
-rw-r--r--agent/call-scd.c30
-rw-r--r--agent/command.c34
-rw-r--r--agent/gpg-agent.c104
5 files changed, 173 insertions, 26 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 9c57ad43e..9621e5de0 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,20 @@
+2005-06-03 Werner Koch <[email protected]>
+
+ * command.c (cmd_updatestartuptty): New.
+
+ * gpg-agent.c: New option --write-env-file.
+
+ * gpg-agent.c (handle_connections): Make sure that the signals we
+ are handling are not blocked.Block signals while creating new
+ threads.
+
+2005-06-02 Werner Koch <[email protected]>
+
+ * call-scd.c (agent_scd_dump_state, dump_mutex_state): New.
+ * gpg-agent.c (handle_signal): Print it on SIGUSR1.
+ (handle_connections): Include the file descriptor into the
+ threadnames.
+
2005-06-01 Werner Koch <[email protected]>
* gpg-agent.c: Include setenv.h.
diff --git a/agent/agent.h b/agent/agent.h
index a667c0d46..51e66abee 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -54,12 +54,13 @@ struct {
int batch; /* Batch mode */
const char *homedir; /* Configuration directory name */
- /* Environment setting gathred at program start. */
- const char *startup_display;
- const char *startup_ttyname;
- const char *startup_ttytype;
- const char *startup_lc_ctype;
- const char *startup_lc_messages;
+ /* Environment setting gathered at program start or hanged using the
+ Assuan command UPDATESTARTUPTTY. */
+ char *startup_display;
+ char *startup_ttyname;
+ char *startup_ttytype;
+ char *startup_lc_ctype;
+ char *startup_lc_messages;
const char *pinentry_program; /* Filename of the program to start as
@@ -248,6 +249,7 @@ int divert_generic_cmd (ctrl_t ctrl,
/*-- call-scd.c --*/
void initialize_module_call_scd (void);
+void agent_scd_dump_state (void);
void agent_scd_check_aliveness (void);
int agent_reset_scd (ctrl_t ctrl);
int agent_card_learn (ctrl_t ctrl,
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 78e28fe97..00c9df2a7 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -116,6 +116,35 @@ initialize_module_call_scd (void)
}
+static void
+dump_mutex_state (pth_mutex_t *m)
+{
+ if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
+ log_printf ("not_initialized");
+ else if (!(m->mx_state & PTH_MUTEX_LOCKED))
+ log_printf ("not_locked");
+ else
+ log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
+}
+
+
+/* This function may be called to print infromation pertaining to the
+ current state of this module to the log. */
+void
+agent_scd_dump_state (void)
+{
+ log_info ("agent_scd_dump_state: scd_lock=");
+ dump_mutex_state (&start_scd_lock);
+ log_printf ("\n");
+ log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
+ primary_scd_ctx,
+ (long)assuan_get_pid (primary_scd_ctx),
+ primary_scd_ctx_reusable);
+ if (socket_name)
+ log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
+}
+
+
/* The unlock_scd function shall be called after having accessed the
SCD. It is currently not very useful but gives an opportunity to
keep track of connections currently calling SCD. Note that the
@@ -384,6 +413,7 @@ agent_scd_check_aliveness (void)
}
+
/* Reset the SCD if it has been used. */
int
agent_reset_scd (ctrl_t ctrl)
diff --git a/agent/command.c b/agent/command.c
index 8af159f6d..56167118d 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -868,6 +868,39 @@ cmd_scd (ASSUAN_CONTEXT ctx, char *line)
+/* UPDATESTARTUPTTY
+
+ Set startup TTY and X DISPLAY variables to the values of this
+ session. This command is useful to pull future pinentries to
+ another screen. It is only required because there is no way in the
+ ssh-agent protocol to convey this information. */
+static int
+cmd_updatestartuptty (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+
+ xfree (opt.startup_display); opt.startup_display = NULL;
+ xfree (opt.startup_ttyname); opt.startup_ttyname = NULL;
+ xfree (opt.startup_ttytype); opt.startup_ttytype = NULL;
+ xfree (opt.startup_lc_ctype); opt.startup_lc_ctype = NULL;
+ xfree (opt.startup_lc_messages); opt.startup_lc_messages = NULL;
+
+ if (ctrl->display)
+ opt.startup_display = xtrystrdup (ctrl->display);
+ if (ctrl->ttyname)
+ opt.startup_ttyname = xtrystrdup (ctrl->ttyname);
+ if (ctrl->ttytype)
+ opt.startup_ttytype = xtrystrdup (ctrl->ttytype);
+ if (ctrl->lc_ctype)
+ opt.startup_lc_ctype = xtrystrdup (ctrl->lc_ctype);
+ if (ctrl->lc_messages)
+ opt.startup_lc_messages = xtrystrdup (ctrl->lc_messages);
+
+ return 0;
+}
+
+
+
static int
option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
{
@@ -957,6 +990,7 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "INPUT", NULL },
{ "OUTPUT", NULL },
{ "SCD", cmd_scd },
+ { "UPDATESTARTUPTTY", cmd_updatestartuptty },
{ NULL }
};
int i, rc;
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 3537b07f0..90b071d5e 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -93,7 +93,8 @@ enum cmd_and_opt_values
oKeepTTY,
oKeepDISPLAY,
oSSHSupport,
- oDisableScdaemon
+ oDisableScdaemon,
+ oWriteEnvFile
};
@@ -147,6 +148,8 @@ static ARGPARSE_OPTS opts[] = {
{ oAllowPresetPassphrase, "allow-preset-passphrase", 0,
N_("allow presetting passphrase")},
{ oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") },
+ { oWriteEnvFile, "write-env-file", 2,
+ N_("|FILE|write environment settings also to FILE")},
{0}
};
@@ -438,6 +441,7 @@ main (int argc, char **argv )
int gpgconf_list = 0;
int standard_socket = 0;
gpg_error_t err;
+ const char *env_file_name = NULL;
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@@ -501,7 +505,7 @@ main (int argc, char **argv )
opt.startup_ttytype = getenv ("TERM");
if (opt.startup_ttytype)
opt.startup_ttytype = xstrdup (opt.startup_ttytype);
- /* Fixme: Neen to use the locale fucntion here. */
+ /* Fixme: Better use the locale function here. */
opt.startup_lc_ctype = getenv ("LC_CTYPE");
if (opt.startup_lc_ctype)
opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype);
@@ -619,6 +623,7 @@ main (int argc, char **argv )
case oKeepDISPLAY: opt.keep_display = 1; break;
case oSSHSupport: opt.ssh_support = 1; break;
+ case oWriteEnvFile: env_file_name = pargs.r.ret_str; break;
default : pargs.err = configfp? 1:2; break;
}
@@ -855,6 +860,29 @@ main (int argc, char **argv )
if (opt.ssh_support)
*socket_name_ssh = 0;
+ if (env_file_name)
+ {
+ FILE *fp;
+
+ fp = fopen (env_file_name, "w");
+ if (!fp)
+ log_error (_("error creating `%s': %s\n"),
+ env_file_name, strerror (errno));
+ else
+ {
+ fputs (infostr, fp);
+ putc ('\n', fp);
+ if (opt.ssh_support)
+ {
+ fputs (infostr_ssh_sock, fp);
+ putc ('\n', fp);
+ fputs (infostr_ssh_pid, fp);
+ putc ('\n', fp);
+ }
+ fclose (fp);
+ }
+ }
+
if (argc)
{ /* Run the program given on the commandline. */
@@ -1273,7 +1301,7 @@ create_directories (void)
static void
handle_tick (void)
{
- /* Check whether the scdaemon has dies and cleanup in this case. */
+ /* Check whether the scdaemon has died and cleanup in this case. */
agent_scd_check_aliveness ();
/* If we are running as a child of another process, check whether
@@ -1311,6 +1339,7 @@ handle_signal (int signo)
case SIGUSR1:
log_info ("SIGUSR1 received - printing internal information:\n");
pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ());
+ agent_scd_dump_state ();
break;
case SIGUSR2:
@@ -1353,7 +1382,8 @@ start_connection_thread (void *arg)
int fd = (int)arg;
if (opt.verbose)
- log_info (_("handler for fd %d started\n"), fd);
+ log_info (_("handler 0x%lx for fd %d started\n"),
+ (long)pth_self (), fd);
/* FIXME: Move this housekeeping into a ticker function. Calling it
for each connection should work but won't work anymore if our
@@ -1362,7 +1392,8 @@ start_connection_thread (void *arg)
start_command_handler (-1, fd);
if (opt.verbose)
- log_info (_("handler for fd %d terminated\n"), fd);
+ log_info (_("handler 0x%lx for fd %d terminated\n"),
+ (long)pth_self (), fd);
return NULL;
}
@@ -1375,13 +1406,15 @@ start_connection_thread_ssh (void *arg)
int fd = (int)arg;
if (opt.verbose)
- log_info (_("ssh handler for fd %d started\n"), fd);
+ log_info (_("ssh handler 0x%lx for fd %d started\n"),
+ (long)pth_self (), fd);
agent_trustlist_housekeeping ();
start_command_handler_ssh (fd);
if (opt.verbose)
- log_info (_("ssh handler for fd %d terminated\n"), fd);
+ log_info (_("ssh handler 0x%lx for fd %d terminated\n"),
+ (long)pth_self (), fd);
return NULL;
}
@@ -1405,15 +1438,17 @@ handle_connections (int listen_fd, int listen_fd_ssh)
tattr = pth_attr_new();
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
- pth_attr_set (tattr, PTH_ATTR_NAME, "gpg-agent");
#ifndef HAVE_W32_SYSTEM /* fixme */
+ /* Make sure that the signals we are going to handle are not blocked
+ and create an event object for them. */
sigemptyset (&sigs );
sigaddset (&sigs, SIGHUP);
sigaddset (&sigs, SIGUSR1);
sigaddset (&sigs, SIGUSR2);
sigaddset (&sigs, SIGINT);
sigaddset (&sigs, SIGTERM);
+ pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
#else
ev = NULL;
@@ -1427,6 +1462,8 @@ handle_connections (int listen_fd, int listen_fd_ssh)
for (;;)
{
+ sigset_t oldsigs;
+
if (shutdown_pending)
{
if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1)
@@ -1488,6 +1525,12 @@ handle_connections (int listen_fd, int listen_fd_ssh)
handle_tick ();
}
+
+ /* We now might create new threads and because we don't want any
+ signals - we are handling here - to be delivered to a new
+ thread. Thus we need to block those signals. */
+ pth_sigmask (SIG_BLOCK, &sigs, &oldsigs);
+
if (FD_ISSET (listen_fd, &read_fdset))
{
plen = sizeof paddr;
@@ -1496,12 +1539,20 @@ handle_connections (int listen_fd, int listen_fd_ssh)
{
log_error ("accept failed: %s\n", strerror (errno));
}
- else if (!pth_spawn (tattr, start_connection_thread, (void*)fd))
- {
- log_error ("error spawning connection handler: %s\n",
- strerror (errno) );
- close (fd);
- }
+ else
+ {
+ char threadname[50];
+ snprintf (threadname, sizeof threadname-1,
+ "conn fd=%d (gpg)", fd);
+ threadname[sizeof threadname -1] = 0;
+ pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
+ if (!pth_spawn (tattr, start_connection_thread, (void*)fd))
+ {
+ log_error ("error spawning connection handler: %s\n",
+ strerror (errno) );
+ close (fd);
+ }
+ }
fd = -1;
}
@@ -1513,14 +1564,27 @@ handle_connections (int listen_fd, int listen_fd_ssh)
{
log_error ("accept failed for ssh: %s\n", strerror (errno));
}
- else if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd))
- {
- log_error ("error spawning ssh connection handler: %s\n",
- strerror (errno) );
- close (fd);
- }
+ else
+ {
+ char threadname[50];
+ snprintf (threadname, sizeof threadname-1,
+ "conn fd=%d (ssh)", fd);
+ threadname[sizeof threadname -1] = 0;
+ pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
+
+ if (!pth_spawn (tattr, start_connection_thread_ssh, (void*)fd))
+ {
+ log_error ("error spawning ssh connection handler: %s\n",
+ strerror (errno) );
+ close (fd);
+ }
+ }
fd = -1;
}
+
+ /* Restore the signal mask. */
+ pth_sigmask (SIG_SETMASK, &oldsigs, NULL);
+
}
pth_event_free (ev, PTH_FREE_ALL);