[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 and 1.147.2.3

version 1.147, 2001/10/08 19:05:05 version 1.147.2.3, 2002/05/17 00:03:24
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 70 
Line 71 
 #include "sshtty.h"  #include "sshtty.h"
   
 #ifdef SMARTCARD  #ifdef SMARTCARD
 #include <openssl/engine.h>  
 #include "scard.h"  #include "scard.h"
 #endif  #endif
   
Line 123 
Line 123 
 /* socket address the host resolves to */  /* socket address the host resolves to */
 struct sockaddr_storage hostaddr;  struct sockaddr_storage hostaddr;
   
 /*  
  * Flag to indicate that we have received a window change signal which has  
  * not yet been processed.  This will cause a message indicating the new  
  * window size to be sent to the server a little later.  This is volatile  
  * because this is updated in a signal handler.  
  */  
 volatile int received_window_change_signal = 0;  
   
 /* Private host keys. */  /* Private host keys. */
 struct {  struct {
         Key     **keys;          Key     **keys;
Line 146 
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;
   
 /* 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 470 
Line 465 
                                 /* 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 480 
Line 475 
                                     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 740 
Line 735 
         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.keys, sensitive_data.nkeys,          ssh_login(sensitive_data.keys, sensitive_data.nkeys,
             host, (struct sockaddr *)&hostaddr, pw);              host, (struct sockaddr *)&hostaddr, pw);
Line 773 
Line 770 
 }  }
   
 static void  static void
 x11_get_proto(char *proto, int proto_len, char *data, int data_len)  x11_get_proto(char **_proto, char **_data)
 {  {
         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;
   
         if (options.xauth_location) {          *_proto = proto;
           *_data = data;
           proto[0] = data[0] = '\0';
           if (options.xauth_location && (display = getenv("DISPLAY"))) {
                 /* Try to get Xauthority information for the display. */                  /* Try to get Xauthority information for the display. */
                 snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL,                  if (strncmp(display, "localhost:", 10) == 0)
                     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, "%.100s list unix:%s 2>"
                               _PATH_DEVNULL, options.xauth_location, display+10);
                   else
                           snprintf(line, sizeof line, "%.100s 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 %s %s", proto, data) == 2)                      sscanf(line, "%*s %511s %511s", proto, data) == 2)
                         got_data = 1;                          got_data = 1;
                 if (f)                  if (f)
                         pclose(f);                          pclose(f);
Line 801 
Line 815 
         if (!got_data) {          if (!got_data) {
                 u_int32_t rand = 0;                  u_int32_t rand = 0;
   
                 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, data_len - 2 * i, "%02x", rand & 0xff);                          snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
                         rand >>= 8;                          rand >>= 8;
                 }                  }
         }          }
Line 823 
Line 837 
                     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_request_local_forwarding(                  success += channel_setup_local_fwd_listener(
                     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 862 
Line 876 
 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 880 
Line 893 
                 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(&plen);                  type = packet_read();
                 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 918 
Line 931 
                 packet_write_wait();                  packet_write_wait();
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read(&plen);                  type = packet_read();
                 if (type == SSH_SMSG_SUCCESS) {                  if (type == SSH_SMSG_SUCCESS) {
                         interactive = 1;                          interactive = 1;
                         have_tty = 1;                          have_tty = 1;
Line 929 
Line 942 
         }          }
         /* 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[512], data[512];                  char *proto, *data;
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 x11_get_proto(proto, sizeof proto, data, sizeof data);                  x11_get_proto(&proto, &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(&plen);                  type = packet_read();
                 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 957 
Line 970 
                 auth_request_forwarding();                  auth_request_forwarding();
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read(&plen);                  type = packet_read();
                 packet_integrity_check(plen, 0, type);                  packet_check_eom();
                 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 979 
Line 992 
                 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, buffer_ptr(&command));                  debug("Sending command: %.*s", len, (u_char *)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 997 
Line 1010 
 }  }
   
 static void  static void
 client_subsystem_reply(int type, int plen, void *ctxt)  client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
 {  {
         int id, len;          int id, len;
   
Line 1005 
Line 1018 
         len = buffer_len(&command);          len = buffer_len(&command);
         if (len > 900)          if (len > 900)
                 len = 900;                  len = 900;
         packet_done();          packet_check_eom();
         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, buffer_ptr(&command), id);                      len, (u_char *)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 1045 
Line 1079 
         }          }
         if (options.forward_x11 &&          if (options.forward_x11 &&
             getenv("DISPLAY") != NULL) {              getenv("DISPLAY") != NULL) {
                 char proto[512], data[512];                  char *proto, *data;
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 x11_get_proto(proto, sizeof proto, data, sizeof data);                  x11_get_proto(&proto, &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 1067 
Line 1101 
                 if (len > 900)                  if (len > 900)
                         len = 900;                          len = 900;
                 if (subsystem_flag) {                  if (subsystem_flag) {
                         debug("Sending subsystem: %.*s", len, buffer_ptr(&command));                          debug("Sending subsystem: %.*s", len, (u_char *)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 asume 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, buffer_ptr(&command));                          debug("Sending command: %.*s", len, (u_char *)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(id, "shell", 0);                  channel_request_start(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 1116 
Line 1149 
   
         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 *= 2;                  window >>= 1;
                 packetmax *=2;                  packetmax >>= 1;
         }          }
         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_callback(c->self,                  channel_register_confirm(c->self, ssh_session2_setup);
                      SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,  
                      ssh_session2_setup, (void *)0);  
   
         return c->self;          return c->self;
 }  }
Line 1162 
Line 1191 
 load_public_identity_files(void)  load_public_identity_files(void)
 {  {
         char *filename;          char *filename;
         Key *public;  
         int i = 0;          int i = 0;
           Key *public;
 #ifdef SMARTCARD  #ifdef SMARTCARD
         if (options.smartcard_device != NULL &&          Key **keys;
             options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES &&  
             (public = sc_get_key(options.smartcard_device)) != NULL ) {  
                 Key *new;  
   
                 if (options.num_identity_files + 2 > SSH_MAX_IDENTITY_FILES)          if (options.smartcard_device != NULL &&
                         options.num_identity_files = SSH_MAX_IDENTITY_FILES - 2;              options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
                 memmove(&options.identity_files[2], &options.identity_files[0],              (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {
                     sizeof(char *) * options.num_identity_files);                  int count = 0;
                 options.num_identity_files += 2;                  for (i = 0; keys[i] != NULL; i++) {
                 i = 2;                          count++;
                           memmove(&options.identity_files[1], &options.identity_files[0],
                 /* XXX ssh1 vs ssh2 */                              sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
                 new = key_new(KEY_RSA);                          memmove(&options.identity_keys[1], &options.identity_keys[0],
                 new->flags = KEY_FLAG_EXT;                              sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
                 BN_copy(new->rsa->n, public->rsa->n);                          options.num_identity_files++;
                 BN_copy(new->rsa->e, public->rsa->e);                          options.identity_keys[0] = keys[i];
                 RSA_set_method(new->rsa, sc_get_engine());                          options.identity_files[0] = xstrdup("smartcard key");;
                 options.identity_keys[0] = new;                  }
                 options.identity_files[0] = xstrdup("smartcard rsa key");;                  if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
                           options.num_identity_files = SSH_MAX_IDENTITY_FILES;
                 new = key_new(KEY_RSA1);                  i = count;
                 new->flags = KEY_FLAG_EXT;                  xfree(keys);
                 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  
changed lines
  Added in v.1.147.2.3