mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-28 22:49:59 +01:00
agent: Use a thread to monitor socket takeover.
* agent/gpg-agent.c (check_own_socket_running): Remove. (socket_takeover_detected): New. (check_own_socket): Remove. (handle_tick): Don't call check_own_socket any more. (handle_connections): Start off the check_own_socket_thread. Check socket_takeover_detected to handle the event. (do_check_own_socket): New, factoring out the task. (check_own_socket_thread): Loop with the interval. -- GnuPG-bug-id: 6692 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
9dd8fd4ae4
commit
95186ae92f
@ -384,9 +384,6 @@ static int startup_signal_mask_valid;
|
|||||||
/* Flag to indicate that a shutdown was requested. */
|
/* Flag to indicate that a shutdown was requested. */
|
||||||
static int shutdown_pending;
|
static int shutdown_pending;
|
||||||
|
|
||||||
/* Counter for the currently running own socket checks. */
|
|
||||||
static int check_own_socket_running;
|
|
||||||
|
|
||||||
/* Flags to indicate that check_own_socket shall not be called. */
|
/* Flags to indicate that check_own_socket shall not be called. */
|
||||||
static int disable_check_own_socket;
|
static int disable_check_own_socket;
|
||||||
|
|
||||||
@ -396,6 +393,9 @@ static int is_supervised;
|
|||||||
/* Flag indicating to start the daemon even if one already runs. */
|
/* Flag indicating to start the daemon even if one already runs. */
|
||||||
static int steal_socket;
|
static int steal_socket;
|
||||||
|
|
||||||
|
/* Flag to monitor socket takeover. */
|
||||||
|
static int socket_takeover_detected;
|
||||||
|
|
||||||
/* Flag to inhibit socket removal in cleanup. */
|
/* Flag to inhibit socket removal in cleanup. */
|
||||||
static int inhibit_socket_removal;
|
static int inhibit_socket_removal;
|
||||||
|
|
||||||
@ -528,8 +528,8 @@ static void handle_connections (gnupg_fd_t listen_fd,
|
|||||||
gnupg_fd_t listen_fd_extra,
|
gnupg_fd_t listen_fd_extra,
|
||||||
gnupg_fd_t listen_fd_browser,
|
gnupg_fd_t listen_fd_browser,
|
||||||
gnupg_fd_t listen_fd_ssh);
|
gnupg_fd_t listen_fd_ssh);
|
||||||
static void check_own_socket (void);
|
|
||||||
static int check_for_running_agent (int silent);
|
static int check_for_running_agent (int silent);
|
||||||
|
static void *check_own_socket_thread (void *arg);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2442,12 +2442,8 @@ create_directories (void)
|
|||||||
static void
|
static void
|
||||||
handle_tick (void)
|
handle_tick (void)
|
||||||
{
|
{
|
||||||
static time_t last_minute;
|
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
if (!last_minute)
|
|
||||||
last_minute = time (NULL);
|
|
||||||
|
|
||||||
/* If we are running as a child of another process, check whether
|
/* If we are running as a child of another process, check whether
|
||||||
the parent is still alive and shutdown if not. */
|
the parent is still alive and shutdown if not. */
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#ifndef HAVE_W32_SYSTEM
|
||||||
@ -2464,15 +2460,6 @@ handle_tick (void)
|
|||||||
}
|
}
|
||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
/* Code to be run from time to time. */
|
|
||||||
#if CHECK_OWN_SOCKET_INTERVAL > 0
|
|
||||||
if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
|
|
||||||
{
|
|
||||||
check_own_socket ();
|
|
||||||
last_minute = time (NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Need to check for expired cache entries. */
|
/* Need to check for expired cache entries. */
|
||||||
agent_cache_housekeeping ();
|
agent_cache_housekeeping ();
|
||||||
|
|
||||||
@ -3099,6 +3086,15 @@ handle_connections (gnupg_fd_t listen_fd,
|
|||||||
else
|
else
|
||||||
have_homedir_inotify = 1;
|
have_homedir_inotify = 1;
|
||||||
|
|
||||||
|
if (!disable_check_own_socket)
|
||||||
|
{
|
||||||
|
npth_t thread;
|
||||||
|
|
||||||
|
err = npth_create (&thread, &tattr, check_own_socket_thread, NULL);
|
||||||
|
if (err)
|
||||||
|
log_error ("error spawning check_own_socket_thread: %s\n", strerror (err));
|
||||||
|
}
|
||||||
|
|
||||||
/* On Windows we need to fire up a separate thread to listen for
|
/* On Windows we need to fire up a separate thread to listen for
|
||||||
requests from Putty (an SSH client), so we can replace Putty's
|
requests from Putty (an SSH client), so we can replace Putty's
|
||||||
Pageant (its ssh-agent implementation). */
|
Pageant (its ssh-agent implementation). */
|
||||||
@ -3278,6 +3274,15 @@ handle_connections (gnupg_fd_t listen_fd,
|
|||||||
log_info ("homedir has been removed - shutting down\n");
|
log_info ("homedir has been removed - shutting down\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (socket_takeover_detected)
|
||||||
|
{
|
||||||
|
/* We may not remove the socket as it is now in use by another
|
||||||
|
server. */
|
||||||
|
inhibit_socket_removal = 1;
|
||||||
|
shutdown_pending = 2;
|
||||||
|
log_info ("this process is useless - shutting down\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!shutdown_pending)
|
if (!shutdown_pending)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
@ -3358,20 +3363,18 @@ check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The thread running the actual check. We need to run this in a
|
/* Check whether we are still listening on our own socket. In case
|
||||||
separate thread so that check_own_thread can be called from the
|
another gpg-agent process started after us has taken ownership of
|
||||||
timer tick. */
|
our socket, we would linger around without any real task. Thus we
|
||||||
static void *
|
better check once in a while whether we are really needed. */
|
||||||
check_own_socket_thread (void *arg)
|
static int
|
||||||
|
do_check_own_socket (const char *sockname)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char *sockname = arg;
|
|
||||||
assuan_context_t ctx = NULL;
|
assuan_context_t ctx = NULL;
|
||||||
membuf_t mb;
|
membuf_t mb;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
check_own_socket_running++;
|
|
||||||
|
|
||||||
rc = assuan_new (&ctx);
|
rc = assuan_new (&ctx);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -3409,57 +3412,37 @@ check_own_socket_thread (void *arg)
|
|||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
xfree (sockname);
|
|
||||||
if (ctx)
|
if (ctx)
|
||||||
assuan_release (ctx);
|
assuan_release (ctx);
|
||||||
if (rc)
|
|
||||||
{
|
return rc;
|
||||||
/* We may not remove the socket as it is now in use by another
|
|
||||||
server. */
|
|
||||||
inhibit_socket_removal = 1;
|
|
||||||
shutdown_pending = 2;
|
|
||||||
log_info ("this process is useless - shutting down\n");
|
|
||||||
}
|
|
||||||
check_own_socket_running--;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The thread running the actual check. */
|
||||||
/* Check whether we are still listening on our own socket. In case
|
static void *
|
||||||
another gpg-agent process started after us has taken ownership of
|
check_own_socket_thread (void *arg)
|
||||||
our socket, we would linger around without any real task. Thus we
|
|
||||||
better check once in a while whether we are really needed. */
|
|
||||||
static void
|
|
||||||
check_own_socket (void)
|
|
||||||
{
|
{
|
||||||
char *sockname;
|
char *sockname;
|
||||||
npth_t thread;
|
|
||||||
npth_attr_t tattr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (disable_check_own_socket)
|
(void)arg;
|
||||||
return;
|
|
||||||
|
|
||||||
if (check_own_socket_running || shutdown_pending)
|
|
||||||
return; /* Still running or already shutting down. */
|
|
||||||
|
|
||||||
sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
|
sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
|
||||||
if (!sockname)
|
if (!sockname)
|
||||||
return; /* Out of memory. */
|
return NULL; /* Out of memory. */
|
||||||
|
|
||||||
err = npth_attr_init (&tattr);
|
while (1)
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
xfree (sockname);
|
if (do_check_own_socket (sockname))
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
|
|
||||||
err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
|
|
||||||
if (err)
|
|
||||||
log_error ("error spawning check_own_socket_thread: %s\n", strerror (err));
|
|
||||||
npth_attr_destroy (&tattr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
gnupg_sleep (CHECK_OWN_SOCKET_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (sockname);
|
||||||
|
socket_takeover_detected = 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Figure out whether an agent is available and running. Prints an
|
/* Figure out whether an agent is available and running. Prints an
|
||||||
|
Loading…
x
Reference in New Issue
Block a user