]> andersk Git - openssh.git/commitdiff
- dtucker@cvs.openbsd.org 2007/03/19 12:16:42
authordtucker <dtucker>
Wed, 21 Mar 2007 09:45:06 +0000 (09:45 +0000)
committerdtucker <dtucker>
Wed, 21 Mar 2007 09:45:06 +0000 (09:45 +0000)
     [ssh-agent.c]
     Remove the signal handler that checks if the agent's parent process
     has gone away, instead check when the select loop returns.  Record when
     the next key will expire when scanning for expired keys.  Set the select
     timeout to whichever of these two things happens next.  With djm@, with &
     ok deraadt@ markus@

ChangeLog
ssh-agent.c

index db4afe47c848148818b9e707b02622d05f35fe54..246a0ea49294efad61286d34512ee0081a8009bb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
      a configuration override. In the future, we will change the
      server's default itself so users who need the legacy protocol
      will need to turn it on explicitly
+   - dtucker@cvs.openbsd.org 2007/03/19 12:16:42
+     [ssh-agent.c]
+     Remove the signal handler that checks if the agent's parent process
+     has gone away, instead check when the select loop returns.  Record when
+     the next key will expire when scanning for expired keys.  Set the select
+     timeout to whichever of these two things happens next.  With djm@, with &
+     ok deraadt@ markus@
 
 20070313
  - (dtucker) [entropy.c scard-opensc.c ssh-rand-helper.c] Bug #1294: include
index a3a867c33b70e7a191c1608eb862f11b7ed34988..c3d5e5a757d9409a4e6289c8c43841ab44f2c6da 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.154 2007/02/28 00:55:30 dtucker Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.155 2007/03/19 12:16:42 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -120,6 +120,7 @@ int max_fd = 0;
 
 /* pid of shell == parent of agent */
 pid_t parent_pid = -1;
+u_int parent_alive_interval = 0;
 
 /* pathname and directory for AUTH_SOCKET */
 char socket_name[MAXPATHLEN];
@@ -421,10 +422,11 @@ process_remove_all_identities(SocketEntry *e, int version)
        buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
 }
 
-static void
+/* removes expired keys and returns number of seconds until the next expiry */
+static u_int
 reaper(void)
 {
-       u_int now = time(NULL);
+       u_int deadline = 0, now = time(NULL);
        Identity *id, *nxt;
        int version;
        Idtab *tab;
@@ -433,14 +435,22 @@ reaper(void)
                tab = idtab_lookup(version);
                for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
                        nxt = TAILQ_NEXT(id, next);
-                       if (id->death != 0 && now >= id->death) {
+                       if (id->death == 0)
+                               continue;
+                       if (now >= id->death) {
                                debug("expiring key '%s'", id->comment);
                                TAILQ_REMOVE(&tab->idlist, id, next);
                                free_identity(id);
                                tab->nentries--;
-                       }
+                       } else
+                               deadline = (deadline == 0) ? id->death :
+                                   MIN(deadline, id->death);
                }
        }
+       if (deadline == 0 || deadline <= now)
+               return 0;
+       else
+               return (deadline - now);
 }
 
 static void
@@ -826,10 +836,12 @@ new_socket(sock_type type, int fd)
 }
 
 static int
-prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp)
+prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
+    struct timeval **tvpp)
 {
-       u_int i, sz;
+       u_int i, sz, deadline;
        int n = 0;
+       static struct timeval tv;
 
        for (i = 0; i < sockets_alloc; i++) {
                switch (sockets[i].type) {
@@ -873,6 +885,17 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp)
                        break;
                }
        }
+       deadline = reaper();
+       if (parent_alive_interval != 0)
+               deadline = (deadline == 0) ? parent_alive_interval :
+                   MIN(deadline, parent_alive_interval);
+       if (deadline == 0) {
+               *tvpp = NULL;
+       } else {
+               tv.tv_sec = deadline;
+               tv.tv_usec = 0;
+               *tvpp = &tv;
+       }
        return (1);
 }
 
@@ -980,19 +1003,14 @@ cleanup_handler(int sig)
        _exit(2);
 }
 
-/*ARGSUSED*/
 static void
-check_parent_exists(int sig)
+check_parent_exists(void)
 {
-       int save_errno = errno;
-
        if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
                /* printf("Parent has died - Authentication agent exiting.\n"); */
-               cleanup_handler(sig); /* safe */
+               cleanup_socket();
+               _exit(2);
        }
-       mysignal(SIGALRM, check_parent_exists);
-       alarm(10);
-       errno = save_errno;
 }
 
 static void
@@ -1027,7 +1045,7 @@ main(int ac, char **av)
        extern char *optarg;
        pid_t pid;
        char pidstrbuf[1 + 3 * sizeof pid];
-       struct timeval tv;
+       struct timeval *tvp = NULL;
 
        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
        sanitise_stdfd();
@@ -1228,10 +1246,8 @@ main(int ac, char **av)
 
 skip:
        new_socket(AUTH_SOCKET, sock);
-       if (ac > 0) {
-               mysignal(SIGALRM, check_parent_exists);
-               alarm(10);
-       }
+       if (ac > 0)
+               parent_alive_interval = 10;
        idtab_init();
        if (!d_flag)
                signal(SIGINT, SIG_IGN);
@@ -1241,12 +1257,12 @@ skip:
        nalloc = 0;
 
        while (1) {
-               tv.tv_sec = 10;
-               tv.tv_usec = 0;
-               prepare_select(&readsetp, &writesetp, &max_fd, &nalloc);
-               result = select(max_fd + 1, readsetp, writesetp, NULL, &tv);
+               prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
+               result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
                saved_errno = errno;
-               reaper();       /* remove expired keys */
+               if (parent_alive_interval != 0)
+                       check_parent_exists();
+               (void) reaper();        /* remove expired keys */
                if (result < 0) {
                        if (saved_errno == EINTR)
                                continue;
This page took 0.246347 seconds and 5 git commands to generate.