[BACK]Return to ssh-agent.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/ssh-agent.c between version 1.37 and 1.37.2.1

version 1.37, 2000/09/21 11:07:51 version 1.37.2.1, 2001/02/16 20:13:17
Line 39 
Line 39 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
   #include <openssl/evp.h>
   #include <openssl/md5.h>
   
 #include "ssh.h"  #include "ssh.h"
 #include "rsa.h"  #include "rsa.h"
 #include "buffer.h"  #include "buffer.h"
Line 47 
Line 50 
 #include "packet.h"  #include "packet.h"
 #include "getput.h"  #include "getput.h"
 #include "mpaux.h"  #include "mpaux.h"
   
 #include <openssl/evp.h>  
 #include <openssl/md5.h>  
 #include <openssl/dsa.h>  
 #include <openssl/rsa.h>  
 #include "key.h"  #include "key.h"
 #include "authfd.h"  #include "authfd.h"
 #include "dsa.h"  #include "cipher.h"
 #include "kex.h"  #include "kex.h"
 #include "compat.h"  #include "compat.h"
   #include "log.h"
   
 typedef struct {  typedef struct {
         int fd;          int fd;
Line 67 
Line 66 
         Buffer output;          Buffer output;
 } SocketEntry;  } SocketEntry;
   
 unsigned int sockets_alloc = 0;  u_int sockets_alloc = 0;
 SocketEntry *sockets = NULL;  SocketEntry *sockets = NULL;
   
 typedef struct {  typedef struct {
Line 94 
Line 93 
   
 extern char *__progname;  extern char *__progname;
   
   int     prepare_select(fd_set **, fd_set **, int *);
   
 void  void
 idtab_init(void)  idtab_init(void)
 {  {
Line 143 
Line 144 
         buffer_put_int(&msg, tab->nentries);          buffer_put_int(&msg, tab->nentries);
         for (i = 0; i < tab->nentries; i++) {          for (i = 0; i < tab->nentries; i++) {
                 Identity *id = &tab->identities[i];                  Identity *id = &tab->identities[i];
                 if (id->key->type == KEY_RSA) {                  if (id->key->type == KEY_RSA1) {
                         buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));                          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->e);
                         buffer_put_bignum(&msg, id->key->rsa->n);                          buffer_put_bignum(&msg, id->key->rsa->n);
                 } else {                  } else {
                         unsigned char *blob;                          u_char *blob;
                         unsigned int blen;                          u_int blen;
                         dsa_make_key_blob(id->key, &blob, &blen);                          key_to_blob(id->key, &blob, &blen);
                         buffer_put_string(&msg, blob, blen);                          buffer_put_string(&msg, blob, blen);
                         xfree(blob);                          xfree(blob);
                 }                  }
Line 170 
Line 171 
         int i, len;          int i, len;
         Buffer msg;          Buffer msg;
         MD5_CTX md;          MD5_CTX md;
         unsigned char buf[32], mdbuf[16], session_id[16];          u_char buf[32], mdbuf[16], session_id[16];
         unsigned int response_type;          u_int response_type;
   
         buffer_init(&msg);          buffer_init(&msg);
         key = key_new(KEY_RSA);          key = key_new(KEY_RSA1);
         challenge = BN_new();          challenge = BN_new();
   
         buffer_get_int(&e->input);                              /* ignored */          buffer_get_int(&e->input);                              /* ignored */
Line 193 
Line 194 
         private = lookup_private_key(key, NULL, 1);          private = lookup_private_key(key, NULL, 1);
         if (private != NULL) {          if (private != NULL) {
                 /* Decrypt the challenge using the private key. */                  /* 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. */                  /* The response is MD5 of decrypted challenge plus session id. */
                 len = BN_num_bytes(challenge);                  len = BN_num_bytes(challenge);
Line 232 
Line 234 
 {  {
         extern int datafellows;          extern int datafellows;
         Key *key, *private;          Key *key, *private;
         unsigned char *blob, *data, *signature = NULL;          u_char *blob, *data, *signature = NULL;
         unsigned int blen, dlen, slen = 0;          u_int blen, dlen, slen = 0;
         int flags;          int flags;
         Buffer msg;          Buffer msg;
         int ok = -1;          int ok = -1;
   
         datafellows = 0;          datafellows = 0;
   
         blob = buffer_get_string(&e->input, &blen);          blob = buffer_get_string(&e->input, &blen);
         data = buffer_get_string(&e->input, &dlen);          data = buffer_get_string(&e->input, &dlen);
   
Line 247 
Line 249 
         if (flags & SSH_AGENT_OLD_SIGNATURE)          if (flags & SSH_AGENT_OLD_SIGNATURE)
                 datafellows = SSH_BUG_SIGBLOB;                  datafellows = SSH_BUG_SIGBLOB;
   
         key = dsa_key_from_blob(blob, blen);          key = key_from_blob(blob, blen);
         if (key != NULL) {          if (key != NULL) {
                 private = lookup_private_key(key, NULL, 2);                  private = lookup_private_key(key, NULL, 2);
                 if (private != NULL)                  if (private != NULL)
                         ok = dsa_sign(private, &signature, &slen, data, dlen);                          ok = key_sign(private, &signature, &slen, data, dlen);
         }          }
         key_free(key);          key_free(key);
         buffer_init(&msg);          buffer_init(&msg);
Line 276 
Line 278 
 process_remove_identity(SocketEntry *e, int version)  process_remove_identity(SocketEntry *e, int version)
 {  {
         Key *key = NULL, *private;          Key *key = NULL, *private;
         unsigned char *blob;          u_char *blob;
         unsigned int blen;          u_int blen;
         unsigned int bits;          u_int bits;
         int success = 0;          int success = 0;
   
         switch(version){          switch(version){
         case 1:          case 1:
                 key = key_new(KEY_RSA);                  key = key_new(KEY_RSA1);
                 bits = buffer_get_int(&e->input);                  bits = buffer_get_int(&e->input);
                 buffer_get_bignum(&e->input, key->rsa->e);                  buffer_get_bignum(&e->input, key->rsa->e);
                 buffer_get_bignum(&e->input, key->rsa->n);                  buffer_get_bignum(&e->input, key->rsa->n);
   
                 if (bits != key_size(key))                  if (bits != key_size(key))
                         log("Warning: identity keysize mismatch: actual %d, announced %d",                          log("Warning: identity keysize mismatch: actual %d, announced %d",
                               key_size(key), bits);                              key_size(key), bits);
                 break;                  break;
         case 2:          case 2:
                 blob = buffer_get_string(&e->input, &blen);                  blob = buffer_get_string(&e->input, &blen);
                 key = dsa_key_from_blob(blob, blen);                  key = key_from_blob(blob, blen);
                 xfree(blob);                  xfree(blob);
                 break;                  break;
         }          }
Line 305 
Line 307 
                         /*                          /*
                          * We have this key.  Free the old key.  Since we                           * We have this key.  Free the old key.  Since we
                          * don\'t want to leave empty slots in the middle of                           * don\'t want to leave empty slots in the middle of
                          * the array, we actually free the key there and copy                           * the array, we actually free the key there and move
                          * data from the last entry.                           * all the entries between the empty slot and the end
                            * of the array.
                          */                           */
                         Idtab *tab = idtab_lookup(version);                          Idtab *tab = idtab_lookup(version);
                         key_free(tab->identities[idx].key);                          key_free(tab->identities[idx].key);
                         xfree(tab->identities[idx].comment);                          xfree(tab->identities[idx].comment);
                         if (idx != tab->nentries)                          if (tab->nentries < 1)
                                 tab->identities[idx] = tab->identities[tab->nentries];                                  fatal("process_remove_identity: "
                                       "internal error: tab->nentries %d",
                                       tab->nentries);
                           if (idx != tab->nentries - 1) {
                                   int i;
                                   for (i = idx; i < tab->nentries - 1; i++)
                                           tab->identities[i] = tab->identities[i+1];
                           }
                           tab->identities[tab->nentries - 1].key = NULL;
                           tab->identities[tab->nentries - 1].comment = NULL;
                         tab->nentries--;                          tab->nentries--;
                         success = 1;                          success = 1;
                 }                  }
Line 326 
Line 338 
 void  void
 process_remove_all_identities(SocketEntry *e, int version)  process_remove_all_identities(SocketEntry *e, int version)
 {  {
         unsigned int i;          u_int i;
         Idtab *tab = idtab_lookup(version);          Idtab *tab = idtab_lookup(version);
   
         /* Loop over all identities and clear the keys. */          /* Loop over all identities and clear the keys. */
Line 345 
Line 357 
 }  }
   
 void  void
 process_add_identity(SocketEntry *e, int version)  generate_additional_parameters(RSA *rsa)
 {  {
         Key *k = NULL;  
         RSA *rsa;  
         BIGNUM *aux;          BIGNUM *aux;
         BN_CTX *ctx;          BN_CTX *ctx;
         char *type;          /* 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
   process_add_identity(SocketEntry *e, int version)
   {
           Key *k = NULL;
           char *type_name;
         char *comment;          char *comment;
         int success = 0;          int type, success = 0;
         Idtab *tab = idtab_lookup(version);          Idtab *tab = idtab_lookup(version);
   
         switch (version) {          switch (version) {
         case 1:          case 1:
                 k = key_new(KEY_RSA);                  k = key_new_private(KEY_RSA1);
                 rsa = k->rsa;                  buffer_get_int(&e->input);                      /* ignored */
                   buffer_get_bignum(&e->input, k->rsa->n);
                   buffer_get_bignum(&e->input, k->rsa->e);
                   buffer_get_bignum(&e->input, k->rsa->d);
                   buffer_get_bignum(&e->input, k->rsa->iqmp);
   
                 /* allocate mem for private key */  
                 /* XXX rsa->n and rsa->e are already allocated */  
                 rsa->d = BN_new();  
                 rsa->iqmp = BN_new();  
                 rsa->q = BN_new();  
                 rsa->p = BN_new();  
                 rsa->dmq1 = BN_new();  
                 rsa->dmp1 = BN_new();  
   
                 buffer_get_int(&e->input);               /* ignored */  
   
                 buffer_get_bignum(&e->input, rsa->n);  
                 buffer_get_bignum(&e->input, rsa->e);  
                 buffer_get_bignum(&e->input, rsa->d);  
                 buffer_get_bignum(&e->input, rsa->iqmp);  
   
                 /* SSH and SSL have p and q swapped */                  /* SSH and SSL have p and q swapped */
                 buffer_get_bignum(&e->input, rsa->q);   /* p */                  buffer_get_bignum(&e->input, k->rsa->q);        /* p */
                 buffer_get_bignum(&e->input, rsa->p);   /* q */                  buffer_get_bignum(&e->input, k->rsa->p);        /* q */
   
                 /* Generate additional parameters */                  /* Generate additional parameters */
                 aux = BN_new();                  generate_additional_parameters(k->rsa);
                 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);  
   
                 break;                  break;
         case 2:          case 2:
                 type = buffer_get_string(&e->input, NULL);                  type_name = buffer_get_string(&e->input, NULL);
                 if (strcmp(type, KEX_DSS)) {                  type = key_type_from_name(type_name);
                   xfree(type_name);
                   switch(type) {
                   case KEY_DSA:
                           k = key_new_private(type);
                           buffer_get_bignum2(&e->input, k->dsa->p);
                           buffer_get_bignum2(&e->input, k->dsa->q);
                           buffer_get_bignum2(&e->input, k->dsa->g);
                           buffer_get_bignum2(&e->input, k->dsa->pub_key);
                           buffer_get_bignum2(&e->input, k->dsa->priv_key);
                           break;
                   case KEY_RSA:
                           k = key_new_private(type);
                           buffer_get_bignum2(&e->input, k->rsa->n);
                           buffer_get_bignum2(&e->input, k->rsa->e);
                           buffer_get_bignum2(&e->input, k->rsa->d);
                           buffer_get_bignum2(&e->input, k->rsa->iqmp);
                           buffer_get_bignum2(&e->input, k->rsa->p);
                           buffer_get_bignum2(&e->input, k->rsa->q);
   
                           /* Generate additional parameters */
                           generate_additional_parameters(k->rsa);
                           break;
                   default:
                         buffer_clear(&e->input);                          buffer_clear(&e->input);
                         xfree(type);  
                         goto send;                          goto send;
                 }                  }
                 xfree(type);  
   
                 k = key_new(KEY_DSA);  
   
                 /* allocate mem for private key */  
                 k->dsa->priv_key = BN_new();  
   
                 buffer_get_bignum2(&e->input, k->dsa->p);  
                 buffer_get_bignum2(&e->input, k->dsa->q);  
                 buffer_get_bignum2(&e->input, k->dsa->g);  
                 buffer_get_bignum2(&e->input, k->dsa->pub_key);  
                 buffer_get_bignum2(&e->input, k->dsa->priv_key);  
   
                 break;                  break;
         }          }
   
         comment = buffer_get_string(&e->input, NULL);          comment = buffer_get_string(&e->input, NULL);
         if (k == NULL) {          if (k == NULL) {
                 xfree(comment);                  xfree(comment);
Line 449 
Line 462 
 void  void
 process_message(SocketEntry *e)  process_message(SocketEntry *e)
 {  {
         unsigned int msg_len;          u_int msg_len;
         unsigned int type;          u_int type;
         unsigned char *cp;          u_char *cp;
         if (buffer_len(&e->input) < 5)          if (buffer_len(&e->input) < 5)
                 return;         /* Incomplete message. */                  return;         /* Incomplete message. */
         cp = (unsigned char *) buffer_ptr(&e->input);          cp = (u_char *) buffer_ptr(&e->input);
         msg_len = GET_32BIT(cp);          msg_len = GET_32BIT(cp);
         if (msg_len > 256 * 1024) {          if (msg_len > 256 * 1024) {
                 shutdown(e->fd, SHUT_RDWR);                  shutdown(e->fd, SHUT_RDWR);
Line 513 
Line 526 
 void  void
 new_socket(int type, int fd)  new_socket(int type, int fd)
 {  {
         unsigned int i, old_alloc;          u_int i, old_alloc;
         if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)          if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                 error("fcntl O_NONBLOCK: %s", strerror(errno));                  error("fcntl O_NONBLOCK: %s", strerror(errno));
   
Line 542 
Line 555 
         buffer_init(&sockets[old_alloc].output);          buffer_init(&sockets[old_alloc].output);
 }  }
   
 void  int
 prepare_select(fd_set *readset, fd_set *writeset)  prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl)
 {  {
         unsigned int i;          u_int i, sz;
         for (i = 0; i < sockets_alloc; i++)          int n = 0;
   
           for (i = 0; i < sockets_alloc; i++) {
                 switch (sockets[i].type) {                  switch (sockets[i].type) {
                 case AUTH_SOCKET:                  case AUTH_SOCKET:
                 case AUTH_CONNECTION:                  case AUTH_CONNECTION:
                         FD_SET(sockets[i].fd, readset);                          n = MAX(n, sockets[i].fd);
                         if (buffer_len(&sockets[i].output) > 0)  
                                 FD_SET(sockets[i].fd, writeset);  
                         break;                          break;
                 case AUTH_UNUSED:                  case AUTH_UNUSED:
                         break;                          break;
Line 560 
Line 573 
                         fatal("Unknown socket type %d", sockets[i].type);                          fatal("Unknown socket type %d", sockets[i].type);
                         break;                          break;
                 }                  }
           }
   
           sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
           if (*fdrp == NULL || n > *fdl) {
                   if (*fdrp)
                           free(*fdrp);
                   if (*fdwp)
                           free(*fdwp);
                   *fdrp = xmalloc(sz);
                   *fdwp = xmalloc(sz);
                   *fdl = n;
           }
           memset(*fdrp, 0, sz);
           memset(*fdwp, 0, sz);
   
           for (i = 0; i < sockets_alloc; i++) {
                   switch (sockets[i].type) {
                   case AUTH_SOCKET:
                   case AUTH_CONNECTION:
                           FD_SET(sockets[i].fd, *fdrp);
                           if (buffer_len(&sockets[i].output) > 0)
                                   FD_SET(sockets[i].fd, *fdwp);
                           break;
                   default:
                           break;
                   }
           }
           return (1);
 }  }
   
 void  void
 after_select(fd_set *readset, fd_set *writeset)  after_select(fd_set *readset, fd_set *writeset)
 {  {
         unsigned int i;          u_int i;
         int len, sock;          int len, sock;
         socklen_t slen;          socklen_t slen;
         char buf[1024];          char buf[1024];
Line 578 
Line 619 
                 case AUTH_SOCKET:                  case AUTH_SOCKET:
                         if (FD_ISSET(sockets[i].fd, readset)) {                          if (FD_ISSET(sockets[i].fd, readset)) {
                                 slen = sizeof(sunaddr);                                  slen = sizeof(sunaddr);
                                 sock = accept(sockets[i].fd, (struct sockaddr *) & sunaddr, &slen);                                  sock = accept(sockets[i].fd,
                                       (struct sockaddr *) &sunaddr, &slen);
                                 if (sock < 0) {                                  if (sock < 0) {
                                         perror("accept from AUTH_SOCKET");                                          perror("accept from AUTH_SOCKET");
                                         break;                                          break;
Line 589 
Line 631 
                 case AUTH_CONNECTION:                  case AUTH_CONNECTION:
                         if (buffer_len(&sockets[i].output) > 0 &&                          if (buffer_len(&sockets[i].output) > 0 &&
                             FD_ISSET(sockets[i].fd, writeset)) {                              FD_ISSET(sockets[i].fd, writeset)) {
                                 len = write(sockets[i].fd, buffer_ptr(&sockets[i].output),                                  len = write(sockets[i].fd,
                                          buffer_len(&sockets[i].output));                                      buffer_ptr(&sockets[i].output),
                                       buffer_len(&sockets[i].output));
                                 if (len <= 0) {                                  if (len <= 0) {
                                         shutdown(sockets[i].fd, SHUT_RDWR);                                          shutdown(sockets[i].fd, SHUT_RDWR);
                                         close(sockets[i].fd);                                          close(sockets[i].fd);
Line 623 
Line 666 
 void  void
 check_parent_exists(int sig)  check_parent_exists(int sig)
 {  {
           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"); */
                 exit(1);                  exit(1);
         }          }
         signal(SIGALRM, check_parent_exists);          signal(SIGALRM, check_parent_exists);
         alarm(10);          alarm(10);
           errno = save_errno;
 }  }
   
 void  void
 cleanup_socket(void)  cleanup_socket(void)
 {  {
         remove(socket_name);          if (socket_name[0])
         rmdir(socket_dir);                  unlink(socket_name);
           if (socket_dir[0])
                   rmdir(socket_dir);
 }  }
   
 void  void
Line 646 
Line 694 
 }  }
   
 void  void
 usage()  cleanup_handler(int sig)
 {  {
           cleanup_socket();
           _exit(2);
   }
   
   void
   usage(void)
   {
         fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);          fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);
         fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n",          fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n",
                 __progname);              __progname);
         exit(1);          exit(1);
 }  }
   
 int  int
 main(int ac, char **av)  main(int ac, char **av)
 {  {
         fd_set readset, writeset;  
         int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch;          int sock, c_flag = 0, k_flag = 0, s_flag = 0, ch;
         struct sockaddr_un sunaddr;          struct sockaddr_un sunaddr;
           struct rlimit rlim;
         pid_t pid;          pid_t pid;
         char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid];          char *shell, *format, *pidstr, pidstrbuf[1 + 3 * sizeof pid];
           extern int optind;
           fd_set *readsetp = NULL, *writesetp = NULL;
   
         /* check if RSA support exists */  
         if (rsa_alive() == 0) {  
                 fprintf(stderr,  
                         "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",  
                         __progname);  
                 exit(1);  
         }  
         while ((ch = getopt(ac, av, "cks")) != -1) {          while ((ch = getopt(ac, av, "cks")) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'c':                  case 'c':
Line 704 
Line 754 
                 pidstr = getenv(SSH_AGENTPID_ENV_NAME);                  pidstr = getenv(SSH_AGENTPID_ENV_NAME);
                 if (pidstr == NULL) {                  if (pidstr == NULL) {
                         fprintf(stderr, "%s not set, cannot kill agent\n",                          fprintf(stderr, "%s not set, cannot kill agent\n",
                                 SSH_AGENTPID_ENV_NAME);                              SSH_AGENTPID_ENV_NAME);
                         exit(1);                          exit(1);
                 }                  }
                 pid = atoi(pidstr);                  pid = atoi(pidstr);
                 if (pid < 1) {  /* XXX PID_MAX check too */                  if (pid < 1) {
                 /* Yes, PID_MAX check please */  
                         fprintf(stderr, "%s=\"%s\", which is not a good PID\n",                          fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
                                 SSH_AGENTPID_ENV_NAME, pidstr);                              SSH_AGENTPID_ENV_NAME, pidstr);
                         exit(1);                          exit(1);
                 }                  }
                 if (kill(pid, SIGTERM) == -1) {                  if (kill(pid, SIGTERM) == -1) {
Line 733 
Line 782 
                 exit(1);                  exit(1);
         }          }
         snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir,          snprintf(socket_name, sizeof socket_name, "%s/agent.%d", socket_dir,
                  parent_pid);              parent_pid);
   
         /*          /*
          * Create socket early so it will exist before command gets run from           * Create socket early so it will exist before command gets run from
Line 755 
Line 804 
                 perror("listen");                  perror("listen");
                 cleanup_exit(1);                  cleanup_exit(1);
         }          }
   
         /*          /*
          * Fork, and have the parent execute the command, if any, or present           * Fork, and have the parent execute the command, if any, or present
          * the socket data.  The child continues as the authentication agent.           * the socket data.  The child continues as the authentication agent.
Line 770 
Line 820 
                 if (ac == 0) {                  if (ac == 0) {
                         format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";                          format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
                         printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,                          printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
                                SSH_AUTHSOCKET_ENV_NAME);                              SSH_AUTHSOCKET_ENV_NAME);
                         printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,                          printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
                                SSH_AGENTPID_ENV_NAME);                              SSH_AGENTPID_ENV_NAME);
                         printf("echo Agent pid %d;\n", pid);                          printf("echo Agent pid %d;\n", pid);
                         exit(0);                          exit(0);
                 }                  }
Line 789 
Line 839 
         close(1);          close(1);
         close(2);          close(2);
   
           /* deny core dumps, since memory contains unencrypted private keys */
           rlim.rlim_cur = rlim.rlim_max = 0;
           if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
                   perror("setrlimit rlimit_core failed");
                   cleanup_exit(1);
           }
         if (setsid() == -1) {          if (setsid() == -1) {
                 perror("setsid");                  perror("setsid");
                 cleanup_exit(1);                  cleanup_exit(1);
Line 805 
Line 861 
         idtab_init();          idtab_init();
         signal(SIGINT, SIG_IGN);          signal(SIGINT, SIG_IGN);
         signal(SIGPIPE, SIG_IGN);          signal(SIGPIPE, SIG_IGN);
         signal(SIGHUP, cleanup_exit);          signal(SIGHUP, cleanup_handler);
         signal(SIGTERM, cleanup_exit);          signal(SIGTERM, cleanup_handler);
         while (1) {          while (1) {
                 FD_ZERO(&readset);                  prepare_select(&readsetp, &writesetp, &max_fd);
                 FD_ZERO(&writeset);                  if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) {
                 prepare_select(&readset, &writeset);  
                 if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0) {  
                         if (errno == EINTR)                          if (errno == EINTR)
                                 continue;                                  continue;
                         exit(1);                          exit(1);
                 }                  }
                 after_select(&readset, &writeset);                  after_select(readsetp, writesetp);
         }          }
         /* NOTREACHED */          /* NOTREACHED */
 }  }

Legend:
Removed from v.1.37  
changed lines
  Added in v.1.37.2.1