1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Changed the scdaemon to handle concurrent sessions. Adjusted

gpg-agent accordingly. Code cleanups.
This commit is contained in:
Werner Koch 2005-05-18 10:48:06 +00:00
parent a5c4c4bf12
commit 4237a9cc7f
27 changed files with 1093 additions and 644 deletions

View file

@ -1,3 +1,19 @@
2005-05-18 Werner Koch <wk@g10code.com>
* divert-scd.c (ask_for_card): Removed the card reset kludge.
2005-05-17 Werner Koch <wk@g10code.com>
* call-scd.c (unlock_scd): Add new arg CTRL. Changed all callers.
(start_scd): Reoworked to allow for additional connections.
* agent.h (ctrl_t): Add local data for the SCdaemon.
* command.c (start_command_handler): Release SERVER_LOCAL.
* gpg-agent.c (create_server_socket): Use xmalloc.
(main): Removed option --disable-pth a dummy. Removed non-pth
code path.
(cleanup_sh): Removed. Not needed anymore.
2005-05-05 Moritz Schulte <moritz@g10code.com>
* command-ssh.c (ssh_key_to_buffer): Rename to ...

View file

@ -99,10 +99,19 @@ struct {
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
struct server_local_s;
struct scd_local_s;
/* Collection of data per session (aka connection). */
struct server_control_s {
/* Private data of the server (command.c). */
struct server_local_s *server_local;
/* Private data of the SCdaemon (call-scd.c). */
struct scd_local_s *scd_local;
int connection_fd; /* -1 or an identifier for the current connection. */
char *display;
char *ttyname;
char *ttytype;

View file

@ -18,12 +18,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* Fixme: For now we have serialized all access to the scdaemon which
make sense becuase the scdaemon can't handle concurrent connections
right now. We should however keep a list of connections and lock
just that connection - it migth make sense to implemtn parts of
this in Assuan.*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
@ -37,9 +31,7 @@
#ifndef HAVE_W32_SYSTEM
#include <sys/wait.h>
#endif
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include <pth.h>
#include "agent.h"
#include <assuan.h>
@ -50,24 +42,20 @@
#define MAX_OPEN_FDS 20
#endif
static ASSUAN_CONTEXT scd_ctx = NULL;
#ifdef USE_GNU_PTH
static pth_mutex_t scd_lock;
#endif
/* We need to keep track of the connection currently using the SCD.
For a pipe server this is all a NOP because the connection will
always have the connection indicator -1. agent_reset_scd releases
the active connection; i.e. sets it back to -1, so that a new
connection can start using the SCD. If we eventually allow
multiple SCD session we will either make scdaemon multi-threaded or
fork of a new scdaemon and let it see how it can get access to a
reader.
*/
static int active_connection_fd = -1;
static int active_connection = 0;
/* Definition of module local data of the CTRL structure. */
struct scd_local_s
{
assuan_context_t ctx; /* NULL or session context for the SCdaemon
used with this connection. */
int locked; /* This flag is used to assert proper use of
start_scd and unlock_scd. */
};
/* Callback parameter for learn card */
struct learn_parm_s {
struct learn_parm_s
{
void (*kpinfo_cb)(void*, const char *);
void *kpinfo_cb_arg;
void (*certinfo_cb)(void*, const char *);
@ -76,13 +64,39 @@ struct learn_parm_s {
void *sinfo_cb_arg;
};
struct inq_needpin_s {
ASSUAN_CONTEXT ctx;
struct inq_needpin_s
{
assuan_context_t ctx;
int (*getpin_cb)(void *, const char *, char*, size_t);
void *getpin_cb_arg;
};
/* A Mutex used inside the start_scd function. */
static pth_mutex_t start_scd_lock;
/* A malloced string with the name of the socket to be used for
additional connections. May be NULL if not provided by
SCdaemon. */
static char *socket_name;
/* The context of the primary connection. This is also used as a flag
to indicate whether the scdaemon has been started. */
static assuan_context_t primary_scd_ctx;
/* To allow reuse of the primary connection, the following flag is set
to true if the primary context has been reset and is not in use by
any connection. */
static int primary_scd_ctx_reusable;
/* Local prototypes. */
static assuan_error_t membuf_data_cb (void *opaque,
const void *buffer, size_t length);
/* This function must be called once to initialize this module. This
has to be done before a second thread is spawned. We can't do the
@ -91,27 +105,35 @@ struct inq_needpin_s {
void
initialize_module_call_scd (void)
{
#ifdef USE_GNU_PTH
static int initialized;
if (!initialized)
if (pth_mutex_init (&scd_lock))
{
if (!pth_mutex_init (&start_scd_lock))
log_fatal ("error initializing mutex: %s\n", strerror (errno));
initialized = 1;
#endif /*USE_GNU_PTH*/
}
}
/* 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
"lock" operation is done by the start_scd() function which must be
called and error checked before any SCD operation. CTRL is the
usual connection context and RC the error code to be passed trhough
the function. */
static int
unlock_scd (int rc)
unlock_scd (ctrl_t ctrl, int rc)
{
#ifdef USE_GNU_PTH
if (!pth_mutex_release (&scd_lock))
if (ctrl->scd_local->locked != 1)
{
log_error ("failed to release the SCD lock\n");
log_error ("unlock_scd: invalid lock count (%d)\n",
ctrl->scd_local->locked);
if (!rc)
rc = gpg_error (GPG_ERR_INTERNAL);
}
#endif /*USE_GNU_PTH*/
ctrl->scd_local->locked = 0;
return rc;
}
@ -125,68 +147,115 @@ atfork_cb (void *opaque, int where)
}
/* Fork off the SCdaemon if this has not already been done. Note that
this fucntion alos locks the daemon. */
/* Fork off the SCdaemon if this has not already been done. Lock the
daemon and make sure that a proper context has been setup in CTRL.
Thsi fucntion might also lock the daemon, which means that the
caller must call unlock_scd after this fucntion has returned
success and the actual Assuan transaction been done. */
static int
start_scd (ctrl_t ctrl)
{
int rc;
gpg_error_t err = 0;
const char *pgmname;
ASSUAN_CONTEXT ctx;
const char *argv[3];
assuan_context_t ctx;
const char *argv[4];
int no_close_list[3];
int i;
int rc;
if (opt.disable_scdaemon)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
#ifdef USE_GNU_PTH
if (!pth_mutex_acquire (&scd_lock, 0, NULL))
/* If this is the first call for this session, setup the local data
structure. */
if (!ctrl->scd_local)
{
log_error ("failed to acquire the SCD lock\n");
ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
if (!ctrl->scd_local)
return gpg_error_from_errno (errno);
}
/* Assert that the lock count is as expected. */
if (ctrl->scd_local->locked)
{
log_error ("start_scd: invalid lock count (%d)\n",
ctrl->scd_local->locked);
return gpg_error (GPG_ERR_INTERNAL);
}
#endif
ctrl->scd_local->locked++;
if (scd_ctx)
/* If we already have a context, we better do a sanity check now to
see whether it has accidently died. This avoids annoying
timeouts and hung connections. */
if (ctrl->scd_local->ctx)
{
pid_t pid;
/* If we are not the connection currently using the SCD, return
an error. */
if (!active_connection)
{
active_connection_fd = ctrl->connection_fd;
active_connection = 1;
}
else if (ctrl->connection_fd != active_connection_fd)
return unlock_scd (gpg_error (GPG_ERR_CONFLICT));
/* Okay, we already started the scdaemon and it is used by us.*/
/* We better do a sanity check now to see whether it has
accidently died. */
#ifndef HAVE_W32_SYSTEM
pid = assuan_get_pid (scd_ctx);
pid = assuan_get_pid (ctrl->scd_local->ctx);
if (pid != (pid_t)(-1) && pid
&& ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
{
assuan_disconnect (scd_ctx);
scd_ctx = NULL;
assuan_disconnect (ctrl->scd_local->ctx);
ctrl->scd_local->ctx = NULL;
}
else
#endif
return 0;
return 0; /* Okay, the context is fine. */
}
/* We need to protect the lowwing code. */
if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
{
log_error ("failed to acquire the start_scd lock: %s\n",
strerror (errno));
return gpg_error (GPG_ERR_INTERNAL);
}
/* Check whether the pipe server has already been started and in
this case either reuse a lingering pipe connection or establish a
new socket based one. */
if (primary_scd_ctx && primary_scd_ctx_reusable)
{
ctx = primary_scd_ctx;
primary_scd_ctx_reusable = 0;
if (opt.verbose)
log_info ("new connection to SCdaemon established (reusing)\n");
goto leave;
}
if (socket_name)
{
rc = assuan_socket_connect (&ctx, socket_name, 0);
if (rc)
{
log_error ("can't connect to socket `%s': %s\n",
socket_name, assuan_strerror (rc));
err = gpg_error (GPG_ERR_NO_SCDAEMON);
goto leave;
}
if (opt.verbose)
log_info ("new connection to SCdaemon established\n");
goto leave;
}
if (primary_scd_ctx)
{
log_info ("SCdaemon is running but won't accept further connections\n");
err = gpg_error (GPG_ERR_NO_SCDAEMON);
goto leave;
}
/* Nope, it has not been started. Fire it up now. */
if (opt.verbose)
log_info ("no running SCdaemon - starting it\n");
if (fflush (NULL))
{
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
err = gpg_error (gpg_err_code_from_errno (errno));
log_error ("error flushing pending output: %s\n", strerror (errno));
return unlock_scd (tmperr);
goto leave;
}
if (!opt.scdaemon_program || !*opt.scdaemon_program)
@ -198,7 +267,8 @@ start_scd (ctrl_t ctrl)
argv[0] = pgmname;
argv[1] = "--server";
argv[2] = NULL;
argv[2] = "--multi-server";
argv[3] = NULL;
i=0;
if (!opt.running_detached)
@ -216,30 +286,68 @@ start_scd (ctrl_t ctrl)
{
log_error ("can't connect to the SCdaemon: %s\n",
assuan_strerror (rc));
return unlock_scd (gpg_error (GPG_ERR_NO_SCDAEMON));
err = gpg_error (GPG_ERR_NO_SCDAEMON);
goto leave;
}
scd_ctx = ctx;
active_connection_fd = ctrl->connection_fd;
active_connection = 1;
if (DBG_ASSUAN)
log_debug ("connection to SCdaemon established\n");
if (opt.verbose)
log_debug ("first connection to SCdaemon established\n");
/* Tell the scdaemon that we want him to send us an event signal.
But only do this if we are running as a regular sever and not
simply as a pipe server. */
/* Fixme: gpg-agent does not use this signal yet. */
/* if (ctrl->connection_fd != -1) */
/* { */
/* #ifndef HAVE_W32_SYSTEM */
/* char buf[100]; */
/* Get the name of the additional socket opened by scdaemon. */
{
membuf_t data;
unsigned char *databuf;
size_t datalen;
/* sprintf (buf, "OPTION event-signal=%d", SIGUSR2); */
/* assuan_transact (scd_ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); */
/* #endif */
/* } */
xfree (socket_name);
socket_name = NULL;
init_membuf (&data, 256);
assuan_transact (ctx, "GETINFO socket_name",
membuf_data_cb, &data, NULL, NULL, NULL, NULL);
return 0;
databuf = get_membuf (&data, &datalen);
if (databuf && datalen)
{
socket_name = xtrymalloc (datalen + 1);
if (!socket_name)
log_error ("warning: can't store socket name: %s\n",
strerror (errno));
else
{
memcpy (socket_name, databuf, datalen);
socket_name[datalen] = 0;
if (DBG_ASSUAN)
log_debug ("additional connections at `%s'\n", socket_name);
}
}
xfree (databuf);
}
/* Tell the scdaemon we want him to send us an event signal. */
#ifndef HAVE_W32_SYSTEM
{
char buf[100];
sprintf (buf, "OPTION event-signal=%d", SIGUSR2);
assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
}
#endif
primary_scd_ctx = ctx;
primary_scd_ctx_reusable = 0;
leave:
if (err)
{
unlock_scd (ctrl, err);
}
else
{
ctrl->scd_local->ctx = ctx;
}
if (!pth_mutex_release (&start_scd_lock))
log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
return err;
}
@ -248,25 +356,28 @@ start_scd (ctrl_t ctrl)
int
agent_reset_scd (ctrl_t ctrl)
{
int rc = 0;
#ifdef USE_GNU_PTH
if (!pth_mutex_acquire (&scd_lock, 0, NULL))
if (ctrl->scd_local)
{
log_error ("failed to acquire the SCD lock for reset\n");
return gpg_error (GPG_ERR_INTERNAL);
}
#endif
if (active_connection && active_connection_fd == ctrl->connection_fd)
{
if (scd_ctx)
rc = assuan_transact (scd_ctx, "RESET", NULL, NULL,
NULL, NULL, NULL, NULL);
active_connection_fd = -1;
active_connection = 0;
if (ctrl->scd_local->ctx)
{
/* We can't disconnect the primary context becuase libassuan
does a waitpid on it and thus the system would hang.
Instead we send a reset and keep that connection for
reuse. */
if (ctrl->scd_local->ctx == primary_scd_ctx)
{
if (!assuan_transact (primary_scd_ctx, "RESET",
NULL, NULL, NULL, NULL, NULL, NULL))
primary_scd_ctx_reusable = 1;
}
else
assuan_disconnect (ctrl->scd_local->ctx);
}
xfree (ctrl->scd_local);
ctrl->scd_local = NULL;
}
return unlock_scd (map_assuan_err (rc));
return 0;
}
@ -360,13 +471,13 @@ agent_card_learn (ctrl_t ctrl,
parm.certinfo_cb_arg = certinfo_cb_arg;
parm.sinfo_cb = sinfo_cb;
parm.sinfo_cb_arg = sinfo_cb_arg;
rc = assuan_transact (scd_ctx, "LEARN --force",
rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
NULL, NULL, NULL, NULL,
learn_status_cb, &parm);
if (rc)
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
@ -414,16 +525,16 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno)
if (rc)
return rc;
rc = assuan_transact (scd_ctx, "SERIALNO",
rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
NULL, NULL, NULL, NULL,
get_serialno_cb, &serialno);
if (rc)
{
xfree (serialno);
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
*r_serialno = serialno;
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
@ -495,31 +606,32 @@ agent_card_pksign (ctrl_t ctrl,
return rc;
if (indatalen*2 + 50 > DIM(line))
return unlock_scd (gpg_error (GPG_ERR_GENERAL));
return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
sprintf (line, "SETDATA ");
p = line + strlen (line);
for (i=0; i < indatalen ; i++, p += 2 )
sprintf (p, "%02X", indata[i]);
rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
rc = assuan_transact (ctrl->scd_local->ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
init_membuf (&data, 1024);
inqparm.ctx = scd_ctx;
inqparm.ctx = ctrl->scd_local->ctx;
inqparm.getpin_cb = getpin_cb;
inqparm.getpin_cb_arg = getpin_cb_arg;
snprintf (line, DIM(line)-1,
ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
line[DIM(line)-1] = 0;
rc = assuan_transact (scd_ctx, line,
rc = assuan_transact (ctrl->scd_local->ctx, line,
membuf_data_cb, &data,
inq_needpin, &inqparm,
NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
sigbuf = get_membuf (&data, &sigbuflen);
@ -531,7 +643,7 @@ agent_card_pksign (ctrl_t ctrl,
{
gpg_error_t tmperr = out_of_core ();
xfree (*r_buf);
return unlock_scd (tmperr);
return unlock_scd (ctrl, tmperr);
}
p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" );
sprintf (p, "%u:", (unsigned int)sigbuflen);
@ -542,7 +654,7 @@ agent_card_pksign (ctrl_t ctrl,
xfree (sigbuf);
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
/* Decipher INDATA using the current card. Note that the returned value is */
@ -567,36 +679,37 @@ agent_card_pkdecrypt (ctrl_t ctrl,
/* FIXME: use secure memory where appropriate */
if (indatalen*2 + 50 > DIM(line))
return unlock_scd (gpg_error (GPG_ERR_GENERAL));
return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
sprintf (line, "SETDATA ");
p = line + strlen (line);
for (i=0; i < indatalen ; i++, p += 2 )
sprintf (p, "%02X", indata[i]);
rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
rc = assuan_transact (ctrl->scd_local->ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
init_membuf (&data, 1024);
inqparm.ctx = scd_ctx;
inqparm.ctx = ctrl->scd_local->ctx;
inqparm.getpin_cb = getpin_cb;
inqparm.getpin_cb_arg = getpin_cb_arg;
snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
line[DIM(line)-1] = 0;
rc = assuan_transact (scd_ctx, line,
rc = assuan_transact (ctrl->scd_local->ctx, line,
membuf_data_cb, &data,
inq_needpin, &inqparm,
NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
*r_buf = get_membuf (&data, r_buflen);
if (!*r_buf)
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
@ -619,20 +732,20 @@ agent_card_readcert (ctrl_t ctrl,
init_membuf (&data, 1024);
snprintf (line, DIM(line)-1, "READCERT %s", id);
line[DIM(line)-1] = 0;
rc = assuan_transact (scd_ctx, line,
rc = assuan_transact (ctrl->scd_local->ctx, line,
membuf_data_cb, &data,
NULL, NULL,
NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
*r_buf = get_membuf (&data, r_buflen);
if (!*r_buf)
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
@ -655,26 +768,26 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
init_membuf (&data, 1024);
snprintf (line, DIM(line)-1, "READKEY %s", id);
line[DIM(line)-1] = 0;
rc = assuan_transact (scd_ctx, line,
rc = assuan_transact (ctrl->scd_local->ctx, line,
membuf_data_cb, &data,
NULL, NULL,
NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
*r_buf = get_membuf (&data, &buflen);
if (!*r_buf)
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
{
xfree (*r_buf); *r_buf = NULL;
return unlock_scd (gpg_error (GPG_ERR_INV_VALUE));
return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
}
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}
@ -744,7 +857,7 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
if (err)
return err;
err = map_assuan_err (assuan_transact (scd_ctx, line,
err = map_assuan_err (assuan_transact (ctrl->scd_local->ctx, line,
NULL, NULL, NULL, NULL,
card_getattr_cb, &parm));
if (!err && parm.error)
@ -758,7 +871,7 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
else
xfree (parm.data);
return unlock_scd (err);
return unlock_scd (ctrl, err);
}
@ -810,19 +923,19 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
if (rc)
return rc;
inqparm.ctx = scd_ctx;
inqparm.ctx = ctrl->scd_local->ctx;
inqparm.getpin_cb = getpin_cb;
inqparm.getpin_cb_arg = getpin_cb_arg;
rc = assuan_transact (scd_ctx, cmdline,
rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
pass_data_thru, assuan_context,
inq_needpin, &inqparm,
pass_status_thru, assuan_context);
if (rc)
{
return unlock_scd (map_assuan_err (rc));
return unlock_scd (ctrl, map_assuan_err (rc));
}
return unlock_scd (0);
return unlock_scd (ctrl, 0);
}

View file

@ -1061,5 +1061,6 @@ start_command_handler (int listen_fd, int fd)
free (ctrl.lc_ctype);
if (ctrl.lc_messages)
free (ctrl.lc_messages);
xfree (ctrl.server_local);
}

View file

@ -108,13 +108,6 @@ ask_for_card (CTRL ctrl, const unsigned char *shadow_info, char **r_kid)
if (!rc)
{
/* We better reset the SCD now. This is kludge required
because the scdaemon is currently not always able to
detect the presence of a card. With a fully working
scdaemon this would not be required; i.e. the pkcs#15
support does not require it because OpenSC correclty
detects a present card. */
agent_reset_scd (ctrl);
if (asprintf (&desc,
"%s:%%0A%%0A"
" \"%.*s\"",

View file

@ -37,9 +37,7 @@
#endif /*HAVE_W32_SYSTEM*/
#include <unistd.h>
#include <signal.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include <pth.h>
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
@ -83,7 +81,6 @@ enum cmd_and_opt_values
oLCctype,
oLCmessages,
oScdaemonProgram,
oDisablePth,
oDefCacheTTL,
oMaxCacheTTL,
oUseStandardSocket,
@ -120,7 +117,6 @@ static ARGPARSE_OPTS opts[] = {
{ oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
{ oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")},
{ oLogFile, "log-file" ,2, N_("use a log file for the server")},
{ oDisablePth, "disable-pth", 0, N_("do not allow multiple connections")},
{ oUseStandardSocket, "use-standard-socket", 0,
N_("use a standard location for the socket")},
{ oNoUseStandardSocket, "no-use-standard-socket", 0, "@"},
@ -157,7 +153,6 @@ static ARGPARSE_OPTS opts[] = {
#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */
#define MAX_CACHE_TTL (120*60) /* 2 hours */
static volatile int caught_fatal_sig = 0;
/* flag to indicate that a shutdown was requested */
static int shutdown_pending;
@ -190,10 +185,11 @@ static const char *debug_level;
static char *current_logfile;
/* The handle_tick() function may test whether a parent is still
runing. We record the PID of the parent here or -1 if it should be
running. We record the PID of the parent here or -1 if it should be
watched. */
static pid_t parent_pid = (pid_t)(-1);
/*
Local prototypes.
*/
@ -203,17 +199,15 @@ static char *create_socket_name (int use_standard_socket,
static int create_server_socket (int is_standard_name, const char *name);
static void create_directories (void);
#ifdef USE_GNU_PTH
static void handle_connections (int listen_fd, int listen_fd_ssh);
/* Pth wrapper function definitions. */
GCRY_THREAD_OPTION_PTH_IMPL;
#endif /*USE_GNU_PTH*/
static int check_for_running_agent (int);
/* Pth wrapper function definitions. */
GCRY_THREAD_OPTION_PTH_IMPL;
/*
Functions.
*/
@ -351,28 +345,6 @@ cleanup (void)
}
static RETSIGTYPE
cleanup_sh (int sig)
{
if (caught_fatal_sig)
raise (sig);
caught_fatal_sig = 1;
/* gcry_control( GCRYCTL_TERM_SECMEM );*/
cleanup ();
#ifndef HAVE_DOSISH_SYSTEM
{ /* reset action to default action and raise signal again */
struct sigaction nact;
nact.sa_handler = SIG_DFL;
sigemptyset( &nact.sa_mask );
nact.sa_flags = 0;
sigaction( sig, &nact, NULL);
}
#endif
raise( sig );
}
/* Handle options which are allowed to be reset after program start.
Return true when the current option in PARGS could be handled and
@ -462,7 +434,6 @@ main (int argc, char **argv )
int csh_style = 0;
char *logfile = NULL;
int debug_wait = 0;
int disable_pth = 0;
int gpgconf_list = 0;
int standard_socket = 0;
gpg_error_t err;
@ -481,14 +452,12 @@ main (int argc, char **argv )
/* Libgcrypt requires us to register the threading model first.
Note that this will also do the pth_init. */
#ifdef USE_GNU_PTH
err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
if (err)
{
log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
gpg_strerror (err));
}
#endif /*USE_GNU_PTH*/
/* Check that the libraries are suitable. Do it here because
@ -634,7 +603,6 @@ main (int argc, char **argv )
case oSh: csh_style = 0; break;
case oServer: pipe_server = 1; break;
case oDaemon: is_daemon = 1; break;
case oDisablePth: disable_pth = 1; break;
case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
@ -983,45 +951,17 @@ main (int argc, char **argv )
exit (1);
}
{
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
sigaction (SIGPIPE, &sa, NULL);
}
#endif /*!HAVE_W32_SYSTEM*/
#ifdef USE_GNU_PTH
if (!disable_pth)
{
#ifndef HAVE_W32_SYSTEM /* FIXME */
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
sigaction (SIGPIPE, &sa, NULL);
#endif
handle_connections (fd, opt.ssh_support ? fd_ssh : -1);
}
else
#endif /*!USE_GNU_PTH*/
/* setup signals */
{
#ifndef HAVE_W32_SYSTEM /* FIXME */
struct sigaction oact, nact;
nact.sa_handler = cleanup_sh;
sigemptyset (&nact.sa_mask);
nact.sa_flags = 0;
sigaction (SIGHUP, NULL, &oact);
if (oact.sa_handler != SIG_IGN)
sigaction (SIGHUP, &nact, NULL);
sigaction( SIGTERM, NULL, &oact );
if (oact.sa_handler != SIG_IGN)
sigaction (SIGTERM, &nact, NULL);
nact.sa_handler = SIG_IGN;
sigaction (SIGPIPE, &nact, NULL);
sigaction (SIGINT, &nact, NULL);
#endif
start_command_handler (fd, -1);
}
handle_connections (fd, opt.ssh_support ? fd_ssh : -1);
close (fd);
}
@ -1127,7 +1067,7 @@ reread_configuration (void)
/* Create a name for the socket. With USE_STANDARD_SOCKET given as
true ising STANDARD_NAME in the home directory or if given has
true using STANDARD_NAME in the home directory or if given has
false from the mkdir type name TEMPLATE. In the latter case a
unique name in a unique new directory will be created. In both
cases check for valid characters as well as against a maximum
@ -1195,7 +1135,7 @@ create_server_socket (int is_standard_name, const char *name)
agent_exit (2);
}
serv_addr = malloc (sizeof (*serv_addr)); /* FIXME. */
serv_addr = xmalloc (sizeof (*serv_addr));
memset (serv_addr, 0, sizeof *serv_addr);
serv_addr->sun_family = AF_UNIX;
assert (strlen (name) + 1 < sizeof (serv_addr->sun_path));
@ -1325,7 +1265,6 @@ create_directories (void)
#ifdef USE_GNU_PTH
/* This is the worker for the ticker. It is called every few seconds
and may only do fast operations. */
static void
@ -1581,7 +1520,6 @@ handle_connections (int listen_fd, int listen_fd_ssh)
cleanup ();
log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
}
#endif /*USE_GNU_PTH*/
/* Figure out whether an agent is available and running. Prints an