diff options
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index ba2461211b02..25f10c549552 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.183 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.190 2014/07/25 21:22:03 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -49,8 +49,10 @@ #endif #include "openbsd-compat/sys-queue.h" +#ifdef WITH_OPENSSL #include <openssl/evp.h> #include "openbsd-compat/openssl-compat.h" +#endif #include <errno.h> #include <fcntl.h> @@ -124,6 +126,9 @@ int max_fd = 0; pid_t parent_pid = -1; time_t parent_alive_interval = 0; +/* pid of process for which cleanup_socket is applicable */ +pid_t cleanup_pid = 0; + /* pathname and directory for AUTH_SOCKET */ char socket_name[MAXPATHLEN]; char socket_dir[MAXPATHLEN]; @@ -221,9 +226,11 @@ process_request_identities(SocketEntry *e, int version) buffer_put_int(&msg, tab->nentries); TAILQ_FOREACH(id, &tab->idlist, next) { if (id->key->type == KEY_RSA1) { +#ifdef WITH_SSH1 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); buffer_put_bignum(&msg, id->key->rsa->e); buffer_put_bignum(&msg, id->key->rsa->n); +#endif } else { u_char *blob; u_int blen; @@ -238,6 +245,7 @@ process_request_identities(SocketEntry *e, int version) buffer_free(&msg); } +#ifdef WITH_SSH1 /* ssh1 only */ static void process_authentication_challenge1(SocketEntry *e) @@ -273,7 +281,7 @@ process_authentication_challenge1(SocketEntry *e) if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { Key *private = id->key; /* Decrypt the challenge using the private key. */ - if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) + if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0) goto failure; /* The response is MD5 of decrypted challenge plus session id. */ @@ -308,6 +316,7 @@ send: BN_clear_free(challenge); buffer_free(&msg); } +#endif /* ssh2 only */ static void @@ -359,12 +368,16 @@ process_sign_request2(SocketEntry *e) static void process_remove_identity(SocketEntry *e, int version) { - u_int blen, bits; + u_int blen; int success = 0; Key *key = NULL; u_char *blob; +#ifdef WITH_SSH1 + u_int bits; +#endif /* WITH_SSH1 */ switch (version) { +#ifdef WITH_SSH1 case 1: key = key_new(KEY_RSA1); bits = buffer_get_int(&e->request); @@ -375,6 +388,7 @@ process_remove_identity(SocketEntry *e, int version) logit("Warning: identity keysize mismatch: actual %u, announced %u", key_size(key), bits); break; +#endif /* WITH_SSH1 */ case 2: blob = buffer_get_string(&e->request, &blen); key = key_from_blob(blob, blen); @@ -471,6 +485,7 @@ process_add_identity(SocketEntry *e, int version) Key *k = NULL; switch (version) { +#ifdef WITH_SSH1 case 1: k = key_new_private(KEY_RSA1); (void) buffer_get_int(&e->request); /* ignored */ @@ -484,7 +499,9 @@ process_add_identity(SocketEntry *e, int version) buffer_get_bignum(&e->request, k->rsa->p); /* q */ /* Generate additional parameters */ - rsa_generate_additional_parameters(k->rsa); + if (rsa_generate_additional_parameters(k->rsa) != 0) + fatal("%s: rsa_generate_additional_parameters " + "error", __func__); /* enable blinding */ if (RSA_blinding_on(k->rsa, NULL) != 1) { @@ -493,6 +510,7 @@ process_add_identity(SocketEntry *e, int version) goto send; } break; +#endif /* WITH_SSH1 */ case 2: k = key_private_deserialize(&e->request); if (k == NULL) { @@ -501,11 +519,10 @@ process_add_identity(SocketEntry *e, int version) } break; } - comment = buffer_get_string(&e->request, NULL); - if (k == NULL) { - free(comment); + if (k == NULL) goto send; - } + comment = buffer_get_string(&e->request, NULL); + while (buffer_len(&e->request)) { switch ((type = buffer_get_char(&e->request))) { case SSH_AGENT_CONSTRAIN_LIFETIME: @@ -733,6 +750,7 @@ process_message(SocketEntry *e) case SSH_AGENTC_UNLOCK: process_lock_agent(e, type == SSH_AGENTC_LOCK); break; +#ifdef WITH_SSH1 /* ssh1 */ case SSH_AGENTC_RSA_CHALLENGE: process_authentication_challenge1(e); @@ -750,6 +768,7 @@ process_message(SocketEntry *e) case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: process_remove_all_identities(e, 1); break; +#endif /* ssh2 */ case SSH2_AGENTC_SIGN_REQUEST: process_sign_request2(e); @@ -949,6 +968,7 @@ after_select(fd_set *readset, fd_set *writeset) break; } buffer_append(&sockets[i].input, buf, len); + explicit_bzero(buf, sizeof(buf)); process_message(&sockets[i]); } break; @@ -960,6 +980,9 @@ after_select(fd_set *readset, fd_set *writeset) static void cleanup_socket(void) { + if (cleanup_pid != 0 && getpid() != cleanup_pid) + return; + debug("%s: cleanup", __func__); if (socket_name[0]) unlink(socket_name); if (socket_dir[0]) @@ -1001,15 +1024,10 @@ check_parent_exists(void) static void usage(void) { - fprintf(stderr, "usage: %s [options] [command [arg ...]]\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"); - fprintf(stderr, " -a socket Bind agent socket to given name.\n"); - fprintf(stderr, " -t life Default identity lifetime (seconds).\n"); + fprintf(stderr, + "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" + " [command [arg ...]]\n" + " ssh-agent [-c | -s] -k\n"); exit(1); } @@ -1021,17 +1039,16 @@ main(int ac, char **av) u_int nalloc; char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; - struct sockaddr_un sunaddr; #ifdef HAVE_SETRLIMIT struct rlimit rlim; #endif - int prev_mask; extern int optind; extern char *optarg; pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; struct timeval *tvp = NULL; size_t len; + mode_t prev_mask; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -1045,7 +1062,9 @@ main(int ac, char **av) prctl(PR_SET_DUMPABLE, 0); #endif +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif __progname = ssh_get_progname(av[0]); seed_rng(); @@ -1142,27 +1161,14 @@ main(int ac, char **av) * Create socket early so it will exist before command gets run from * the parent. */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - *socket_name = '\0'; /* Don't unlink any existing file */ - cleanup_exit(1); - } - memset(&sunaddr, 0, sizeof(sunaddr)); - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); prev_mask = umask(0177); - if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { - perror("bind"); + sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); + if (sock < 0) { + /* XXX - unix_listener() calls error() not perror() */ *socket_name = '\0'; /* Don't unlink any existing file */ - umask(prev_mask); cleanup_exit(1); } umask(prev_mask); - if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { - perror("listen"); - cleanup_exit(1); - } /* * Fork, and have the parent execute the command, if any, or present @@ -1231,6 +1237,8 @@ main(int ac, char **av) skip: + cleanup_pid = getpid(); + #ifdef ENABLE_PKCS11 pkcs11_init(0); #endif |