[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.69.2.3 and 1.69.2.4

version 1.69.2.3, 2001/03/21 19:46:30 version 1.69.2.4, 2001/05/07 21:09:36
Line 67 
Line 67 
 #include "misc.h"  #include "misc.h"
 #include "kex.h"  #include "kex.h"
 #include "mac.h"  #include "mac.h"
   #include "sshtty.h"
   
 extern char *__progname;  extern char *__progname;
   
Line 122 
Line 123 
  */   */
 volatile int received_window_change_signal = 0;  volatile int received_window_change_signal = 0;
   
 /* Flag indicating whether we have a valid host private key loaded. */  /* Private host keys. */
 int host_private_key_loaded = 0;  struct {
           Key     **keys;
           int     nkeys;
   } sensitive_data;
   
 /* Host private key. */  
 RSA *host_private_key = NULL;  
   
 /* Original real UID. */  /* Original real UID. */
 uid_t original_real_uid;  uid_t original_real_uid;
   
Line 255 
Line 256 
                 if (setrlimit(RLIMIT_CORE, &rlim) < 0)                  if (setrlimit(RLIMIT_CORE, &rlim) < 0)
                         fatal("setrlimit failed: %.100s", strerror(errno));                          fatal("setrlimit failed: %.100s", strerror(errno));
         }          }
           /* Get user data. */
           pw = getpwuid(original_real_uid);
           if (!pw) {
                   log("You don't exist, go away!");
                   exit(1);
           }
           /* Take a copy of the returned structure. */
           pw = pwcopy(pw);
   
         /*          /*
          * Use uid-swapping to give up root privileges for the duration of           * Use uid-swapping to give up root privileges for the duration of
          * option processing.  We will re-instantiate the rights when we are           * option processing.  We will re-instantiate the rights when we are
Line 262 
Line 272 
          * them when the port has been created (actually, when the connection           * them when the port has been created (actually, when the connection
          * has been made, as we may need to create the port several times).           * has been made, as we may need to create the port several times).
          */           */
         temporarily_use_uid(original_real_uid);          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
Line 295 
Line 305 
                 opt = av[optind][1];                  opt = av[optind][1];
                 if (!opt)                  if (!opt)
                         usage();                          usage();
                 if (strchr("eilcmpLRo", opt)) { /* options with arguments */                  if (strchr("eilcmpLRDo", opt)) {   /* options with arguments */
                         optarg = av[optind] + 2;                          optarg = av[optind] + 2;
                         if (strcmp(optarg, "") == 0) {                          if (strcmp(optarg, "") == 0) {
                                 if (optind >= ac - 1)                                  if (optind >= ac - 1)
Line 434 
Line 444 
                         }                          }
                         break;                          break;
                 case 'p':                  case 'p':
                         options.port = atoi(optarg);                          options.port = a2port(optarg);
                           if (options.port == 0) {
                                   fprintf(stderr, "Bad port '%s'\n", optarg);
                                   exit(1);
                           }
                         break;                          break;
                 case 'l':                  case 'l':
                         options.user = optarg;                          options.user = optarg;
Line 461 
Line 475 
                         }                          }
                         add_local_forward(&options, fwd_port, buf, fwd_host_port);                          add_local_forward(&options, fwd_port, buf, fwd_host_port);
                         break;                          break;
   
                   case 'D':
                           fwd_port = a2port(optarg);
                           if (fwd_port == 0) {
                                   fprintf(stderr, "Bad dynamic port '%s'\n", optarg);
                                   exit(1);
                           }
                           add_local_forward(&options, fwd_port, "socks4", 0);
                           break;
   
                 case 'C':                  case 'C':
                         options.compression = 1;                          options.compression = 1;
                         break;                          break;
Line 504 
Line 528 
                 /* No command specified - execute shell on a tty. */                  /* No command specified - execute shell on a tty. */
                 tty_flag = 1;                  tty_flag = 1;
                 if (subsystem_flag) {                  if (subsystem_flag) {
                         fprintf(stderr, "You must specify a subsystem to invoke.");                          fprintf(stderr, "You must specify a subsystem to invoke.\n");
                         usage();                          usage();
                 }                  }
         } else {          } else {
Line 535 
Line 559 
                 tty_flag = 0;                  tty_flag = 0;
         }          }
   
         /* Get user data. */  
         pw = getpwuid(original_real_uid);  
         if (!pw) {  
                 log("You don't exist, go away!");  
                 exit(1);  
         }  
         /* Take a copy of the returned structure. */  
         pw = pwcopy(pw);  
   
         /*          /*
          * Initialize "log" output.  Since we are the client all output           * Initialize "log" output.  Since we are the client all output
          * actually goes to stderr.           * actually goes to stderr.
          */           */
         log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);          log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
               SYSLOG_FACILITY_USER, 1);
   
         /* Read per-user configuration file. */          /* Read per-user configuration file. */
         snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE);          snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE);
Line 587 
Line 603 
                 restore_uid();                  restore_uid();
   
                 /* Switch to the original uid permanently. */                  /* Switch to the original uid permanently. */
                 permanently_set_uid(original_real_uid);                  permanently_set_uid(pw);
   
                 /* Execute rsh. */                  /* Execute rsh. */
                 rsh_connect(host, options.user, &command);                  rsh_connect(host, options.user, &command);
Line 601 
Line 617 
         ok = ssh_connect(host, &hostaddr, options.port,          ok = ssh_connect(host, &hostaddr, options.port,
             options.connection_attempts,              options.connection_attempts,
             original_effective_uid != 0 || !options.use_privileged_port,              original_effective_uid != 0 || !options.use_privileged_port,
             original_real_uid,              pw, options.proxy_command);
             options.proxy_command);  
   
         /*          /*
          * If we successfully made the connection, load the host private key           * If we successfully made the connection, load the host private key
Line 610 
Line 625 
          * 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 (ok && (options.protocol & SSH_PROTO_1)) {          sensitive_data.nkeys = 0;
                 Key k;          sensitive_data.keys = NULL;
                 host_private_key = RSA_new();          if (ok && (options.rhosts_rsa_authentication ||
                 k.type = KEY_RSA1;              options.hostbased_authentication)) {
                 k.rsa = host_private_key;                  sensitive_data.nkeys = 3;
                 if (load_private_key(_PATH_HOST_KEY_FILE, "", &k, NULL))                  sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
                         host_private_key_loaded = 1;                  sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
                       _PATH_HOST_KEY_FILE, "", NULL);
                   sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
                       _PATH_HOST_DSA_KEY_FILE, "", NULL);
                   sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
                       _PATH_HOST_RSA_KEY_FILE, "", NULL);
         }          }
         /*          /*
          * 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 633 
Line 653 
          * process, read the private hostkey and impersonate the host.           * process, read the private hostkey and impersonate the host.
          * OpenBSD does not allow ptracing of setuid processes.           * OpenBSD does not allow ptracing of setuid processes.
          */           */
         permanently_set_uid(original_real_uid);          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
Line 675 
Line 695 
             tilde_expand_filename(options.user_hostfile2, original_real_uid);              tilde_expand_filename(options.user_hostfile2, original_real_uid);
   
         /* 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(host_private_key_loaded, host_private_key,          ssh_login(sensitive_data.keys, sensitive_data.nkeys,
                   host, (struct sockaddr *)&hostaddr, original_real_uid);              host, (struct sockaddr *)&hostaddr, pw);
   
         /* We no longer need the host private key.  Clear it now. */          /* We no longer need the private host keys.  Clear them now. */
         if (host_private_key_loaded)          if (sensitive_data.nkeys != 0) {
                 RSA_free(host_private_key);     /* Destroys contents safely */                  for (i = 0; i < sensitive_data.nkeys; i++) {
                           if (sensitive_data.keys[i] != NULL) {
                                   /* Destroys contents safely */
                                   debug3("clear hostkey %d", i);
                                   key_free(sensitive_data.keys[i]);
                                   sensitive_data.keys[i] = NULL;
                           }
                   }
                   xfree(sensitive_data.keys);
           }
   
         exit_status = compat20 ? ssh_session2() : ssh_session();          exit_status = compat20 ? ssh_session2() : ssh_session();
         packet_close();          packet_close();
Line 826 
Line 855 
                 packet_put_int(ws.ws_ypixel);                  packet_put_int(ws.ws_ypixel);
   
                 /* Store tty modes in the packet. */                  /* Store tty modes in the packet. */
                 tty_make_modes(fileno(stdin));                  tty_make_modes(fileno(stdin), NULL);
   
                 /* Send the packet, and wait for it to leave. */                  /* Send the packet, and wait for it to leave. */
                 packet_send();                  packet_send();
Line 930 
Line 959 
 {  {
         int len;          int len;
         int interactive = 0;          int interactive = 0;
           struct termios tio;
   
         debug("client_init id %d arg %ld", id, (long)arg);          debug("client_init id %d arg %ld", id, (long)arg);
   
         if (no_shell_flag)  
                 goto done;  
   
         if (tty_flag) {          if (tty_flag) {
                 struct winsize ws;                  struct winsize ws;
                 char *cp;                  char *cp;
Line 952 
Line 979 
                 packet_put_int(ws.ws_row);                  packet_put_int(ws.ws_row);
                 packet_put_int(ws.ws_xpixel);                  packet_put_int(ws.ws_xpixel);
                 packet_put_int(ws.ws_ypixel);                  packet_put_int(ws.ws_ypixel);
                 packet_put_cstring("");         /* XXX: encode terminal modes */                  tio = get_saved_tio();
                   tty_make_modes(/*ignored*/ 0, &tio);
                 packet_send();                  packet_send();
                 interactive = 1;                  interactive = 1;
                 /* XXX wait for reply */                  /* XXX wait for reply */
Line 998 
Line 1026 
         }          }
         /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */          /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
   
 done:  
         /* register different callback, etc. XXX */          /* register different callback, etc. XXX */
         packet_set_interactive(interactive);          packet_set_interactive(interactive);
 }  }
   
 int  int
 ssh_session2(void)  ssh_session2_command(void)
 {  {
         int window, packetmax, id;          int id, window, packetmax;
         int in, out, err;          int in, out, err;
   
         if (stdin_null_flag) {          if (stdin_null_flag) {
Line 1028 
Line 1055 
         if (!isatty(err))          if (!isatty(err))
                 set_nonblock(err);                  set_nonblock(err);
   
         /* XXX should be pre-session */  
         ssh_init_forwarding();  
   
         /* If requested, let ssh continue in the background. */  
         if (fork_after_authentication_flag)  
                 if (daemon(1, 1) < 0)  
                         fatal("daemon() failed: %.200s", strerror(errno));  
   
         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) {
Line 1047 
Line 1066 
             window, packetmax, CHAN_EXTENDED_WRITE,              window, packetmax, CHAN_EXTENDED_WRITE,
             xstrdup("client-session"), /*nonblock*/0);              xstrdup("client-session"), /*nonblock*/0);
   
   debug("channel_new: %d", id);
   
         channel_open(id);          channel_open(id);
         channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,          channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
              ssh_session2_callback, (void *)0);               ssh_session2_callback, (void *)0);
   
         return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id);          return id;
 }  }
   
 int  int
 guess_identity_file_type(const char *filename)  ssh_session2(void)
 {  {
         struct stat st;          int id;
         Key *public;  
         int type = KEY_RSA1; /* default */  
   
         if (stat(filename, &st) < 0) {          /* XXX should be pre-session */
                 /* ignore this key */          ssh_init_forwarding();
                 return KEY_UNSPEC;  
         }          id = no_shell_flag ? -1 : ssh_session2_command();
         public = key_new(type);  
         if (!load_public_key(filename, public, NULL)) {          /* If requested, let ssh continue in the background. */
                 /* ok, so we will assume this is 'some' key */          if (fork_after_authentication_flag)
                 type = KEY_UNSPEC;                  if (daemon(1, 1) < 0)
         }                          fatal("daemon() failed: %.200s", strerror(errno));
         key_free(public);  
         return type;          return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id);
 }  }
   
 void  void
Line 1084 
Line 1103 
         for (i = 0; i < options.num_identity_files; i++) {          for (i = 0; i < options.num_identity_files; i++) {
                 filename = tilde_expand_filename(options.identity_files[i],                  filename = tilde_expand_filename(options.identity_files[i],
                     original_real_uid);                      original_real_uid);
                 public = key_new(KEY_RSA1);                  public = key_load_public(filename, NULL);
                 if (!load_public_key(filename, public, NULL)) {  
                         key_free(public);  
                         public = key_new(KEY_UNSPEC);  
                         if (!try_load_public_key(filename, public, NULL)) {  
                                 debug("unknown identity file %s", filename);  
                                 key_free(public);  
                                 public = NULL;  
                         }  
                 }  
                 debug("identity file %s type %d", filename,                  debug("identity file %s type %d", filename,
                     public ? public->type : -1);                      public ? public->type : -1);
                 xfree(options.identity_files[i]);                  xfree(options.identity_files[i]);

Legend:
Removed from v.1.69.2.3  
changed lines
  Added in v.1.69.2.4