-/* $OpenBSD: ssh-agent.c,v 1.47 2001/01/21 19:05:56 markus Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.55 2001/06/23 15:12:20 itojun Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 implementation,
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.47 2001/01/21 19:05:56 markus Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.55 2001/06/23 15:12:20 itojun Exp $");
#include <openssl/evp.h>
#include <openssl/md5.h>
char *__progname;
#endif
-int prepare_select(fd_set **, fd_set **, int *);
-
-void
+static void
idtab_init(void)
{
int i;
}
/* return private key table for requested protocol version */
-Idtab *
+static Idtab *
idtab_lookup(int version)
{
if (version < 1 || version > 2)
}
/* return matching private key for given public key */
-Key *
+static Key *
lookup_private_key(Key *key, int *idx, int version)
{
int i;
}
/* send list of supported public keys to 'client' */
-void
+static void
process_request_identities(SocketEntry *e, int version)
{
Idtab *tab = idtab_lookup(version);
}
/* ssh1 only */
-void
+static void
process_authentication_challenge1(SocketEntry *e)
{
Key *key, *private;
private = lookup_private_key(key, NULL, 1);
if (private != NULL) {
/* Decrypt the challenge using the private key. */
- rsa_private_decrypt(challenge, challenge, private->rsa);
+ if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
+ goto failure;
/* The response is MD5 of decrypted challenge plus session id. */
len = BN_num_bytes(challenge);
}
/* ssh2 only */
-void
+static void
process_sign_request2(SocketEntry *e)
{
extern int datafellows;
}
/* shared */
-void
+static void
process_remove_identity(SocketEntry *e, int version)
{
Key *key = NULL, *private;
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
}
-void
+static void
process_remove_all_identities(SocketEntry *e, int version)
{
u_int i;
return;
}
-void
-generate_additional_parameters(RSA *rsa)
-{
- BIGNUM *aux;
- BN_CTX *ctx;
- /* Generate additional parameters */
- aux = BN_new();
- ctx = BN_CTX_new();
-
- BN_sub(aux, rsa->q, BN_value_one());
- BN_mod(rsa->dmq1, rsa->d, aux, ctx);
-
- BN_sub(aux, rsa->p, BN_value_one());
- BN_mod(rsa->dmp1, rsa->d, aux, ctx);
-
- BN_clear_free(aux);
- BN_CTX_free(ctx);
-}
-
-void
+static void
process_add_identity(SocketEntry *e, int version)
{
Key *k = NULL;
/* dispatch incoming messages */
-void
+static void
process_message(SocketEntry *e)
{
u_int msg_len;
}
}
-void
+static void
new_socket(int type, int fd)
{
u_int i, old_alloc;
buffer_init(&sockets[old_alloc].output);
}
-int
+static int
prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl)
{
u_int i, sz;
sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
if (*fdrp == NULL || n > *fdl) {
if (*fdrp)
- free(*fdrp);
+ xfree(*fdrp);
if (*fdwp)
- free(*fdwp);
+ xfree(*fdwp);
*fdrp = xmalloc(sz);
*fdwp = xmalloc(sz);
*fdl = n;
return (1);
}
-void
+static void
after_select(fd_set *readset, fd_set *writeset)
{
u_int i;
case AUTH_CONNECTION:
if (buffer_len(&sockets[i].output) > 0 &&
FD_ISSET(sockets[i].fd, writeset)) {
- len = write(sockets[i].fd,
- buffer_ptr(&sockets[i].output),
- buffer_len(&sockets[i].output));
+ do {
+ len = write(sockets[i].fd,
+ buffer_ptr(&sockets[i].output),
+ buffer_len(&sockets[i].output));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EINTR))
+ continue;
+ break;
+ } while (1);
if (len <= 0) {
shutdown(sockets[i].fd, SHUT_RDWR);
close(sockets[i].fd);
buffer_consume(&sockets[i].output, len);
}
if (FD_ISSET(sockets[i].fd, readset)) {
- len = read(sockets[i].fd, buf, sizeof(buf));
+ do {
+ len = read(sockets[i].fd, buf, sizeof(buf));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EINTR))
+ continue;
+ break;
+ } while (1);
if (len <= 0) {
shutdown(sockets[i].fd, SHUT_RDWR);
close(sockets[i].fd);
}
}
-void
+static void
check_parent_exists(int sig)
{
int save_errno = errno;
errno = save_errno;
}
-void
+static void
cleanup_socket(void)
{
- unlink(socket_name);
- rmdir(socket_dir);
+ if (socket_name[0])
+ unlink(socket_name);
+ if (socket_dir[0])
+ rmdir(socket_dir);
}
-void
+static void
cleanup_exit(int i)
{
cleanup_socket();
exit(i);
}
-void
-usage()
+static void
+cleanup_handler(int sig)
+{
+ cleanup_socket();
+ _exit(2);
+}
+
+static void
+usage(void)
{
fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);
fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n",
struct sockaddr_un sunaddr;
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
+#endif
+#ifdef HAVE_CYGWIN
+ int prev_mask;
#endif
pid_t pid;
char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid];
extern int optind;
fd_set *readsetp = NULL, *writesetp = NULL;
+ SSLeay_add_all_algorithms();
+
__progname = get_progname(av[0]);
init_rng();
-
+ seed_rng();
+
#ifdef __GNU_LIBRARY__
while ((ch = getopt(ac, av, "+cks")) != -1) {
#else /* __GNU_LIBRARY__ */
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
+#ifdef HAVE_CYGWIN
+ prev_mask = umask(0177);
+#endif
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
perror("bind");
+#ifdef HAVE_CYGWIN
+ umask(prev_mask);
+#endif
cleanup_exit(1);
}
+#ifdef HAVE_CYGWIN
+ umask(prev_mask);
+#endif
if (listen(sock, 5) < 0) {
perror("listen");
cleanup_exit(1);
idtab_init();
signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, cleanup_exit);
- signal(SIGTERM, cleanup_exit);
+ signal(SIGHUP, cleanup_handler);
+ signal(SIGTERM, cleanup_handler);
while (1) {
prepare_select(&readsetp, &writesetp, &max_fd);
if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) {