]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
ssh-agent: exit 0 from SIGTERM under systemd socket-activation
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Wed, 16 Apr 2025 00:18:34 +0000 (10:18 +1000)
committerDamien Miller <djm@mindrot.org>
Thu, 8 May 2025 00:08:30 +0000 (10:08 +1000)
When the ssh-agent service is configured to be launched under systemd
socket-activation, the user can inspect the status of the agent with
something like:

    systemctl --user status ssh-agent.service

If the user does:

    systemctl --user stop ssh-agent.service

it causes the `systemd --user` supervisor to send a SIGTERM to the
agent, which terminates while leaving the systemd-managed socket in
place.  That's good, and as expected. (If the user wants to close the
socket, they can do "systemctl --user stop ssh-agent.socket" instead)

But because ssh-agent exits with code 2 in response to a SIGTERM, the
supervisor marks the service as "failed", even though the state of the
supervised service is exactly the same as during session startup (not
running, ready to launch when a client connects to the socket).

This change makes ssh-agent exit cleanly (code 0) in response to a
SIGTERM when launched under socket activation. This aligns the systemd
supervisor's understanding of the state of supervised ssh-agent with
reality.

Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
ssh-agent.c

index 8a88ef3fd1c0a9e763506677b05486b6f70e6e00..d82b351d04b643183a0985432046771a03978fc2 100644 (file)
@@ -2241,6 +2241,7 @@ main(int ac, char **av)
        size_t npfd = 0;
        u_int maxfds;
        sigset_t nsigset, osigset;
+       int socket_activated = 0;
 
        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
        sanitise_stdfd();
@@ -2414,6 +2415,7 @@ main(int ac, char **av)
                        fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid());
                debug("using socket activation on fd=3");
                sock = 3;
+               socket_activated = 1;
        }
 
        if (sock == -1 && agentsocket == NULL && !T_flag) {
@@ -2577,7 +2579,8 @@ skip:
                sigprocmask(SIG_BLOCK, &nsigset, &osigset);
                if (signalled_exit != 0) {
                        logit("exiting on signal %d", (int)signalled_exit);
-                       cleanup_exit(2);
+                       cleanup_exit((signalled_exit == SIGTERM &&
+                           socket_activated) ? 0 : 2);
                }
                if (signalled_keydrop) {
                        logit("signal %d received; removing all keys",