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

Diff for /src/usr.bin/ssh/session.c between version 1.42 and 1.42.2.3

version 1.42, 2000/10/27 07:32:18 version 1.42.2.3, 2001/03/21 19:46:28
Line 9 
Line 9 
  * called by a name other than "ssh" or "Secure Shell".   * called by a name other than "ssh" or "Secure Shell".
  *   *
  * SSH2 support by Markus Friedl.   * SSH2 support by Markus Friedl.
  * Copyright (c) 2000 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 35 
Line 35 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include "xmalloc.h"  
 #include "ssh.h"  #include "ssh.h"
 #include "pty.h"  #include "ssh1.h"
   #include "ssh2.h"
   #include "xmalloc.h"
   #include "sshpty.h"
 #include "packet.h"  #include "packet.h"
 #include "buffer.h"  #include "buffer.h"
 #include "mpaux.h"  #include "mpaux.h"
 #include "servconf.h"  
 #include "uidswap.h"  #include "uidswap.h"
 #include "compat.h"  #include "compat.h"
 #include "channels.h"  #include "channels.h"
 #include "nchan.h"  #include "nchan.h"
   
 #include "bufaux.h"  #include "bufaux.h"
 #include "ssh2.h"  
 #include "auth.h"  #include "auth.h"
 #include "auth-options.h"  #include "auth-options.h"
   #include "pathnames.h"
   #include "log.h"
   #include "servconf.h"
   #include "sshlogin.h"
   #include "serverloop.h"
   #include "canohost.h"
   #include "session.h"
   
 #ifdef HAVE_LOGIN_CAP  #ifdef HAVE_LOGIN_CAP
 #include <login_cap.h>  #include <login_cap.h>
Line 90 
Line 96 
 void    do_exec_pty(Session *s, const char *command, struct passwd * pw);  void    do_exec_pty(Session *s, const char *command, struct passwd * pw);
 void    do_exec_no_pty(Session *s, const char *command, struct passwd * pw);  void    do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
 void    do_login(Session *s, const char *command);  void    do_login(Session *s, const char *command);
   void    do_child(Session *s, const char *command);
   
 void  
 do_child(const char *command, struct passwd * pw, const char *term,  
     const char *display, const char *auth_proto,  
     const char *auth_data, const char *ttyname);  
   
 /* import */  /* import */
 extern ServerOptions options;  extern ServerOptions options;
 extern char *__progname;  extern char *__progname;
 extern int log_stderr;  extern int log_stderr;
 extern int debug_flag;  extern int debug_flag;
 extern unsigned int utmp_len;  extern u_int utmp_len;
   
 extern int startup_pipe;  extern int startup_pipe;
   
Line 109 
Line 111 
 static char *xauthfile;  static char *xauthfile;
   
 /* original command from peer. */  /* original command from peer. */
 char *original_command = NULL;  char *original_command = NULL;
   
 /* data */  /* data */
 #define MAX_SESSIONS 10  #define MAX_SESSIONS 10
Line 177 
Line 179 
         char *command;          char *command;
         int n_bytes;          int n_bytes;
         int plen;          int plen;
         unsigned int proto_len, data_len, dlen;          u_int proto_len, data_len, dlen;
           int screen_flag;
   
         /*          /*
          * Cancel the alarm we set to limit the time taken for           * Cancel the alarm we set to limit the time taken for
Line 189 
Line 192 
                 startup_pipe = -1;                  startup_pipe = -1;
         }          }
   
         /*  
          * Inform the channel mechanism that we are the server side and that  
          * the client may request to connect to any port at all. (The user  
          * could do it anyway, and we wouldn\'t know what is permitted except  
          * by the client telling us, so we can equally well trust the client  
          * not to request anything bogus.)  
          */  
         if (!no_port_forwarding_flag && options.allow_tcp_forwarding)  
                 channel_permit_all_opens();  
   
         s = session_new();          s = session_new();
         s->pw = pw;          s->pw = pw;
   
           if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
                   channel_permit_all_opens();
   
 #ifdef HAVE_LOGIN_CAP  #ifdef HAVE_LOGIN_CAP
         if ((lc = login_getclass(pw->pw_class)) == NULL) {          if ((lc = login_getclass(pw->pw_class)) == NULL) {
                 error("unable to get login class");                  error("unable to get login class");
Line 301 
Line 297 
   
                         s->auth_proto = packet_get_string(&proto_len);                          s->auth_proto = packet_get_string(&proto_len);
                         s->auth_data = packet_get_string(&data_len);                          s->auth_data = packet_get_string(&data_len);
                         packet_integrity_check(plen, 4 + proto_len + 4 + data_len + 4, type);  
   
                         if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER)                          screen_flag = packet_get_protocol_flags() &
                               SSH_PROTOFLAG_SCREEN_NUMBER;
                           debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
   
                           if (packet_remaining() == 4) {
                                   if (!screen_flag)
                                           debug2("Buggy client: "
                                               "X11 screen flag missing");
                                   packet_integrity_check(plen,
                                       4 + proto_len + 4 + data_len + 4, type);
                                 s->screen = packet_get_int();                                  s->screen = packet_get_int();
                         else                          } else {
                                   packet_integrity_check(plen,
                                       4 + proto_len + 4 + data_len, type);
                                 s->screen = 0;                                  s->screen = 0;
                           }
                         s->display = x11_create_display_inet(s->screen, options.x11_display_offset);                          s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
   
                         if (s->display == NULL)                          if (s->display == NULL)
Line 364 
Line 371 
   
                 case SSH_CMSG_EXEC_SHELL:                  case SSH_CMSG_EXEC_SHELL:
                 case SSH_CMSG_EXEC_CMD:                  case SSH_CMSG_EXEC_CMD:
                         /* Set interactive/non-interactive mode. */  
                         packet_set_interactive(have_pty || s->display != NULL,  
                             options.keepalives);  
   
                         if (type == SSH_CMSG_EXEC_CMD) {                          if (type == SSH_CMSG_EXEC_CMD) {
                                 command = packet_get_string(&dlen);                                  command = packet_get_string(&dlen);
                                 debug("Exec command '%.500s'", command);                                  debug("Exec command '%.500s'", command);
Line 491 
Line 494 
 #endif /* USE_PIPES */  #endif /* USE_PIPES */
   
                 /* Do processing for the child (exec command etc). */                  /* Do processing for the child (exec command etc). */
                 do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL);                  do_child(s, command);
                 /* NOTREACHED */                  /* NOTREACHED */
         }          }
         if (pid < 0)          if (pid < 0)
                 packet_disconnect("fork failed: %.100s", strerror(errno));                  packet_disconnect("fork failed: %.100s", strerror(errno));
         s->pid = pid;          s->pid = pid;
           /* Set interactive/non-interactive mode. */
           packet_set_interactive(s->display != NULL);
 #ifdef USE_PIPES  #ifdef USE_PIPES
         /* We are the parent.  Close the child sides of the pipes. */          /* We are the parent.  Close the child sides of the pipes. */
         close(pin[0]);          close(pin[0]);
Line 576 
Line 581 
                         do_login(s, command);                          do_login(s, command);
   
                 /* Do common processing for the child, such as execing the command. */                  /* Do common processing for the child, such as execing the command. */
                 do_child(command, pw, s->term, s->display, s->auth_proto,                  do_child(s, command);
                     s->auth_data, s->tty);  
                 /* NOTREACHED */                  /* NOTREACHED */
         }          }
         if (pid < 0)          if (pid < 0)
Line 603 
Line 607 
         s->ptymaster = ptymaster;          s->ptymaster = ptymaster;
   
         /* Enter interactive session. */          /* Enter interactive session. */
           packet_set_interactive(1);
         if (compat20) {          if (compat20) {
                 session_set_fds(s, ptyfd, fdout, -1);                  session_set_fds(s, ptyfd, fdout, -1);
         } else {          } else {
Line 617 
Line 622 
 {  {
         static const char *remote = "";          static const char *remote = "";
         if (utmp_len > 0)          if (utmp_len > 0)
                 remote = get_canonical_hostname();                  remote = get_canonical_hostname(options.reverse_mapping_check);
         if (utmp_len == 0 || strlen(remote) > utmp_len)          if (utmp_len == 0 || strlen(remote) > utmp_len)
                 remote = get_remote_ipaddr();                  remote = get_remote_ipaddr();
         return remote;          return remote;
Line 700 
Line 705 
  * already exists, its value is overriden.   * already exists, its value is overriden.
  */   */
 void  void
 child_set_env(char ***envp, unsigned int *envsizep, const char *name,  child_set_env(char ***envp, u_int *envsizep, const char *name,
               const char *value)                const char *value)
 {  {
         unsigned int i, namelen;          u_int i, namelen;
         char **env;          char **env;
   
         /*          /*
Line 741 
Line 746 
  * and assignments of the form name=value.  No other forms are allowed.   * and assignments of the form name=value.  No other forms are allowed.
  */   */
 void  void
 read_environment_file(char ***env, unsigned int *envsize,  read_environment_file(char ***env, u_int *envsize,
                       const char *filename)                        const char *filename)
 {  {
         FILE *f;          FILE *f;
Line 781 
Line 786 
  * ids, and executing the command or shell.   * ids, and executing the command or shell.
  */   */
 void  void
 do_child(const char *command, struct passwd * pw, const char *term,  do_child(Session *s, const char *command)
          const char *display, const char *auth_proto,  
          const char *auth_data, const char *ttyname)  
 {  {
         const char *shell, *hostname = NULL, *cp = NULL;          const char *shell, *hostname = NULL, *cp = NULL;
           struct passwd * pw = s->pw;
         char buf[256];          char buf[256];
         char cmd[1024];          char cmd[1024];
         FILE *f = NULL;          FILE *f = NULL;
         unsigned int envsize, i;          u_int envsize, i;
         char **env;          char **env;
         extern char **environ;          extern char **environ;
         struct stat st;          struct stat st;
         char *argv[10];          char *argv[10];
           int do_xauth = s->auth_proto != NULL && s->auth_data != NULL;
   
         /* login(1) is only called if we execute the login shell */          /* login(1) is only called if we execute the login shell */
         if (options.use_login && command != NULL)          if (options.use_login && command != NULL)
Line 826 
Line 831 
                             (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {                              (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
                                 perror("unable to set user context");                                  perror("unable to set user context");
                                 exit(1);                                  exit(1);
   
                         }                          }
 #else  #else
                         if (setlogin(pw->pw_name) < 0)                          if (setlogin(pw->pw_name) < 0)
Line 916 
Line 921 
                  get_remote_ipaddr(), get_remote_port(), get_local_port());                   get_remote_ipaddr(), get_remote_port(), get_local_port());
         child_set_env(&env, &envsize, "SSH_CLIENT", buf);          child_set_env(&env, &envsize, "SSH_CLIENT", buf);
   
         if (ttyname)          if (s->ttyfd != -1)
                 child_set_env(&env, &envsize, "SSH_TTY", ttyname);                  child_set_env(&env, &envsize, "SSH_TTY", s->tty);
         if (term)          if (s->term)
                 child_set_env(&env, &envsize, "TERM", term);                  child_set_env(&env, &envsize, "TERM", s->term);
         if (display)          if (s->display)
                 child_set_env(&env, &envsize, "DISPLAY", display);                  child_set_env(&env, &envsize, "DISPLAY", s->display);
         if (original_command)          if (original_command)
                 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",                  child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
                     original_command);                      original_command);
Line 1012 
Line 1017 
          * in this order).           * in this order).
          */           */
         if (!options.use_login) {          if (!options.use_login) {
                 if (stat(SSH_USER_RC, &st) >= 0) {                  if (stat(_PATH_SSH_USER_RC, &st) >= 0) {
                         if (debug_flag)                          if (debug_flag)
                                 fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);                                  fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
                                       _PATH_SSH_USER_RC);
                         f = popen("/bin/sh " SSH_USER_RC, "w");                          f = popen(_PATH_BSHELL " " _PATH_SSH_USER_RC, "w");
                         if (f) {                          if (f) {
                                 if (auth_proto != NULL && auth_data != NULL)                                  if (do_xauth)
                                         fprintf(f, "%s %s\n", auth_proto, auth_data);                                          fprintf(f, "%s %s\n", s->auth_proto,
                                               s->auth_data);
                                 pclose(f);                                  pclose(f);
                         } else                          } else
                                 fprintf(stderr, "Could not run %s\n", SSH_USER_RC);                                  fprintf(stderr, "Could not run %s\n",
                 } else if (stat(SSH_SYSTEM_RC, &st) >= 0) {                                      _PATH_SSH_USER_RC);
                   } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
                         if (debug_flag)                          if (debug_flag)
                                 fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC);                                  fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
                                       _PATH_SSH_SYSTEM_RC);
                         f = popen("/bin/sh " SSH_SYSTEM_RC, "w");                          f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
                         if (f) {                          if (f) {
                                 if (auth_proto != NULL && auth_data != NULL)                                  if (do_xauth)
                                         fprintf(f, "%s %s\n", auth_proto, auth_data);                                          fprintf(f, "%s %s\n", s->auth_proto,
                                               s->auth_data);
                                 pclose(f);                                  pclose(f);
                         } else                          } else
                                 fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);                                  fprintf(stderr, "Could not run %s\n",
                 } else if (options.xauth_location != NULL) {                                      _PATH_SSH_SYSTEM_RC);
                   } else if (do_xauth && options.xauth_location != NULL) {
                         /* Add authority data to .Xauthority if appropriate. */                          /* Add authority data to .Xauthority if appropriate. */
                         if (auth_proto != NULL && auth_data != NULL) {                          char *screen = strchr(s->display, ':');
                                 char *screen = strchr(display, ':');  
                                 if (debug_flag) {                          if (debug_flag) {
                                   fprintf(stderr,
                                       "Running %.100s add "
                                       "%.100s %.100s %.100s\n",
                                       options.xauth_location, s->display,
                                       s->auth_proto, s->auth_data);
                                   if (screen != NULL)
                                         fprintf(stderr,                                          fprintf(stderr,
                                             "Running %.100s add %.100s %.100s %.100s\n",                                              "Adding %.*s/unix%s %s %s\n",
                                             options.xauth_location, display,                                              (int)(screen - s->display),
                                             auth_proto, auth_data);                                              s->display, screen,
                                         if (screen != NULL)                                              s->auth_proto, s->auth_data);
                                                 fprintf(stderr,  
                                                     "Adding %.*s/unix%s %s %s\n",  
                                                     (int)(screen-display), display,  
                                                     screen, auth_proto, auth_data);  
                                 }  
                                 snprintf(cmd, sizeof cmd, "%s -q -",  
                                     options.xauth_location);  
                                 f = popen(cmd, "w");  
                                 if (f) {  
                                         fprintf(f, "add %s %s %s\n", display,  
                                             auth_proto, auth_data);  
                                         if (screen != NULL)  
                                                 fprintf(f, "add %.*s/unix%s %s %s\n",  
                                                     (int)(screen-display), display,  
                                                     screen, auth_proto, auth_data);  
                                         pclose(f);  
                                 } else {  
                                         fprintf(stderr, "Could not run %s\n",  
                                             cmd);  
                                 }  
                         }                          }
                           snprintf(cmd, sizeof cmd, "%s -q -",
                               options.xauth_location);
                           f = popen(cmd, "w");
                           if (f) {
                                   fprintf(f, "add %s %s %s\n", s->display,
                                       s->auth_proto, s->auth_data);
                                   if (screen != NULL)
                                           fprintf(f, "add %.*s/unix%s %s %s\n",
                                               (int)(screen - s->display),
                                               s->display, screen,
                                               s->auth_proto,
                                               s->auth_data);
                                   pclose(f);
                           } else {
                                   fprintf(stderr, "Could not run %s\n",
                                       cmd);
                           }
                 }                  }
                 /* Get the last component of the shell name. */                  /* Get the last component of the shell name. */
                 cp = strrchr(shell, '/');                  cp = strrchr(shell, '/');
Line 1086 
Line 1098 
                          * Check for mail if we have a tty and it was enabled                           * Check for mail if we have a tty and it was enabled
                          * in server options.                           * in server options.
                          */                           */
                         if (ttyname && options.check_mail) {                          if (s->ttyfd != -1 && options.check_mail) {
                                 char *mailbox;                                  char *mailbox;
                                 struct stat mailstat;                                  struct stat mailstat;
   
                                 mailbox = getenv("MAIL");                                  mailbox = getenv("MAIL");
                                 if (mailbox != NULL) {                                  if (mailbox != NULL) {
                                         if (stat(mailbox, &mailstat) != 0 ||                                          if (stat(mailbox, &mailstat) != 0 ||
Line 1201 
Line 1214 
         }          }
         s->pw = auth_get_user();          s->pw = auth_get_user();
         if (s->pw == NULL)          if (s->pw == NULL)
                 fatal("no user for session %i", s->self);                  fatal("no user for session %d", s->self);
         debug("session_open: session %d: link with channel %d", s->self, chanid);          debug("session_open: session %d: link with channel %d", s->self, chanid);
         s->chanid = chanid;          s->chanid = chanid;
         return 1;          return 1;
Line 1253 
Line 1266 
 int  int
 session_pty_req(Session *s)  session_pty_req(Session *s)
 {  {
         unsigned int len;          u_int len;
         char *term_modes;       /* encoded terminal modes */          char *term_modes;       /* encoded terminal modes */
   
         if (no_pty_flag)          if (no_pty_flag)
Line 1302 
Line 1315 
 int  int
 session_subsystem_req(Session *s)  session_subsystem_req(Session *s)
 {  {
         unsigned int len;          u_int len;
         int success = 0;          int success = 0;
         char *subsys = packet_get_string(&len);          char *subsys = packet_get_string(&len);
         int i;          int i;
Line 1398 
Line 1411 
 int  int
 session_exec_req(Session *s)  session_exec_req(Session *s)
 {  {
         unsigned int len;          u_int len;
         char *command = packet_get_string(&len);          char *command = packet_get_string(&len);
         packet_done();          packet_done();
         if (forced_command) {          if (forced_command) {
Line 1416 
Line 1429 
         return 1;          return 1;
 }  }
   
   int
   session_auth_agent_req(Session *s)
   {
           static int called = 0;
           packet_done();
           if (no_agent_forwarding_flag) {
                   debug("session_auth_agent_req: no_agent_forwarding_flag");
                   return 0;
           }
           if (called) {
                   return 0;
           } else {
                   called = 1;
                   return auth_input_request_forwarding(s->pw);
           }
   }
   
 void  void
 session_input_channel_req(int id, void *arg)  session_input_channel_req(int id, void *arg)
 {  {
         unsigned int len;          u_int len;
         int reply;          int reply;
         int success = 0;          int success = 0;
         char *rtype;          char *rtype;
Line 1452 
Line 1482 
                         success =  session_pty_req(s);                          success =  session_pty_req(s);
                 } else if (strcmp(rtype, "x11-req") == 0) {                  } else if (strcmp(rtype, "x11-req") == 0) {
                         success = session_x11_req(s);                          success = session_x11_req(s);
                   } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
                           success = session_auth_agent_req(s);
                 } else if (strcmp(rtype, "subsystem") == 0) {                  } else if (strcmp(rtype, "subsystem") == 0) {
                         success = session_subsystem_req(s);                          success = session_subsystem_req(s);
                 }                  }
Line 1492 
Line 1524 
         if (s == NULL || s->ttyfd == -1)          if (s == NULL || s->ttyfd == -1)
                 return;                  return;
   
         debug("session_pty_cleanup: session %i release %s", s->self, s->tty);          debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
   
         /* Cancel the cleanup function. */          /* Cancel the cleanup function. */
         fatal_remove_cleanup(pty_cleanup_proc, (void *)s);          fatal_remove_cleanup(pty_cleanup_proc, (void *)s);
Line 1650 
Line 1682 
 }  }
   
 void  void
 do_authenticated2(void)  do_authenticated2(Authctxt *authctxt)
 {  {
         struct passwd *pw;  
   
         /*          /*
          * Cancel the alarm we set to limit the time taken for           * Cancel the alarm we set to limit the time taken for
          * authentication.           * authentication.
Line 1663 
Line 1693 
                 close(startup_pipe);                  close(startup_pipe);
                 startup_pipe = -1;                  startup_pipe = -1;
         }          }
           if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
                   channel_permit_all_opens();
 #ifdef HAVE_LOGIN_CAP  #ifdef HAVE_LOGIN_CAP
         pw = auth_get_user();          if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
         if ((lc = login_getclass(pw->pw_class)) == NULL) {  
                 error("unable to get login class");                  error("unable to get login class");
                 return;                  return;
         }          }

Legend:
Removed from v.1.42  
changed lines
  Added in v.1.42.2.3