summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2007-03-21 20:45:06 +1100
committerDarren Tucker <dtucker@zip.com.au>2007-03-21 20:45:06 +1100
commit2812dc92859ab0dc095d38494d651bd83f3c1dc5 (patch)
treeaa0115ee3c27eea2100e198f39ef262741a315f7 /ssh-agent.c
parent506ed88cef81bdaed373e90204090e27711633ff (diff)
- 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@
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index a3a867c33..c3d5e5a75 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.154 2007/02/28 00:55:30 dtucker Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.155 2007/03/19 12:16:42 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -120,6 +120,7 @@ int max_fd = 0;
120 120
121/* pid of shell == parent of agent */ 121/* pid of shell == parent of agent */
122pid_t parent_pid = -1; 122pid_t parent_pid = -1;
123u_int parent_alive_interval = 0;
123 124
124/* pathname and directory for AUTH_SOCKET */ 125/* pathname and directory for AUTH_SOCKET */
125char socket_name[MAXPATHLEN]; 126char socket_name[MAXPATHLEN];
@@ -421,10 +422,11 @@ process_remove_all_identities(SocketEntry *e, int version)
421 buffer_put_char(&e->output, SSH_AGENT_SUCCESS); 422 buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
422} 423}
423 424
424static void 425/* removes expired keys and returns number of seconds until the next expiry */
426static u_int
425reaper(void) 427reaper(void)
426{ 428{
427 u_int now = time(NULL); 429 u_int deadline = 0, now = time(NULL);
428 Identity *id, *nxt; 430 Identity *id, *nxt;
429 int version; 431 int version;
430 Idtab *tab; 432 Idtab *tab;
@@ -433,14 +435,22 @@ reaper(void)
433 tab = idtab_lookup(version); 435 tab = idtab_lookup(version);
434 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 436 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
435 nxt = TAILQ_NEXT(id, next); 437 nxt = TAILQ_NEXT(id, next);
436 if (id->death != 0 && now >= id->death) { 438 if (id->death == 0)
439 continue;
440 if (now >= id->death) {
437 debug("expiring key '%s'", id->comment); 441 debug("expiring key '%s'", id->comment);
438 TAILQ_REMOVE(&tab->idlist, id, next); 442 TAILQ_REMOVE(&tab->idlist, id, next);
439 free_identity(id); 443 free_identity(id);
440 tab->nentries--; 444 tab->nentries--;
441 } 445 } else
446 deadline = (deadline == 0) ? id->death :
447 MIN(deadline, id->death);
442 } 448 }
443 } 449 }
450 if (deadline == 0 || deadline <= now)
451 return 0;
452 else
453 return (deadline - now);
444} 454}
445 455
446static void 456static void
@@ -826,10 +836,12 @@ new_socket(sock_type type, int fd)
826} 836}
827 837
828static int 838static int
829prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp) 839prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
840 struct timeval **tvpp)
830{ 841{
831 u_int i, sz; 842 u_int i, sz, deadline;
832 int n = 0; 843 int n = 0;
844 static struct timeval tv;
833 845
834 for (i = 0; i < sockets_alloc; i++) { 846 for (i = 0; i < sockets_alloc; i++) {
835 switch (sockets[i].type) { 847 switch (sockets[i].type) {
@@ -873,6 +885,17 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp)
873 break; 885 break;
874 } 886 }
875 } 887 }
888 deadline = reaper();
889 if (parent_alive_interval != 0)
890 deadline = (deadline == 0) ? parent_alive_interval :
891 MIN(deadline, parent_alive_interval);
892 if (deadline == 0) {
893 *tvpp = NULL;
894 } else {
895 tv.tv_sec = deadline;
896 tv.tv_usec = 0;
897 *tvpp = &tv;
898 }
876 return (1); 899 return (1);
877} 900}
878 901
@@ -980,19 +1003,14 @@ cleanup_handler(int sig)
980 _exit(2); 1003 _exit(2);
981} 1004}
982 1005
983/*ARGSUSED*/
984static void 1006static void
985check_parent_exists(int sig) 1007check_parent_exists(void)
986{ 1008{
987 int save_errno = errno;
988
989 if (parent_pid != -1 && kill(parent_pid, 0) < 0) { 1009 if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
990 /* printf("Parent has died - Authentication agent exiting.\n"); */ 1010 /* printf("Parent has died - Authentication agent exiting.\n"); */
991 cleanup_handler(sig); /* safe */ 1011 cleanup_socket();
1012 _exit(2);
992 } 1013 }
993 mysignal(SIGALRM, check_parent_exists);
994 alarm(10);
995 errno = save_errno;
996} 1014}
997 1015
998static void 1016static void
@@ -1027,7 +1045,7 @@ main(int ac, char **av)
1027 extern char *optarg; 1045 extern char *optarg;
1028 pid_t pid; 1046 pid_t pid;
1029 char pidstrbuf[1 + 3 * sizeof pid]; 1047 char pidstrbuf[1 + 3 * sizeof pid];
1030 struct timeval tv; 1048 struct timeval *tvp = NULL;
1031 1049
1032 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1050 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1033 sanitise_stdfd(); 1051 sanitise_stdfd();
@@ -1228,10 +1246,8 @@ main(int ac, char **av)
1228 1246
1229skip: 1247skip:
1230 new_socket(AUTH_SOCKET, sock); 1248 new_socket(AUTH_SOCKET, sock);
1231 if (ac > 0) { 1249 if (ac > 0)
1232 mysignal(SIGALRM, check_parent_exists); 1250 parent_alive_interval = 10;
1233 alarm(10);
1234 }
1235 idtab_init(); 1251 idtab_init();
1236 if (!d_flag) 1252 if (!d_flag)
1237 signal(SIGINT, SIG_IGN); 1253 signal(SIGINT, SIG_IGN);
@@ -1241,12 +1257,12 @@ skip:
1241 nalloc = 0; 1257 nalloc = 0;
1242 1258
1243 while (1) { 1259 while (1) {
1244 tv.tv_sec = 10; 1260 prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
1245 tv.tv_usec = 0; 1261 result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
1246 prepare_select(&readsetp, &writesetp, &max_fd, &nalloc);
1247 result = select(max_fd + 1, readsetp, writesetp, NULL, &tv);
1248 saved_errno = errno; 1262 saved_errno = errno;
1249 reaper(); /* remove expired keys */ 1263 if (parent_alive_interval != 0)
1264 check_parent_exists();
1265 (void) reaper(); /* remove expired keys */
1250 if (result < 0) { 1266 if (result < 0) {
1251 if (saved_errno == EINTR) 1267 if (saved_errno == EINTR)
1252 continue; 1268 continue;