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

Diff for /src/usr.bin/ssh/ssh.c between version 1.147.2.5 and 1.148

version 1.147.2.5, 2002/10/11 14:53:07 version 1.148, 2001/10/24 08:41:20
Line 13 
Line 13 
  * called by a name other than "ssh" or "Secure Shell".   * called by a name other than "ssh" or "Secure Shell".
  *   *
  * Copyright (c) 1999 Niels Provos.  All rights reserved.   * Copyright (c) 1999 Niels Provos.  All rights reserved.
  * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.  
  *   *
  * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>   * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
  * in Canada (German citizen).   * in Canada (German citizen).
Line 53 
Line 52 
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "packet.h"  #include "packet.h"
 #include "buffer.h"  #include "buffer.h"
   #include "uidswap.h"
 #include "channels.h"  #include "channels.h"
 #include "key.h"  #include "key.h"
 #include "authfd.h"  #include "authfd.h"
Line 70 
Line 70 
 #include "sshtty.h"  #include "sshtty.h"
   
 #ifdef SMARTCARD  #ifdef SMARTCARD
   #include <openssl/engine.h>
 #include "scard.h"  #include "scard.h"
 #endif  #endif
   
Line 98 
Line 99 
   
 /*  /*
  * Flag indicating that ssh should fork after authentication.  This is useful   * Flag indicating that ssh should fork after authentication.  This is useful
  * so that the passphrase can be entered manually, and then ssh goes to the   * so that the pasphrase can be entered manually, and then ssh goes to the
  * background.   * background.
  */   */
 int fork_after_authentication_flag = 0;  int fork_after_authentication_flag = 0;
Line 123 
Line 124 
 struct sockaddr_storage hostaddr;  struct sockaddr_storage hostaddr;
   
 /* Private host keys. */  /* Private host keys. */
 Sensitive sensitive_data;  struct {
           Key     **keys;
           int     nkeys;
   } sensitive_data;
   
 /* Original real UID. */  /* Original real UID. */
 uid_t original_real_uid;  uid_t original_real_uid;
 uid_t original_effective_uid;  
   
 /* command to be executed */  /* command to be executed */
 Buffer command;  Buffer command;
Line 135 
Line 138 
 /* Should we execute a command or invoke a subsystem? */  /* Should we execute a command or invoke a subsystem? */
 int subsystem_flag = 0;  int subsystem_flag = 0;
   
 /* # of replies received for global requests */  
 static int client_global_request_id = 0;  
   
 /* pid of proxycommand child process */  
 pid_t proxy_command_pid = 0;  
   
 /* Prints a help message to the user.  This function never returns. */  /* Prints a help message to the user.  This function never returns. */
   
 static void  static void
Line 169 
Line 166 
         fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");          fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
         fprintf(stderr, "              Multiple -v increases verbosity.\n");          fprintf(stderr, "              Multiple -v increases verbosity.\n");
         fprintf(stderr, "  -V          Display version number only.\n");          fprintf(stderr, "  -V          Display version number only.\n");
           fprintf(stderr, "  -P          Don't allocate a privileged port.\n");
         fprintf(stderr, "  -q          Quiet; don't display any warning messages.\n");          fprintf(stderr, "  -q          Quiet; don't display any warning messages.\n");
         fprintf(stderr, "  -f          Fork into background after authentication.\n");          fprintf(stderr, "  -f          Fork into background after authentication.\n");
         fprintf(stderr, "  -e char     Set escape character; ``none'' = disable (default: ~).\n");          fprintf(stderr, "  -e char     Set escape character; ``none'' = disable (default: ~).\n");
Line 194 
Line 192 
         exit(1);          exit(1);
 }  }
   
   /*
    * Connects to the given host using rsh (or prints an error message and exits
    * if rsh is not available).  This function never returns.
    */
   static void
   rsh_connect(char *host, char *user, Buffer * command)
   {
           char *args[10];
           int i;
   
           log("Using rsh.  WARNING: Connection will not be encrypted.");
           /* Build argument list for rsh. */
           i = 0;
           args[i++] = _PATH_RSH;
           /* host may have to come after user on some systems */
           args[i++] = host;
           if (user) {
                   args[i++] = "-l";
                   args[i++] = user;
           }
           if (buffer_len(command) > 0) {
                   buffer_append(command, "\0", 1);
                   args[i++] = buffer_ptr(command);
           }
           args[i++] = NULL;
           if (debug_flag) {
                   for (i = 0; args[i]; i++) {
                           if (i != 0)
                                   fprintf(stderr, " ");
                           fprintf(stderr, "%s", args[i]);
                   }
                   fprintf(stderr, "\n");
           }
           execv(_PATH_RSH, args);
           perror(_PATH_RSH);
           exit(1);
   }
   
 static int ssh_session(void);  static int ssh_session(void);
 static int ssh_session2(void);  static int ssh_session2(void);
 static void load_public_identity_files(void);  static void load_public_identity_files(void);
Line 204 
Line 240 
 int  int
 main(int ac, char **av)  main(int ac, char **av)
 {  {
         int i, opt, exit_status;          int i, opt, exit_status, cerr;
         u_short fwd_port, fwd_host_port;          u_short fwd_port, fwd_host_port;
         char sfwd_port[6], sfwd_host_port[6];          char sfwd_port[6], sfwd_host_port[6];
         char *p, *cp, buf[256];          char *p, *cp, buf[256];
         struct stat st;          struct stat st;
         struct passwd *pw;          struct passwd *pw;
         int dummy;          int dummy;
           uid_t original_effective_uid;
         extern int optind, optreset;          extern int optind, optreset;
         extern char *optarg;          extern char *optarg;
   
Line 221 
Line 258 
         original_real_uid = getuid();          original_real_uid = getuid();
         original_effective_uid = geteuid();          original_effective_uid = geteuid();
   
         /*  
          * Use uid-swapping to give up root privileges for the duration of  
          * option processing.  We will re-instantiate the rights when we are  
          * ready to create the privileged port, and will permanently drop  
          * them when the port has been created (actually, when the connection  
          * has been made, as we may need to create the port several times).  
          */  
         PRIV_END;  
   
         /* If we are installed setuid root be careful to not drop core. */          /* If we are installed setuid root be careful to not drop core. */
         if (original_real_uid != original_effective_uid) {          if (original_real_uid != original_effective_uid) {
                 struct rlimit rlim;                  struct rlimit rlim;
Line 247 
Line 275 
         pw = pwcopy(pw);          pw = pwcopy(pw);
   
         /*          /*
            * Use uid-swapping to give up root privileges for the duration of
            * option processing.  We will re-instantiate the rights when we are
            * ready to create the privileged port, and will permanently drop
            * them when the port has been created (actually, when the connection
            * has been made, as we may need to create the port several times).
            */
           temporarily_use_uid(pw);
   
           /*
          * Set our umask to something reasonable, as some files are created           * Set our umask to something reasonable, as some files are created
          * with the default umask.  This will make them world-readable but           * with the default umask.  This will make them world-readable but
          * writable only by the owner, which is ok for all files for which we           * writable only by the owner, which is ok for all files for which we
Line 292 
Line 329 
                 case 'g':                  case 'g':
                         options.gateway_ports = 1;                          options.gateway_ports = 1;
                         break;                          break;
                 case 'P':       /* deprecated */                  case 'P':
                         options.use_privileged_port = 0;                          options.use_privileged_port = 0;
                         break;                          break;
                 case 'a':                  case 'a':
Line 425 
Line 462 
                                 /* NOTREACHED */                                  /* NOTREACHED */
                         }                          }
                         if ((fwd_port = a2port(sfwd_port)) == 0 ||                          if ((fwd_port = a2port(sfwd_port)) == 0 ||
                             (fwd_host_port = a2port(sfwd_host_port)) == 0) {                              (fwd_host_port = a2port(sfwd_host_port)) == 0) {
                                 fprintf(stderr,                                  fprintf(stderr,
                                     "Bad forwarding port(s) '%s'\n", optarg);                                      "Bad forwarding port(s) '%s'\n", optarg);
                                 exit(1);                                  exit(1);
Line 435 
Line 472 
                                     fwd_host_port);                                      fwd_host_port);
                         else if (opt == 'R')                          else if (opt == 'R')
                                 add_remote_forward(&options, fwd_port, buf,                                  add_remote_forward(&options, fwd_port, buf,
                                     fwd_host_port);                                       fwd_host_port);
                         break;                          break;
   
                 case 'D':                  case 'D':
Line 541 
Line 578 
         if (buffer_len(&command) == 0)          if (buffer_len(&command) == 0)
                 tty_flag = 1;                  tty_flag = 1;
   
         /* Force no tty */          /* Force no tty*/
         if (no_tty_flag)          if (no_tty_flag)
                 tty_flag = 0;                  tty_flag = 0;
         /* Do not allocate a tty if stdin is not a tty. */          /* Do not allocate a tty if stdin is not a tty. */
Line 593 
Line 630 
                     "originating port will not be trusted.");                      "originating port will not be trusted.");
                 options.rhosts_authentication = 0;                  options.rhosts_authentication = 0;
         }          }
           /*
            * If using rsh has been selected, exec it now (without trying
            * anything else).  Note that we must release privileges first.
            */
           if (options.use_rsh) {
                   /*
                    * Restore our superuser privileges.  This must be done
                    * before permanently setting the uid.
                    */
                   restore_uid();
   
                   /* Switch to the original uid permanently. */
                   permanently_set_uid(pw);
   
                   /* Execute rsh. */
                   rsh_connect(host, options.user, &command);
                   fatal("rsh_connect returned");
           }
           /* Restore our superuser privileges. */
           restore_uid();
   
         /* Open a connection to the remote host. */          /* Open a connection to the remote host. */
   
         if (ssh_connect(host, &hostaddr, options.port, IPv4or6,          cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
             options.connection_attempts,              options.connection_attempts,
             original_effective_uid == 0 && options.use_privileged_port,              original_effective_uid != 0 || !options.use_privileged_port,
             options.proxy_command) != 0)              pw, options.proxy_command);
                 exit(1);  
   
         /*          /*
          * If we successfully made the connection, load the host private key           * If we successfully made the connection, load the host private key
          * in case we will need it later for combined rsa-rhosts           * in case we will need it later for combined rsa-rhosts
          * authentication. This must be done before releasing extra           * authentication. This must be done before releasing extra
          * privileges, because the file is only readable by root.           * privileges, because the file is only readable by root.
          * If we cannot access the private keys, load the public keys  
          * instead and try to execute the ssh-keysign helper instead.  
          */           */
         sensitive_data.nkeys = 0;          sensitive_data.nkeys = 0;
         sensitive_data.keys = NULL;          sensitive_data.keys = NULL;
         sensitive_data.external_keysign = 0;          if (!cerr && (options.rhosts_rsa_authentication ||
         if (options.rhosts_rsa_authentication ||              options.hostbased_authentication)) {
             options.hostbased_authentication) {  
                 sensitive_data.nkeys = 3;                  sensitive_data.nkeys = 3;
                 sensitive_data.keys = xmalloc(sensitive_data.nkeys *                  sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
                     sizeof(Key));  
   
                 PRIV_START;  
                 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,                  sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
                     _PATH_HOST_KEY_FILE, "", NULL);                      _PATH_HOST_KEY_FILE, "", NULL);
                 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,                  sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
                     _PATH_HOST_DSA_KEY_FILE, "", NULL);                      _PATH_HOST_DSA_KEY_FILE, "", NULL);
                 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,                  sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
                     _PATH_HOST_RSA_KEY_FILE, "", NULL);                      _PATH_HOST_RSA_KEY_FILE, "", NULL);
                 PRIV_END;  
   
                 if (options.hostbased_authentication == 1 &&  
                     sensitive_data.keys[0] == NULL &&  
                     sensitive_data.keys[1] == NULL &&  
                     sensitive_data.keys[2] == NULL) {  
                         sensitive_data.keys[1] = key_load_public(  
                             _PATH_HOST_DSA_KEY_FILE, NULL);  
                         sensitive_data.keys[2] = key_load_public(  
                             _PATH_HOST_RSA_KEY_FILE, NULL);  
                         sensitive_data.external_keysign = 1;  
                 }  
         }          }
         /*          /*
          * Get rid of any extra privileges that we may have.  We will no           * Get rid of any extra privileges that we may have.  We will no
Line 645 
Line 684 
          * user's home directory if it happens to be on a NFS volume where           * user's home directory if it happens to be on a NFS volume where
          * root is mapped to nobody.           * root is mapped to nobody.
          */           */
         seteuid(original_real_uid);  
         setuid(original_real_uid);  
   
         /*          /*
            * Note that some legacy systems need to postpone the following call
            * to permanently_set_uid() until the private hostkey is destroyed
            * with RSA_free().  Otherwise the calling user could ptrace() the
            * process, read the private hostkey and impersonate the host.
            * OpenBSD does not allow ptracing of setuid processes.
            */
           permanently_set_uid(pw);
   
           /*
          * Now that we are back to our own permissions, create ~/.ssh           * Now that we are back to our own permissions, create ~/.ssh
          * directory if it doesn\'t already exist.           * directory if it doesn\'t already exist.
          */           */
Line 657 
Line 703 
                 if (mkdir(buf, 0700) < 0)                  if (mkdir(buf, 0700) < 0)
                         error("Could not create directory '%.200s'.", buf);                          error("Could not create directory '%.200s'.", buf);
   
           /* Check if the connection failed, and try "rsh" if appropriate. */
           if (cerr) {
                   if (!options.fallback_to_rsh)
                           exit(1);
                   if (options.port != 0)
                           log("Secure connection to %.100s on port %hu refused; "
                               "reverting to insecure method",
                               host, options.port);
                   else
                           log("Secure connection to %.100s refused; "
                               "reverting to insecure method.", host);
   
                   rsh_connect(host, options.user, &command);
                   fatal("rsh_connect returned");
           }
         /* load options.identity_files */          /* load options.identity_files */
         load_public_identity_files();          load_public_identity_files();
   
Line 671 
Line 732 
         options.user_hostfile2 =          options.user_hostfile2 =
             tilde_expand_filename(options.user_hostfile2, original_real_uid);              tilde_expand_filename(options.user_hostfile2, original_real_uid);
   
         signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */  
   
         /* Log into the remote system.  This never returns if the login fails. */          /* Log into the remote system.  This never returns if the login fails. */
         ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw);          ssh_login(sensitive_data.keys, sensitive_data.nkeys,
               host, (struct sockaddr *)&hostaddr, pw);
   
         /* We no longer need the private host keys.  Clear them now. */          /* We no longer need the private host keys.  Clear them now. */
         if (sensitive_data.nkeys != 0) {          if (sensitive_data.nkeys != 0) {
Line 701 
Line 761 
   
         exit_status = compat20 ? ssh_session2() : ssh_session();          exit_status = compat20 ? ssh_session2() : ssh_session();
         packet_close();          packet_close();
   
         /*  
          * Send SIGHUP to proxy command if used. We don't wait() in  
          * case it hangs and instead rely on init to reap the child  
          */  
         if (proxy_command_pid > 1)  
                 kill(proxy_command_pid, SIGHUP);  
   
         return exit_status;          return exit_status;
 }  }
   
 static void  static void
 x11_get_proto(char **_proto, char **_data)  x11_get_proto(char *proto, int proto_len, char *data, int data_len)
 {  {
         char line[512];          char line[512];
         static char proto[512], data[512];  
         FILE *f;          FILE *f;
         int got_data = 0, i;          int got_data = 0, i;
         char *display;  
         struct stat st;  
   
         *_proto = proto;          if (options.xauth_location) {
         *_data = data;  
         proto[0] = data[0] = '\0';  
         if (!options.xauth_location ||  
             (stat(options.xauth_location, &st) == -1)) {  
                 debug("No xauth program.");  
         } else {  
                 if ((display = getenv("DISPLAY")) == NULL) {  
                         debug("x11_get_proto: DISPLAY not set");  
                         return;  
                 }  
                 /* Try to get Xauthority information for the display. */                  /* Try to get Xauthority information for the display. */
                 if (strncmp(display, "localhost:", 10) == 0)                  snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL,
                         /*                      options.xauth_location, getenv("DISPLAY"));
                          * Handle FamilyLocal case where $DISPLAY does  
                          * not match an authorization entry.  For this we  
                          * just try "xauth list unix:displaynum.screennum".  
                          * XXX: "localhost" match to determine FamilyLocal  
                          *      is not perfect.  
                          */  
                         snprintf(line, sizeof line, "%s list unix:%s 2>"  
                             _PATH_DEVNULL, options.xauth_location, display+10);  
                 else  
                         snprintf(line, sizeof line, "%s list %.200s 2>"  
                             _PATH_DEVNULL, options.xauth_location, display);  
                 debug2("x11_get_proto: %s", line);  
                 f = popen(line, "r");                  f = popen(line, "r");
                 if (f && fgets(line, sizeof(line), f) &&                  if (f && fgets(line, sizeof(line), f) &&
                     sscanf(line, "%*s %511s %511s", proto, data) == 2)                      sscanf(line, "%*s %s %s", proto, data) == 2)
                         got_data = 1;                          got_data = 1;
                 if (f)                  if (f)
                         pclose(f);                          pclose(f);
Line 766 
Line 793 
         if (!got_data) {          if (!got_data) {
                 u_int32_t rand = 0;                  u_int32_t rand = 0;
   
                 log("Warning: No xauth data; using fake authentication data for X11 forwarding.");                  strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len);
                 strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);  
                 for (i = 0; i < 16; i++) {                  for (i = 0; i < 16; i++) {
                         if (i % 4 == 0)                          if (i % 4 == 0)
                                 rand = arc4random();                                  rand = arc4random();
                         snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);                          snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff);
                         rand >>= 8;                          rand >>= 8;
                 }                  }
         }          }
Line 789 
Line 815 
                     options.local_forwards[i].port,                      options.local_forwards[i].port,
                     options.local_forwards[i].host,                      options.local_forwards[i].host,
                     options.local_forwards[i].host_port);                      options.local_forwards[i].host_port);
                 success += channel_setup_local_fwd_listener(                  success += channel_request_local_forwarding(
                     options.local_forwards[i].port,                      options.local_forwards[i].port,
                     options.local_forwards[i].host,                      options.local_forwards[i].host,
                     options.local_forwards[i].host_port,                      options.local_forwards[i].host_port,
Line 816 
Line 842 
 {  {
         if (options.forward_agent) {          if (options.forward_agent) {
                 /* Clear agent forwarding if we don\'t have an agent. */                  /* Clear agent forwarding if we don\'t have an agent. */
                 if (!ssh_agent_present())                  int authfd = ssh_get_authentication_socket();
                   if (authfd < 0)
                         options.forward_agent = 0;                          options.forward_agent = 0;
                   else
                           ssh_close_authentication_socket(authfd);
         }          }
 }  }
   
Line 825 
Line 854 
 ssh_session(void)  ssh_session(void)
 {  {
         int type;          int type;
           int plen;
         int interactive = 0;          int interactive = 0;
         int have_tty = 0;          int have_tty = 0;
         struct winsize ws;          struct winsize ws;
Line 842 
Line 872 
                 packet_put_int(options.compression_level);                  packet_put_int(options.compression_level);
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
                 type = packet_read();                  type = packet_read(&plen);
                 if (type == SSH_SMSG_SUCCESS)                  if (type == SSH_SMSG_SUCCESS)
                         packet_start_compression(options.compression_level);                          packet_start_compression(options.compression_level);
                 else if (type == SSH_SMSG_FAILURE)                  else if (type == SSH_SMSG_FAILURE)
Line 880 
Line 910 
                 packet_write_wait();                  packet_write_wait();
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read();                  type = packet_read(&plen);
                 if (type == SSH_SMSG_SUCCESS) {                  if (type == SSH_SMSG_SUCCESS) {
                         interactive = 1;                          interactive = 1;
                         have_tty = 1;                          have_tty = 1;
Line 891 
Line 921 
         }          }
         /* Request X11 forwarding if enabled and DISPLAY is set. */          /* Request X11 forwarding if enabled and DISPLAY is set. */
         if (options.forward_x11 && getenv("DISPLAY") != NULL) {          if (options.forward_x11 && getenv("DISPLAY") != NULL) {
                 char *proto, *data;                  char proto[512], data[512];
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 x11_get_proto(&proto, &data);                  x11_get_proto(proto, sizeof proto, data, sizeof data);
                 /* Request forwarding with authentication spoofing. */                  /* Request forwarding with authentication spoofing. */
                 debug("Requesting X11 forwarding with authentication spoofing.");                  debug("Requesting X11 forwarding with authentication spoofing.");
                 x11_request_forwarding_with_spoofing(0, proto, data);                  x11_request_forwarding_with_spoofing(0, proto, data);
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read();                  type = packet_read(&plen);
                 if (type == SSH_SMSG_SUCCESS) {                  if (type == SSH_SMSG_SUCCESS) {
                         interactive = 1;                          interactive = 1;
                 } else if (type == SSH_SMSG_FAILURE) {                  } else if (type == SSH_SMSG_FAILURE) {
Line 919 
Line 949 
                 auth_request_forwarding();                  auth_request_forwarding();
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read();                  type = packet_read(&plen);
                 packet_check_eom();                  packet_integrity_check(plen, 0, type);
                 if (type != SSH_SMSG_SUCCESS)                  if (type != SSH_SMSG_SUCCESS)
                         log("Warning: Remote host denied authentication agent forwarding.");                          log("Warning: Remote host denied authentication agent forwarding.");
         }          }
Line 941 
Line 971 
                 int len = buffer_len(&command);                  int len = buffer_len(&command);
                 if (len > 900)                  if (len > 900)
                         len = 900;                          len = 900;
                 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));                  debug("Sending command: %.*s", len, buffer_ptr(&command));
                 packet_start(SSH_CMSG_EXEC_CMD);                  packet_start(SSH_CMSG_EXEC_CMD);
                 packet_put_string(buffer_ptr(&command), buffer_len(&command));                  packet_put_string(buffer_ptr(&command), buffer_len(&command));
                 packet_send();                  packet_send();
Line 959 
Line 989 
 }  }
   
 static void  static void
 client_subsystem_reply(int type, u_int32_t seq, void *ctxt)  client_subsystem_reply(int type, int plen, void *ctxt)
 {  {
         int id, len;          int id, len;
   
Line 967 
Line 997 
         len = buffer_len(&command);          len = buffer_len(&command);
         if (len > 900)          if (len > 900)
                 len = 900;                  len = 900;
         packet_check_eom();          packet_done();
         if (type == SSH2_MSG_CHANNEL_FAILURE)          if (type == SSH2_MSG_CHANNEL_FAILURE)
                 fatal("Request for subsystem '%.*s' failed on channel %d",                  fatal("Request for subsystem '%.*s' failed on channel %d",
                     len, (u_char *)buffer_ptr(&command), id);                      len, buffer_ptr(&command), id);
 }  }
   
 void  
 client_global_request_reply(int type, u_int32_t seq, void *ctxt)  
 {  
         int i;  
   
         i = client_global_request_id++;  
         if (i >= options.num_remote_forwards) {  
                 debug("client_global_request_reply: too many replies %d > %d",  
                     i, options.num_remote_forwards);  
                 return;  
         }  
         debug("remote forward %s for: listen %d, connect %s:%d",  
             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",  
             options.remote_forwards[i].port,  
             options.remote_forwards[i].host,  
             options.remote_forwards[i].host_port);  
         if (type == SSH2_MSG_REQUEST_FAILURE)  
                 log("Warning: remote port forwarding failed for listen port %d",  
                     options.remote_forwards[i].port);  
 }  
   
 /* request pty/x11/agent/tcpfwd/shell for channel */  /* request pty/x11/agent/tcpfwd/shell for channel */
 static void  static void
 ssh_session2_setup(int id, void *arg)  ssh_session2_setup(int id, void *arg)
Line 1028 
Line 1037 
         }          }
         if (options.forward_x11 &&          if (options.forward_x11 &&
             getenv("DISPLAY") != NULL) {              getenv("DISPLAY") != NULL) {
                 char *proto, *data;                  char proto[512], data[512];
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 x11_get_proto(&proto, &data);                  x11_get_proto(proto, sizeof proto, data, sizeof data);
                 /* Request forwarding with authentication spoofing. */                  /* Request forwarding with authentication spoofing. */
                 debug("Requesting X11 forwarding with authentication spoofing.");                  debug("Requesting X11 forwarding with authentication spoofing.");
                 x11_request_forwarding_with_spoofing(id, proto, data);                  x11_request_forwarding_with_spoofing(id, proto, data);
Line 1050 
Line 1059 
                 if (len > 900)                  if (len > 900)
                         len = 900;                          len = 900;
                 if (subsystem_flag) {                  if (subsystem_flag) {
                         debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));                          debug("Sending subsystem: %.*s", len, buffer_ptr(&command));
                         channel_request_start(id, "subsystem", /*want reply*/ 1);                          channel_request_start(id, "subsystem", /*want reply*/ 1);
                         /* register callback for reply */                          /* register callback for reply */
                         /* XXX we assume that client_loop has already been called */                          /* XXX we asume that client_loop has already been called */
                         dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);                          dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
                         dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);                          dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
                 } else {                  } else {
                         debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));                          debug("Sending command: %.*s", len, buffer_ptr(&command));
                         channel_request_start(id, "exec", 0);                          channel_request_start(id, "exec", 0);
                 }                  }
                 packet_put_string(buffer_ptr(&command), buffer_len(&command));                  packet_put_string(buffer_ptr(&command), buffer_len(&command));
                 packet_send();                  packet_send();
         } else {          } else {
                 channel_request_start(id, "shell", 0);                  channel_request(id, "shell", 0);
                 packet_send();  
         }          }
           /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
   
           /* register different callback, etc. XXX */
         packet_set_interactive(interactive);          packet_set_interactive(interactive);
 }  }
   
Line 1098 
Line 1108 
   
         window = CHAN_SES_WINDOW_DEFAULT;          window = CHAN_SES_WINDOW_DEFAULT;
         packetmax = CHAN_SES_PACKET_DEFAULT;          packetmax = CHAN_SES_PACKET_DEFAULT;
         if (tty_flag) {          if (!tty_flag) {
                 window >>= 1;                  window *= 2;
                 packetmax >>= 1;                  packetmax *=2;
         }          }
         c = channel_new(          c = channel_new(
             "session", SSH_CHANNEL_OPENING, in, out, err,              "session", SSH_CHANNEL_OPENING, in, out, err,
             window, packetmax, CHAN_EXTENDED_WRITE,              window, packetmax, CHAN_EXTENDED_WRITE,
             xstrdup("client-session"), /*nonblock*/0);              xstrdup("client-session"), /*nonblock*/0);
           if (c == NULL)
                   fatal("ssh_session2_open: channel_new failed");
   
         debug3("ssh_session2_open: channel_new: %d", c->self);          debug3("ssh_session2_open: channel_new: %d", c->self);
   
         channel_send_open(c->self);          channel_send_open(c->self);
         if (!no_shell_flag)          if (!no_shell_flag)
                 channel_register_confirm(c->self, ssh_session2_setup);                  channel_register_callback(c->self,
                        SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
                        ssh_session2_setup, (void *)0);
   
         return c->self;          return c->self;
 }  }
Line 1140 
Line 1154 
 load_public_identity_files(void)  load_public_identity_files(void)
 {  {
         char *filename;          char *filename;
         int i = 0;  
         Key *public;          Key *public;
 #ifdef SMARTCARD          int i = 0;
         Key **keys;  
   
   #ifdef SMARTCARD
         if (options.smartcard_device != NULL &&          if (options.smartcard_device != NULL &&
             options.num_identity_files < SSH_MAX_IDENTITY_FILES &&              options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES &&
             (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {              (public = sc_get_key(options.smartcard_device)) != NULL ) {
                 int count = 0;                  Key *new;
                 for (i = 0; keys[i] != NULL; i++) {  
                         count++;                  if (options.num_identity_files + 2 > SSH_MAX_IDENTITY_FILES)
                         memmove(&options.identity_files[1], &options.identity_files[0],                          options.num_identity_files = SSH_MAX_IDENTITY_FILES - 2;
                             sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));                  memmove(&options.identity_files[2], &options.identity_files[0],
                         memmove(&options.identity_keys[1], &options.identity_keys[0],                      sizeof(char *) * options.num_identity_files);
                             sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));                  options.num_identity_files += 2;
                         options.num_identity_files++;                  i = 2;
                         options.identity_keys[0] = keys[i];  
                         options.identity_files[0] = xstrdup("smartcard key");;                  /* XXX ssh1 vs ssh2 */
                 }                  new = key_new(KEY_RSA);
                 if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)                  new->flags = KEY_FLAG_EXT;
                         options.num_identity_files = SSH_MAX_IDENTITY_FILES;                  BN_copy(new->rsa->n, public->rsa->n);
                 i = count;                  BN_copy(new->rsa->e, public->rsa->e);
                 xfree(keys);                  RSA_set_method(new->rsa, sc_get_engine());
                   options.identity_keys[0] = new;
                   options.identity_files[0] = xstrdup("smartcard rsa key");;
   
                   new = key_new(KEY_RSA1);
                   new->flags = KEY_FLAG_EXT;
                   BN_copy(new->rsa->n, public->rsa->n);
                   BN_copy(new->rsa->e, public->rsa->e);
                   RSA_set_method(new->rsa, sc_get_engine());
                   options.identity_keys[1] = new;
                   options.identity_files[1] = xstrdup("smartcard rsa1 key");
   
                   key_free(public);
         }          }
 #endif /* SMARTCARD */  #endif /* SMARTCARD */
         for (; i < options.num_identity_files; i++) {          for (; i < options.num_identity_files; i++) {

Legend:
Removed from v.1.147.2.5  
changed lines
  Added in v.1.148