X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/2b63e80327b2f9ecaf7995eb0811c4e5f8a53725..67656ffcb8e1bdacdf86ef1f4b2df44fd4ce238e:/ssh-agent.c diff --git a/ssh-agent.c b/ssh-agent.c index 309b9d41..e8018bf3 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.60 2001/06/27 05:42:25 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.75 2001/12/19 07:18:56 deraadt Exp $ */ /* * Author: Tatu Ylonen @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.60 2001/06/27 05:42:25 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.75 2001/12/19 07:18:56 deraadt Exp $"); #include #include @@ -61,11 +61,15 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.60 2001/06/27 05:42:25 markus Exp $"); #include "scard.h" #endif +typedef enum { + AUTH_UNUSED, + AUTH_SOCKET, + AUTH_CONNECTION +} sock_type; + typedef struct { int fd; - enum { - AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION - } type; + sock_type type; Buffer input; Buffer output; } SocketEntry; @@ -105,7 +109,7 @@ static void idtab_init(void) { int i; - for (i = 0; i <=2; i++){ + for (i = 0; i <=2; i++) { idtable[i].identities = NULL; idtable[i].nentries = 0; } @@ -289,7 +293,7 @@ process_remove_identity(SocketEntry *e, int version) u_int bits; int success = 0; - switch(version){ + switch (version) { case 1: key = key_new(KEY_RSA1); bits = buffer_get_int(&e->input); @@ -391,7 +395,7 @@ process_add_identity(SocketEntry *e, int version) type_name = buffer_get_string(&e->input, NULL); type = key_type_from_name(type_name); xfree(type_name); - switch(type) { + switch (type) { case KEY_DSA: k = key_new_private(type); buffer_get_bignum2(&e->input, k->dsa->p); @@ -451,12 +455,13 @@ process_add_smartcard_key (SocketEntry *e) { Idtab *tab; Key *n = NULL, *k = NULL; + char *sc_reader_id = NULL; int success = 0; - int sc_reader_num = 0; - - sc_reader_num = buffer_get_int(&e->input); - k = sc_get_key(sc_reader_num); + sc_reader_id = buffer_get_string(&e->input, NULL); + k = sc_get_key(sc_reader_id); + xfree(sc_reader_id); + if (k == NULL) { error("sc_get_pubkey failed"); goto send; @@ -464,6 +469,7 @@ process_add_smartcard_key (SocketEntry *e) success = 1; tab = idtab_lookup(1); + k->type = KEY_RSA1; if (lookup_private_key(k, NULL, 1) == NULL) { if (tab->nentries == 0) tab->identities = xmalloc(sizeof(Identity)); @@ -479,6 +485,7 @@ process_add_smartcard_key (SocketEntry *e) xstrdup("rsa1 smartcard"); tab->nentries++; } + k->type = KEY_RSA; tab = idtab_lookup(2); if (lookup_private_key(k, NULL, 2) == NULL) { if (tab->nentries == 0) @@ -508,13 +515,16 @@ process_remove_smartcard_key(SocketEntry *e) Key *k = NULL, *private; int idx; int success = 0; - int sc_reader_num = 0; + char *sc_reader_id = NULL; - sc_reader_num = buffer_get_int(&e->input); + sc_reader_id = buffer_get_string(&e->input, NULL); + k = sc_get_key(sc_reader_id); + xfree(sc_reader_id); - if ((k = sc_get_key(sc_reader_num)) == NULL) { + if (k == NULL) { error("sc_get_pubkey failed"); } else { + k->type = KEY_RSA1; private = lookup_private_key(k, &idx, 1); if (private != NULL) { Idtab *tab = idtab_lookup(1); @@ -525,6 +535,7 @@ process_remove_smartcard_key(SocketEntry *e) tab->nentries--; success = 1; } + k->type = KEY_RSA; private = lookup_private_key(k, &idx, 2); if (private != NULL) { Idtab *tab = idtab_lookup(2); @@ -542,7 +553,7 @@ process_remove_smartcard_key(SocketEntry *e) buffer_put_char(&e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } -#endif +#endif /* SMARTCARD */ /* dispatch incoming messages */ @@ -604,11 +615,11 @@ process_message(SocketEntry *e) #ifdef SMARTCARD case SSH_AGENTC_ADD_SMARTCARD_KEY: process_add_smartcard_key(e); - break; + break; case SSH_AGENTC_REMOVE_SMARTCARD_KEY: process_remove_smartcard_key(e); - break; -#endif + break; +#endif /* SMARTCARD */ default: /* Unknown message. Respond with failure. */ error("Unknown message %d", type); @@ -620,7 +631,7 @@ process_message(SocketEntry *e) } static void -new_socket(int type, int fd) +new_socket(sock_type type, int fd) { u_int i, old_alloc; if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) @@ -652,7 +663,7 @@ new_socket(int type, int fd) } static int -prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl) +prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, int *nallocp) { u_int i, sz; int n = 0; @@ -672,15 +683,18 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl) } sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); - if (*fdrp == NULL || n > *fdl) { + if (*fdrp == NULL || sz > *nallocp) { if (*fdrp) xfree(*fdrp); if (*fdwp) xfree(*fdwp); *fdrp = xmalloc(sz); *fdwp = xmalloc(sz); - *fdl = n; + *nallocp = sz; } + if (n < *fdl) + debug("XXX shrink: %d < %d", n, *fdl); + *fdl = n; memset(*fdrp, 0, sz); memset(*fdwp, 0, sz); @@ -771,20 +785,6 @@ after_select(fd_set *readset, fd_set *writeset) } } -static void -check_parent_exists(int sig) -{ - int save_errno = errno; - - if (parent_pid != -1 && kill(parent_pid, 0) < 0) { - /* printf("Parent has died - Authentication agent exiting.\n"); */ - exit(1); - } - signal(SIGALRM, check_parent_exists); - alarm(10); - errno = save_errno; -} - static void cleanup_socket(void) { @@ -808,19 +808,37 @@ cleanup_handler(int sig) _exit(2); } +static void +check_parent_exists(int sig) +{ + 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 */ + } + signal(SIGALRM, check_parent_exists); + alarm(10); + errno = save_errno; +} + static void usage(void) { - fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION); - fprintf(stderr, "Usage: %s [-c | -s] [-k] [-d] [command {args...]]\n", + fprintf(stderr, "Usage: %s [options] [command [args ...]]\n", __progname); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); + fprintf(stderr, " -s Generate Bourne shell commands on stdout.\n"); + fprintf(stderr, " -k Kill the current agent.\n"); + fprintf(stderr, " -d Debug mode.\n"); exit(1); } int main(int ac, char **av) { - int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch; + int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc; struct sockaddr_un sunaddr; #ifdef HAVE_SETRLIMIT struct rlimit rlim; @@ -980,6 +998,13 @@ main(int ac, char **av) perror(av[0]); exit(1); } + + if (setsid() == -1) { + perror("setsid"); + cleanup_exit(1); + } + + (void)chdir("/"); close(0); close(1); close(2); @@ -992,10 +1017,6 @@ main(int ac, char **av) cleanup_exit(1); } #endif - if (setsid() == -1) { - perror("setsid"); - cleanup_exit(1); - } skip: if (atexit(cleanup_socket) < 0) { @@ -1008,14 +1029,15 @@ skip: alarm(10); } idtab_init(); - if (!d_flag) { + if (!d_flag) signal(SIGINT, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - } + signal(SIGPIPE, SIG_IGN); signal(SIGHUP, cleanup_handler); signal(SIGTERM, cleanup_handler); + nalloc = 0; + while (1) { - prepare_select(&readsetp, &writesetp, &max_fd); + prepare_select(&readsetp, &writesetp, &max_fd, &nalloc); if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) { if (errno == EINTR) continue;