diff options
author | NIIBE Yutaka <[email protected]> | 2023-08-30 01:57:36 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2023-08-30 01:57:36 +0000 |
commit | 95186ae92f923df6240f1b677cbaf130c4f64fae (patch) | |
tree | 88b7484c4dfa9bb523f1c52126c34ab453da1be4 | |
parent | g13: Fix for new assuan_control. (diff) | |
download | gnupg-95186ae92f923df6240f1b677cbaf130c4f64fae.tar.gz gnupg-95186ae92f923df6240f1b677cbaf130c4f64fae.zip |
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 <[email protected]>
-rw-r--r-- | agent/gpg-agent.c | 107 |
1 files changed, 45 insertions, 62 deletions
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index dd38528bb..a493e2a98 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -384,9 +384,6 @@ static int startup_signal_mask_valid; /* Flag to indicate that a shutdown was requested. */ 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. */ 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. */ static int steal_socket; +/* Flag to monitor socket takeover. */ +static int socket_takeover_detected; + /* Flag to inhibit socket removal in cleanup. */ 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_browser, gnupg_fd_t listen_fd_ssh); -static void check_own_socket (void); 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 handle_tick (void) { - static time_t last_minute; struct stat statbuf; - if (!last_minute) - last_minute = time (NULL); - /* If we are running as a child of another process, check whether the parent is still alive and shutdown if not. */ #ifndef HAVE_W32_SYSTEM @@ -2464,15 +2460,6 @@ handle_tick (void) } #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. */ agent_cache_housekeeping (); @@ -3099,6 +3086,15 @@ handle_connections (gnupg_fd_t listen_fd, else 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 requests from Putty (an SSH client), so we can replace Putty's 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"); } + 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) { 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 - separate thread so that check_own_thread can be called from the - timer tick. */ -static void * -check_own_socket_thread (void *arg) +/* Check whether we are still listening on our own socket. In case + another gpg-agent process started after us has taken ownership of + our socket, we would linger around without any real task. Thus we + better check once in a while whether we are really needed. */ +static int +do_check_own_socket (const char *sockname) { int rc; - char *sockname = arg; assuan_context_t ctx = NULL; membuf_t mb; char *buffer; - check_own_socket_running++; - rc = assuan_new (&ctx); if (rc) { @@ -3409,57 +3412,37 @@ check_own_socket_thread (void *arg) xfree (buffer); leave: - xfree (sockname); if (ctx) assuan_release (ctx); - if (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; -} + return rc; +} -/* Check whether we are still listening on our own socket. In case - another gpg-agent process started after us has taken ownership of - 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) +/* The thread running the actual check. */ +static void * +check_own_socket_thread (void *arg) { char *sockname; - npth_t thread; - npth_attr_t tattr; - int err; - - if (disable_check_own_socket) - return; - if (check_own_socket_running || shutdown_pending) - return; /* Still running or already shutting down. */ + (void)arg; sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); if (!sockname) - return; /* Out of memory. */ + return NULL; /* Out of memory. */ - err = npth_attr_init (&tattr); - if (err) + while (1) { - xfree (sockname); - return; + if (do_check_own_socket (sockname)) + break; + + gnupg_sleep (CHECK_OWN_SOCKET_INTERVAL); } - 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); -} + xfree (sockname); + socket_takeover_detected = 1; + + return NULL; +} /* Figure out whether an agent is available and running. Prints an |