version 1.154, 2007/02/28 00:55:30 |
version 1.155, 2007/03/19 12:16:42 |
|
|
|
|
/* pid of shell == parent of agent */ |
/* pid of shell == parent of agent */ |
pid_t parent_pid = -1; |
pid_t parent_pid = -1; |
|
u_int parent_alive_interval = 0; |
|
|
/* pathname and directory for AUTH_SOCKET */ |
/* pathname and directory for AUTH_SOCKET */ |
char socket_name[MAXPATHLEN]; |
char socket_name[MAXPATHLEN]; |
|
|
buffer_put_char(&e->output, SSH_AGENT_SUCCESS); |
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) |
reaper(void) |
{ |
{ |
u_int now = time(NULL); |
u_int deadline = 0, now = time(NULL); |
Identity *id, *nxt; |
Identity *id, *nxt; |
int version; |
int version; |
Idtab *tab; |
Idtab *tab; |
|
|
tab = idtab_lookup(version); |
tab = idtab_lookup(version); |
for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { |
for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { |
nxt = TAILQ_NEXT(id, next); |
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); |
debug("expiring key '%s'", id->comment); |
TAILQ_REMOVE(&tab->idlist, id, next); |
TAILQ_REMOVE(&tab->idlist, id, next); |
free_identity(id); |
free_identity(id); |
tab->nentries--; |
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 |
static void |
|
|
} |
} |
|
|
static int |
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; |
int n = 0; |
|
static struct timeval tv; |
|
|
for (i = 0; i < sockets_alloc; i++) { |
for (i = 0; i < sockets_alloc; i++) { |
switch (sockets[i].type) { |
switch (sockets[i].type) { |
|
|
break; |
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); |
return (1); |
} |
} |
|
|
|
|
_exit(2); |
_exit(2); |
} |
} |
|
|
/*ARGSUSED*/ |
|
static void |
static void |
check_parent_exists(int sig) |
check_parent_exists(void) |
{ |
{ |
int save_errno = errno; |
|
|
|
if (parent_pid != -1 && kill(parent_pid, 0) < 0) { |
if (parent_pid != -1 && kill(parent_pid, 0) < 0) { |
/* printf("Parent has died - Authentication agent exiting.\n"); */ |
/* 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 |
static void |
|
|
extern char *optarg; |
extern char *optarg; |
pid_t pid; |
pid_t pid; |
char pidstrbuf[1 + 3 * sizeof 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 */ |
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
sanitise_stdfd(); |
sanitise_stdfd(); |
|
|
|
|
skip: |
skip: |
new_socket(AUTH_SOCKET, sock); |
new_socket(AUTH_SOCKET, sock); |
if (ac > 0) { |
if (ac > 0) |
signal(SIGALRM, check_parent_exists); |
parent_alive_interval = 10; |
alarm(10); |
|
} |
|
idtab_init(); |
idtab_init(); |
if (!d_flag) |
if (!d_flag) |
signal(SIGINT, SIG_IGN); |
signal(SIGINT, SIG_IGN); |
|
|
nalloc = 0; |
nalloc = 0; |
|
|
while (1) { |
while (1) { |
tv.tv_sec = 10; |
prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); |
tv.tv_usec = 0; |
result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); |
prepare_select(&readsetp, &writesetp, &max_fd, &nalloc); |
|
result = select(max_fd + 1, readsetp, writesetp, NULL, &tv); |
|
saved_errno = errno; |
saved_errno = errno; |
reaper(); /* remove expired keys */ |
if (parent_alive_interval != 0) |
|
check_parent_exists(); |
|
(void) reaper(); /* remove expired keys */ |
if (result < 0) { |
if (result < 0) { |
if (saved_errno == EINTR) |
if (saved_errno == EINTR) |
continue; |
continue; |