[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.54 and 1.54.2.1

version 1.54, 2001/04/03 13:56:11 version 1.54.2.1, 2001/09/27 19:03:55
Line 12 
Line 12 
  * incompatible with the protocol description in the RFC file, it must be   * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".   * called by a name other than "ssh" or "Secure Shell".
  *   *
  * SSH2 implementation,   * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 57 
Line 56 
 #include "compat.h"  #include "compat.h"
 #include "log.h"  #include "log.h"
   
   #ifdef SMARTCARD
   #include <openssl/engine.h>
   #include "scard.h"
   #endif
   
 typedef struct {  typedef struct {
         int fd;          int fd;
         enum {          enum {
Line 93 
Line 97 
   
 extern char *__progname;  extern char *__progname;
   
 int     prepare_select(fd_set **, fd_set **, int *);  static void
   
 void  
 idtab_init(void)  idtab_init(void)
 {  {
         int i;          int i;
Line 106 
Line 108 
 }  }
   
 /* return private key table for requested protocol version */  /* return private key table for requested protocol version */
 Idtab *  static Idtab *
 idtab_lookup(int version)  idtab_lookup(int version)
 {  {
         if (version < 1 || version > 2)          if (version < 1 || version > 2)
Line 115 
Line 117 
 }  }
   
 /* return matching private key for given public key */  /* return matching private key for given public key */
 Key *  static Key *
 lookup_private_key(Key *key, int *idx, int version)  lookup_private_key(Key *key, int *idx, int version)
 {  {
         int i;          int i;
Line 131 
Line 133 
 }  }
   
 /* send list of supported public keys to 'client' */  /* send list of supported public keys to 'client' */
 void  static void
 process_request_identities(SocketEntry *e, int version)  process_request_identities(SocketEntry *e, int version)
 {  {
         Idtab *tab = idtab_lookup(version);          Idtab *tab = idtab_lookup(version);
Line 163 
Line 165 
 }  }
   
 /* ssh1 only */  /* ssh1 only */
 void  static void
 process_authentication_challenge1(SocketEntry *e)  process_authentication_challenge1(SocketEntry *e)
 {  {
         Key *key, *private;          Key *key, *private;
Line 229 
Line 231 
 }  }
   
 /* ssh2 only */  /* ssh2 only */
 void  static void
 process_sign_request2(SocketEntry *e)  process_sign_request2(SocketEntry *e)
 {  {
         extern int datafellows;          extern int datafellows;
Line 274 
Line 276 
 }  }
   
 /* shared */  /* shared */
 void  static void
 process_remove_identity(SocketEntry *e, int version)  process_remove_identity(SocketEntry *e, int version)
 {  {
         Key *key = NULL, *private;          Key *key = NULL, *private;
Line 335 
Line 337 
             success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);              success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
 }  }
   
 void  static void
 process_remove_all_identities(SocketEntry *e, int version)  process_remove_all_identities(SocketEntry *e, int version)
 {  {
         u_int i;          u_int i;
Line 356 
Line 358 
         return;          return;
 }  }
   
 void  static void
 process_add_identity(SocketEntry *e, int version)  process_add_identity(SocketEntry *e, int version)
 {  {
         Key *k = NULL;          Key *k = NULL;
Line 379 
Line 381 
                 buffer_get_bignum(&e->input, k->rsa->p);        /* q */                  buffer_get_bignum(&e->input, k->rsa->p);        /* q */
   
                 /* Generate additional parameters */                  /* Generate additional parameters */
                 generate_additional_parameters(k->rsa);                  rsa_generate_additional_parameters(k->rsa);
                 break;                  break;
         case 2:          case 2:
                 type_name = buffer_get_string(&e->input, NULL);                  type_name = buffer_get_string(&e->input, NULL);
Line 404 
Line 406 
                         buffer_get_bignum2(&e->input, k->rsa->q);                          buffer_get_bignum2(&e->input, k->rsa->q);
   
                         /* Generate additional parameters */                          /* Generate additional parameters */
                         generate_additional_parameters(k->rsa);                          rsa_generate_additional_parameters(k->rsa);
                         break;                          break;
                 default:                  default:
                         buffer_clear(&e->input);                          buffer_clear(&e->input);
Line 438 
Line 440 
             success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);              success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
 }  }
   
   
   #ifdef SMARTCARD
   static void
   process_add_smartcard_key (SocketEntry *e)
   {
           Idtab *tab;
           Key *n = NULL, *k = NULL;
           char *sc_reader_id = NULL;
           int success = 0;
   
           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;
           }
           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));
                   else
                           tab->identities = xrealloc(tab->identities,
                               (tab->nentries + 1) * sizeof(Identity));
                   n = key_new(KEY_RSA1);
                   BN_copy(n->rsa->n, k->rsa->n);
                   BN_copy(n->rsa->e, k->rsa->e);
                   RSA_set_method(n->rsa, sc_get_engine());
                   tab->identities[tab->nentries].key = n;
                   tab->identities[tab->nentries].comment =
                       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)
                           tab->identities = xmalloc(sizeof(Identity));
                   else
                           tab->identities = xrealloc(tab->identities,
                               (tab->nentries + 1) * sizeof(Identity));
                   n = key_new(KEY_RSA);
                   BN_copy(n->rsa->n, k->rsa->n);
                   BN_copy(n->rsa->e, k->rsa->e);
                   RSA_set_method(n->rsa, sc_get_engine());
                   tab->identities[tab->nentries].key = n;
                   tab->identities[tab->nentries].comment =
                       xstrdup("rsa smartcard");
                   tab->nentries++;
           }
           key_free(k);
   send:
           buffer_put_int(&e->output, 1);
           buffer_put_char(&e->output,
               success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
   }
   
   static void
   process_remove_smartcard_key(SocketEntry *e)
   {
           Key *k = NULL, *private;
           int idx;
           int success = 0;
           char *sc_reader_id = NULL;
   
           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");
           } else {
                   k->type = KEY_RSA1;
                   private = lookup_private_key(k, &idx, 1);
                   if (private != NULL) {
                           Idtab *tab = idtab_lookup(1);
                           key_free(tab->identities[idx].key);
                           xfree(tab->identities[idx].comment);
                           if (idx != tab->nentries)
                                   tab->identities[idx] = tab->identities[tab->nentries];
                           tab->nentries--;
                           success = 1;
                   }
                   k->type = KEY_RSA;
                   private = lookup_private_key(k, &idx, 2);
                   if (private != NULL) {
                           Idtab *tab = idtab_lookup(2);
                           key_free(tab->identities[idx].key);
                           xfree(tab->identities[idx].comment);
                           if (idx != tab->nentries)
                                   tab->identities[idx] = tab->identities[tab->nentries];
                           tab->nentries--;
                           success = 1;
                   }
                   key_free(k);
           }
   
           buffer_put_int(&e->output, 1);
           buffer_put_char(&e->output,
               success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
   }
   #endif /* SMARTCARD */
   
 /* dispatch incoming messages */  /* dispatch incoming messages */
   
 void  static void
 process_message(SocketEntry *e)  process_message(SocketEntry *e)
 {  {
         u_int msg_len;          u_int msg_len;
Line 461 
Line 570 
         buffer_consume(&e->input, 4);          buffer_consume(&e->input, 4);
         type = buffer_get_char(&e->input);          type = buffer_get_char(&e->input);
   
           debug("type %d", type);
         switch (type) {          switch (type) {
         /* ssh1 */          /* ssh1 */
         case SSH_AGENTC_RSA_CHALLENGE:          case SSH_AGENTC_RSA_CHALLENGE:
Line 494 
Line 604 
         case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:          case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
                 process_remove_all_identities(e, 2);                  process_remove_all_identities(e, 2);
                 break;                  break;
   #ifdef SMARTCARD
           case SSH_AGENTC_ADD_SMARTCARD_KEY:
                   process_add_smartcard_key(e);
                   break;
           case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
                   process_remove_smartcard_key(e);
                   break;
   #endif /* SMARTCARD */
         default:          default:
                 /* Unknown message.  Respond with failure. */                  /* Unknown message.  Respond with failure. */
                 error("Unknown message %d", type);                  error("Unknown message %d", type);
Line 504 
Line 622 
         }          }
 }  }
   
 void  static void
 new_socket(int type, int fd)  new_socket(int type, int fd)
 {  {
         u_int i, old_alloc;          u_int i, old_alloc;
Line 536 
Line 654 
         buffer_init(&sockets[old_alloc].output);          buffer_init(&sockets[old_alloc].output);
 }  }
   
 int  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;          u_int i, sz;
         int n = 0;          int n = 0;
Line 557 
Line 675 
         }          }
   
         sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);          sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
         if (*fdrp == NULL || n > *fdl) {          if (*fdrp == NULL || sz > *nallocp) {
                 if (*fdrp)                  if (*fdrp)
                         xfree(*fdrp);                          xfree(*fdrp);
                 if (*fdwp)                  if (*fdwp)
                         xfree(*fdwp);                          xfree(*fdwp);
                 *fdrp = xmalloc(sz);                  *fdrp = xmalloc(sz);
                 *fdwp = 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(*fdrp, 0, sz);
         memset(*fdwp, 0, sz);          memset(*fdwp, 0, sz);
   
Line 584 
Line 705 
         return (1);          return (1);
 }  }
   
 void  static void
 after_select(fd_set *readset, fd_set *writeset)  after_select(fd_set *readset, fd_set *writeset)
 {  {
         u_int i;          u_int i;
Line 656 
Line 777 
                 }                  }
 }  }
   
 void  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;  
 }  
   
 void  
 cleanup_socket(void)  cleanup_socket(void)
 {  {
         if (socket_name[0])          if (socket_name[0])
Line 679 
Line 786 
                 rmdir(socket_dir);                  rmdir(socket_dir);
 }  }
   
 void  static void
 cleanup_exit(int i)  cleanup_exit(int i)
 {  {
         cleanup_socket();          cleanup_socket();
         exit(i);          exit(i);
 }  }
   
 void  static void
 cleanup_handler(int sig)  cleanup_handler(int sig)
 {  {
         cleanup_socket();          cleanup_socket();
         _exit(2);          _exit(2);
 }  }
   
 void  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)  usage(void)
 {  {
         fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);          fprintf(stderr, "Usage: %s [options] [command [args ...]]\n",
         fprintf(stderr, "Usage: %s [-c | -s] [-k] [command {args...]]\n",  
             __progname);              __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);          exit(1);
 }  }
   
 int  int
 main(int ac, char **av)  main(int ac, char **av)
 {  {
         int sock, c_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;          struct sockaddr_un sunaddr;
         struct rlimit rlim;          struct rlimit rlim;
         pid_t pid;          pid_t pid;
Line 715 
Line 840 
   
         SSLeay_add_all_algorithms();          SSLeay_add_all_algorithms();
   
         while ((ch = getopt(ac, av, "cks")) != -1) {          while ((ch = getopt(ac, av, "cdks")) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'c':                  case 'c':
                         if (s_flag)                          if (s_flag)
Line 730 
Line 855 
                                 usage();                                  usage();
                         s_flag++;                          s_flag++;
                         break;                          break;
                   case 'd':
                           if (d_flag)
                                   usage();
                           d_flag++;
                           break;
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 737 
Line 867 
         ac -= optind;          ac -= optind;
         av += optind;          av += optind;
   
         if (ac > 0 && (c_flag || k_flag || s_flag))          if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
                 usage();                  usage();
   
         if (ac == 0 && !c_flag && !k_flag && !s_flag) {          if (ac == 0 && !c_flag && !k_flag && !s_flag && !d_flag) {
                 shell = getenv("SHELL");                  shell = getenv("SHELL");
                 if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)                  if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
                         c_flag = 1;                          c_flag = 1;
Line 804 
Line 934 
          * 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.
          */           */
           if (d_flag) {
                   log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
                   format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
                   printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
                       SSH_AUTHSOCKET_ENV_NAME);
                   printf("echo Agent pid %d;\n", parent_pid);
                   goto skip;
           }
         pid = fork();          pid = fork();
         if (pid == -1) {          if (pid == -1) {
                 perror("fork");                  perror("fork");
Line 830 
Line 968 
                 perror(av[0]);                  perror(av[0]);
                 exit(1);                  exit(1);
         }          }
   
           if (setsid() == -1) {
                   perror("setsid");
                   cleanup_exit(1);
           }
   
           (void)chdir("/");
         close(0);          close(0);
         close(1);          close(1);
         close(2);          close(2);
Line 840 
Line 985 
                 perror("setrlimit rlimit_core failed");                  perror("setrlimit rlimit_core failed");
                 cleanup_exit(1);                  cleanup_exit(1);
         }          }
         if (setsid() == -1) {  
                 perror("setsid");  skip:
                 cleanup_exit(1);  
         }  
         if (atexit(cleanup_socket) < 0) {          if (atexit(cleanup_socket) < 0) {
                 perror("atexit");                  perror("atexit");
                 cleanup_exit(1);                  cleanup_exit(1);
Line 854 
Line 997 
                 alarm(10);                  alarm(10);
         }          }
         idtab_init();          idtab_init();
         signal(SIGINT, SIG_IGN);          if (!d_flag)
                   signal(SIGINT, SIG_IGN);
         signal(SIGPIPE, SIG_IGN);          signal(SIGPIPE, SIG_IGN);
         signal(SIGHUP, cleanup_handler);          signal(SIGHUP, cleanup_handler);
         signal(SIGTERM, cleanup_handler);          signal(SIGTERM, cleanup_handler);
           nalloc = 0;
   
         while (1) {          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 (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) {
                         if (errno == EINTR)                          if (errno == EINTR)
                                 continue;                                  continue;

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.54.2.1