diff --git a/ssh-agent.c b/ssh-agent.c
new file mode 100644
index 0000000..19165b8
--- /dev/null
+++ b/ssh-agent.c
@@ -0,0 +1,572 @@
+/*
+
+ssh-agent.c
+
+Author: Tatu Ylonen <ylo@cs.hut.fi>
+
+Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+                   All rights reserved
+
+Created: Wed Mar 29 03:46:59 1995 ylo
+
+The authentication agent program.
+
+*/
+
+#include "includes.h"
+RCSID("$Id: ssh-agent.c,v 1.1 1999/10/27 03:42:45 damien Exp $");
+
+#include "ssh.h"
+#include "rsa.h"
+#include "authfd.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "getput.h"
+#include "mpaux.h"
+
+#include <openssl/md5.h>
+
+typedef struct
+{
+  int fd;
+  enum { AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION } type;
+  Buffer input;
+  Buffer output;
+} SocketEntry;
+
+unsigned int sockets_alloc = 0;
+SocketEntry *sockets = NULL;
+
+typedef struct
+{
+  RSA *key;
+  char *comment;
+} Identity;
+
+unsigned int num_identities = 0;
+Identity *identities = NULL;
+
+int max_fd = 0;
+
+/* pid of shell == parent of agent */
+int parent_pid = -1;
+
+/* pathname and directory for AUTH_SOCKET */
+char socket_name[1024];
+char socket_dir[1024];
+
+void
+process_request_identity(SocketEntry *e)
+{
+  Buffer msg;
+  int i;
+
+  buffer_init(&msg);
+  buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER);
+  buffer_put_int(&msg, num_identities);
+  for (i = 0; i < num_identities; i++)
+    {
+      buffer_put_int(&msg, BN_num_bits(identities[i].key->n));
+      buffer_put_bignum(&msg, identities[i].key->e);
+      buffer_put_bignum(&msg, identities[i].key->n);
+      buffer_put_string(&msg, identities[i].comment, 
+			strlen(identities[i].comment));
+    }
+  buffer_put_int(&e->output, buffer_len(&msg));
+  buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
+  buffer_free(&msg);
+}
+
+void
+process_authentication_challenge(SocketEntry *e)
+{
+  int i, pub_bits, len;
+  BIGNUM *pub_e, *pub_n, *challenge;
+  Buffer msg;
+  MD5_CTX md;
+  unsigned char buf[32], mdbuf[16], session_id[16];
+  unsigned int response_type;
+
+  buffer_init(&msg);
+  pub_e = BN_new();
+  pub_n = BN_new();
+  challenge = BN_new();
+  pub_bits = buffer_get_int(&e->input);
+  buffer_get_bignum(&e->input, pub_e);
+  buffer_get_bignum(&e->input, pub_n);
+  buffer_get_bignum(&e->input, challenge);
+  if (buffer_len(&e->input) == 0)
+    {
+      /* Compatibility code for old servers. */
+      memset(session_id, 0, 16);
+      response_type = 0;
+    }
+  else
+    {
+      /* New code. */
+      buffer_get(&e->input, (char *)session_id, 16);
+      response_type = buffer_get_int(&e->input);
+    }
+  for (i = 0; i < num_identities; i++)
+    if (pub_bits == BN_num_bits(identities[i].key->n) &&
+	BN_cmp(pub_e, identities[i].key->e) == 0 &&
+	BN_cmp(pub_n, identities[i].key->n) == 0)
+      {
+	/* Decrypt the challenge using the private key. */
+	rsa_private_decrypt(challenge, challenge, identities[i].key);
+
+	/* Compute the desired response. */
+	switch (response_type)
+	  {
+	  case 0: /* As of protocol 1.0 */
+	    /* This response type is no longer supported. */
+	    log("Compatibility with ssh protocol 1.0 no longer supported.");
+	    buffer_put_char(&msg, SSH_AGENT_FAILURE);
+	    goto send;
+
+	  case 1: /* As of protocol 1.1 */
+	    /* The response is MD5 of decrypted challenge plus session id. */
+	    len = BN_num_bytes(challenge);
+	    assert(len <= 32 && len);
+	    memset(buf, 0, 32);
+	    BN_bn2bin(challenge, buf + 32 - len);
+	    MD5_Init(&md);
+	    MD5_Update(&md, buf, 32);
+	    MD5_Update(&md, session_id, 16);
+	    MD5_Final(mdbuf, &md);
+	    break;
+
+	  default:
+	    fatal("process_authentication_challenge: bad response_type %d", 
+		  response_type);
+	    break;
+	  }
+
+	/* Send the response. */
+	buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
+	for (i = 0; i < 16; i++)
+	  buffer_put_char(&msg, mdbuf[i]);
+
+	goto send;
+      }
+  /* Unknown identity.  Send failure. */
+  buffer_put_char(&msg, SSH_AGENT_FAILURE);
+ send:
+  buffer_put_int(&e->output, buffer_len(&msg));
+  buffer_append(&e->output, buffer_ptr(&msg),
+		buffer_len(&msg));
+  buffer_free(&msg);
+  BN_clear_free(pub_e);
+  BN_clear_free(pub_n);
+  BN_clear_free(challenge);
+}
+
+void
+process_remove_identity(SocketEntry *e)
+{
+  unsigned int bits;
+  unsigned int i;
+  BIGNUM *dummy, *n;
+  
+  dummy = BN_new();
+  n = BN_new();
+  
+  /* Get the key from the packet. */
+  bits = buffer_get_int(&e->input);
+  buffer_get_bignum(&e->input, dummy);
+  buffer_get_bignum(&e->input, n);
+  
+  /* Check if we have the key. */
+  for (i = 0; i < num_identities; i++)
+    if (BN_cmp(identities[i].key->n, n) == 0)
+      {
+	/* We have this key.  Free the old key.  Since we don\'t want to leave
+	   empty slots in the middle of the array, we actually free the
+	   key there and copy data from the last entry. */
+	RSA_free(identities[i].key);
+	xfree(identities[i].comment);
+	if (i < num_identities - 1)
+	  identities[i] = identities[num_identities - 1];
+	num_identities--;
+	BN_clear_free(dummy);
+	BN_clear_free(n);
+
+	/* Send success. */
+	buffer_put_int(&e->output, 1);
+	buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
+	return;
+      }
+  /* We did not have the key. */
+  BN_clear(dummy);
+  BN_clear(n);
+
+  /* Send failure. */
+  buffer_put_int(&e->output, 1);
+  buffer_put_char(&e->output, SSH_AGENT_FAILURE);
+}
+
+/* Removes all identities from the agent. */
+
+void
+process_remove_all_identities(SocketEntry *e)
+{
+  unsigned int i;
+  
+  /* Loop over all identities and clear the keys. */
+  for (i = 0; i < num_identities; i++)
+    {
+      RSA_free(identities[i].key);
+      xfree(identities[i].comment);
+    }
+
+  /* Mark that there are no identities. */
+  num_identities = 0;
+
+  /* Send success. */
+  buffer_put_int(&e->output, 1);
+  buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
+  return;
+}
+
+/* Adds an identity to the agent. */
+
+void
+process_add_identity(SocketEntry *e)
+{
+  RSA *k;
+  int i;
+  BIGNUM *aux;
+  BN_CTX *ctx;
+  
+  if (num_identities == 0)
+    identities = xmalloc(sizeof(Identity));
+  else
+    identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity));
+
+  identities[num_identities].key = RSA_new();
+  k = identities[num_identities].key;
+  buffer_get_int(&e->input); /* bits */
+  k->n = BN_new();
+  buffer_get_bignum(&e->input, k->n);
+  k->e = BN_new();
+  buffer_get_bignum(&e->input, k->e);
+  k->d = BN_new();
+  buffer_get_bignum(&e->input, k->d);
+  k->iqmp = BN_new();
+  buffer_get_bignum(&e->input, k->iqmp);
+  /* SSH and SSL have p and q swapped */
+  k->q = BN_new();
+  buffer_get_bignum(&e->input, k->q); /* p */
+  k->p = BN_new();
+  buffer_get_bignum(&e->input, k->p); /* q */
+
+  /* Generate additional parameters */
+  aux = BN_new();
+  ctx = BN_CTX_new();
+
+  BN_sub(aux, k->q, BN_value_one());
+  k->dmq1 = BN_new();
+  BN_mod(k->dmq1, k->d, aux, ctx);
+
+  BN_sub(aux, k->p, BN_value_one());
+  k->dmp1 = BN_new();
+  BN_mod(k->dmp1, k->d, aux, ctx);
+
+  BN_clear_free(aux);
+  BN_CTX_free(ctx);
+  
+  identities[num_identities].comment = buffer_get_string(&e->input, NULL);
+
+  /* Check if we already have the key. */
+  for (i = 0; i < num_identities; i++)
+    if (BN_cmp(identities[i].key->n, k->n) == 0)
+      {
+	/* We already have this key.  Clear and free the new data and
+	   return success. */
+	RSA_free(k);
+	xfree(identities[num_identities].comment);
+
+	/* Send success. */
+	buffer_put_int(&e->output, 1);
+	buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
+	return;
+      }
+
+  /* Increment the number of identities. */
+  num_identities++;
+  
+  /* Send a success message. */
+  buffer_put_int(&e->output, 1);
+  buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
+}
+
+void
+process_message(SocketEntry *e)
+{
+  unsigned int msg_len;
+  unsigned int type;
+  unsigned char *cp;
+  if (buffer_len(&e->input) < 5)
+    return; /* Incomplete message. */
+  cp = (unsigned char *)buffer_ptr(&e->input);
+  msg_len = GET_32BIT(cp);
+  if (msg_len > 256 * 1024)
+    {
+      shutdown(e->fd, SHUT_RDWR);
+      close(e->fd);
+      e->type = AUTH_UNUSED;
+      return;
+    }
+  if (buffer_len(&e->input) < msg_len + 4)
+    return;
+  buffer_consume(&e->input, 4);
+  type = buffer_get_char(&e->input);
+
+  switch (type)
+    {
+    case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
+      process_request_identity(e);
+      break;
+    case SSH_AGENTC_RSA_CHALLENGE:
+      process_authentication_challenge(e);
+      break;
+    case SSH_AGENTC_ADD_RSA_IDENTITY:
+      process_add_identity(e);
+      break;
+    case SSH_AGENTC_REMOVE_RSA_IDENTITY:
+      process_remove_identity(e);
+      break;
+    case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
+      process_remove_all_identities(e);
+      break;
+    default:
+      /* Unknown message.  Respond with failure. */
+      error("Unknown message %d", type);
+      buffer_clear(&e->input);
+      buffer_put_int(&e->output, 1);
+      buffer_put_char(&e->output, SSH_AGENT_FAILURE);
+      break;
+    }
+}
+
+void
+new_socket(int type, int fd)
+{
+  unsigned int i, old_alloc;
+  if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+    error("fcntl O_NONBLOCK: %s", strerror(errno));
+
+  if (fd > max_fd)
+    max_fd = fd;
+
+  for (i = 0; i < sockets_alloc; i++)
+    if (sockets[i].type == AUTH_UNUSED)
+      {
+	sockets[i].fd = fd;
+	sockets[i].type = type;
+	buffer_init(&sockets[i].input);
+	buffer_init(&sockets[i].output);
+	return;
+      }
+  old_alloc = sockets_alloc;
+  sockets_alloc += 10;
+  if (sockets)
+    sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0]));
+  else
+    sockets = xmalloc(sockets_alloc * sizeof(sockets[0]));
+  for (i = old_alloc; i < sockets_alloc; i++)
+    sockets[i].type = AUTH_UNUSED;
+  sockets[old_alloc].type = type;
+  sockets[old_alloc].fd = fd;
+  buffer_init(&sockets[old_alloc].input);
+  buffer_init(&sockets[old_alloc].output);
+}
+
+void
+prepare_select(fd_set *readset, fd_set *writeset)
+{
+  unsigned int i;
+  for (i = 0; i < sockets_alloc; i++)
+    switch (sockets[i].type)
+      {
+      case AUTH_SOCKET:
+      case AUTH_CONNECTION:
+	FD_SET(sockets[i].fd, readset);
+	if (buffer_len(&sockets[i].output) > 0)
+	  FD_SET(sockets[i].fd, writeset);
+	break;
+      case AUTH_UNUSED:
+	break;
+      default:
+	fatal("Unknown socket type %d", sockets[i].type);
+	break;
+      }
+}
+
+void after_select(fd_set *readset, fd_set *writeset)
+{
+  unsigned int i;
+  int len, sock;
+  char buf[1024];
+  struct sockaddr_un sunaddr;
+
+  for (i = 0; i < sockets_alloc; i++)
+    switch (sockets[i].type)
+      {
+      case AUTH_UNUSED:
+	break;
+      case AUTH_SOCKET:
+	if (FD_ISSET(sockets[i].fd, readset))
+	  {
+	    len = sizeof(sunaddr);
+	    sock = accept(sockets[i].fd, (struct sockaddr *)&sunaddr, &len);
+	    if (sock < 0)
+	      {
+		perror("accept from AUTH_SOCKET");
+		break;
+	      }
+	    new_socket(AUTH_CONNECTION, sock);
+	  }
+	break;
+      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));
+	    if (len <= 0)
+	      {
+		shutdown(sockets[i].fd, SHUT_RDWR);
+		close(sockets[i].fd);
+		sockets[i].type = AUTH_UNUSED;
+		break;
+	      }
+	    buffer_consume(&sockets[i].output, len);
+	  }
+	if (FD_ISSET(sockets[i].fd, readset))
+	  {
+	    len = read(sockets[i].fd, buf, sizeof(buf));
+	    if (len <= 0)
+	      {
+		shutdown(sockets[i].fd, SHUT_RDWR);
+		close(sockets[i].fd);
+		sockets[i].type = AUTH_UNUSED;
+		break;
+	      }
+	    buffer_append(&sockets[i].input, buf, len);
+	    process_message(&sockets[i]);
+	  }
+	break;
+      default:
+	fatal("Unknown type %d", sockets[i].type);
+      }
+}
+
+void
+check_parent_exists(int sig)
+{
+  if (kill(parent_pid, 0) < 0)
+    {
+      /* printf("Parent has died - Authentication agent exiting.\n"); */
+      exit(1);
+    }
+  signal(SIGALRM, check_parent_exists);
+  alarm(10);
+}
+
+void cleanup_socket(void) {
+  remove(socket_name);
+  rmdir(socket_dir);
+}
+
+int
+main(int ac, char **av)
+{
+  fd_set readset, writeset;
+  int sock;
+  struct sockaddr_un sunaddr;
+
+  /* check if RSA support exists */
+  if (rsa_alive() == 0) {
+    extern char *__progname;
+    fprintf(stderr,
+      "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
+      __progname);
+    exit(1);
+  }
+
+  if (ac < 2)
+    {
+      fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);
+      fprintf(stderr, "Usage: %s command\n", av[0]);
+      exit(1);
+    }
+
+  parent_pid = getpid();
+
+  /* Create private directory for agent socket */
+  strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir);
+  if (mkdtemp(socket_dir) == NULL) {
+      perror("mkdtemp: private socket dir");
+      exit(1);
+  }
+  snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir, parent_pid);
+  
+  /* Fork, and have the parent execute the command.  The child continues as
+     the authentication agent. */
+  if (fork() != 0)
+    { /* Parent - execute the given command. */
+      setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1);
+      execvp(av[1], av + 1);
+      perror(av[1]);
+      exit(1);
+    }
+
+  if (atexit(cleanup_socket) < 0) {
+	perror("atexit");
+	cleanup_socket();
+	exit(1);
+  }
+
+  sock = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (sock < 0)
+    {
+      perror("socket");
+      exit(1);
+    }
+  memset(&sunaddr, 0, sizeof(sunaddr));
+  sunaddr.sun_family = AF_UNIX;
+  strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
+  if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
+    {
+      perror("bind");
+      exit(1);
+    }
+  if (listen(sock, 5) < 0)
+    {
+      perror("listen");
+      exit(1);
+    }
+  new_socket(AUTH_SOCKET, sock);
+  signal(SIGALRM, check_parent_exists);
+  alarm(10);
+
+  signal(SIGINT, SIG_IGN);
+  while (1)
+    {
+      FD_ZERO(&readset);
+      FD_ZERO(&writeset);
+      prepare_select(&readset, &writeset);
+      if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0)
+	{
+	  if (errno == EINTR)
+	    continue;
+	  perror("select");
+	  exit(1);
+	}
+      after_select(&readset, &writeset);
+    }
+  /*NOTREACHED*/
+}
