summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@cvs.openbsd.org>2007-03-19 12:16:43 +0000
committerDarren Tucker <dtucker@cvs.openbsd.org>2007-03-19 12:16:43 +0000
commita3c761c8739ef6987e743e285f2499f3f8f55f9d (patch)
tree2e420fd8cb385e4122c207f3489416101f3e52df
parentb860e97dd423cf165913bcec8f4e8478001e2614 (diff)
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@
-rw-r--r--usr.bin/ssh/ssh-agent.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c
index 43ffe77f9c7..cc42f729b45 100644
--- a/usr.bin/ssh/ssh-agent.c
+++ b/usr.bin/ssh/ssh-agent.c
@@ -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
@@ -107,6 +107,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];
@@ -408,10 +409,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;
@@ -420,14 +422,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
@@ -813,10 +823,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) {
@@ -860,6 +872,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);
}
@@ -967,19 +990,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);
}
- signal(SIGALRM, check_parent_exists);
- alarm(10);
- errno = save_errno;
}
static void
@@ -1011,7 +1029,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();
@@ -1198,10 +1216,8 @@ main(int ac, char **av)
skip:
new_socket(AUTH_SOCKET, sock);
- if (ac > 0) {
- signal(SIGALRM, check_parent_exists);
- alarm(10);
- }
+ if (ac > 0)
+ parent_alive_interval = 10;
idtab_init();
if (!d_flag)
signal(SIGINT, SIG_IGN);
@@ -1211,12 +1227,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;