[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.12 and 1.12.2.2

version 1.12, 2000/05/03 18:03:07 version 1.12.2.2, 2000/09/01 18:23:22
Line 26 
Line 26 
 #include "bufaux.h"  #include "bufaux.h"
 #include "ssh2.h"  #include "ssh2.h"
 #include "auth.h"  #include "auth.h"
   #include "auth-options.h"
   
   #ifdef HAVE_LOGIN_CAP
   #include <login_cap.h>
   #endif
   
 /* types */  /* types */
   
 #define TTYSZ 64  #define TTYSZ 64
Line 60 
Line 65 
 void    session_proctitle(Session *s);  void    session_proctitle(Session *s);
 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);
   
 void  void
 do_child(const char *command, struct passwd * pw, const char *term,  do_child(const char *command, struct passwd * pw, const char *term,
Line 71 
Line 77 
 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 int startup_pipe;
   
 /* Local Xauthority file. */  /* Local Xauthority file. */
 static char *xauthfile;  static char *xauthfile;
   
Line 79 
Line 88 
 #define MAX_SESSIONS 10  #define MAX_SESSIONS 10
 Session sessions[MAX_SESSIONS];  Session sessions[MAX_SESSIONS];
   
 /* Flags set in auth-rsa from authorized_keys flags.  These are set in auth-rsa.c. */  #ifdef HAVE_LOGIN_CAP
 int no_port_forwarding_flag = 0;  static login_cap_t *lc;
 int no_agent_forwarding_flag = 0;  #endif
 int no_x11_forwarding_flag = 0;  
 int no_pty_flag = 0;  
   
 /* RSA authentication "command=" option. */  
 char *forced_command = NULL;  
   
 /* RSA authentication "environment=" options. */  
 struct envstring *custom_environment = NULL;  
   
 /*  /*
  * Remove local Xauthority file.   * Remove local Xauthority file.
  */   */
Line 156 
Line 157 
          * authentication.           * authentication.
          */           */
         alarm(0);          alarm(0);
           if (startup_pipe != -1) {
                   close(startup_pipe);
                   startup_pipe = -1;
           }
   
         /*          /*
          * Inform the channel mechanism that we are the server side and that           * Inform the channel mechanism that we are the server side and that
Line 170 
Line 175 
         s = session_new();          s = session_new();
         s->pw = pw;          s->pw = pw;
   
   #ifdef HAVE_LOGIN_CAP
           if ((lc = login_getclass(pw->pw_class)) == NULL) {
                   error("unable to get login class");
                   return;
           }
   #endif
   
         /*          /*
          * We stay in this loop until the client requests to execute a shell           * We stay in this loop until the client requests to execute a shell
          * or a command.           * or a command.
Line 248 
Line 260 
                                 packet_send_debug("X11 forwarding disabled in server configuration file.");                                  packet_send_debug("X11 forwarding disabled in server configuration file.");
                                 break;                                  break;
                         }                          }
 #ifdef XAUTH_PATH                          if (!options.xauth_location) {
                                   packet_send_debug("No xauth program; cannot forward with spoofing.");
                                   break;
                           }
                         if (no_x11_forwarding_flag) {                          if (no_x11_forwarding_flag) {
                                 packet_send_debug("X11 forwarding not permitted for this authentication.");                                  packet_send_debug("X11 forwarding not permitted for this authentication.");
                                 break;                                  break;
Line 289 
Line 304 
                         fatal_add_cleanup(xauthfile_cleanup_proc, NULL);                          fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
                         success = 1;                          success = 1;
                         break;                          break;
 #else /* XAUTH_PATH */  
                         packet_send_debug("No xauth program; cannot forward with spoofing.");  
                         break;  
 #endif /* XAUTH_PATH */  
   
                 case SSH_CMSG_AGENT_REQUEST_FORWARDING:                  case SSH_CMSG_AGENT_REQUEST_FORWARDING:
                         if (no_agent_forwarding_flag || compat13) {                          if (no_agent_forwarding_flag || compat13) {
Line 300 
Line 311 
                                 break;                                  break;
                         }                          }
                         debug("Received authentication agent forwarding request.");                          debug("Received authentication agent forwarding request.");
                         auth_input_request_forwarding(pw);                          success = auth_input_request_forwarding(pw);
                         success = 1;  
                         break;                          break;
   
                 case SSH_CMSG_PORT_FORWARD_REQUEST:                  case SSH_CMSG_PORT_FORWARD_REQUEST:
Line 493 
Line 503 
 void  void
 do_exec_pty(Session *s, const char *command, struct passwd * pw)  do_exec_pty(Session *s, const char *command, struct passwd * pw)
 {  {
         FILE *f;  
         char buf[100], *time_string;  
         char line[256];  
         const char *hostname;  
         int fdout, ptyfd, ttyfd, ptymaster;          int fdout, ptyfd, ttyfd, ptymaster;
         int quiet_login;  
         pid_t pid;          pid_t pid;
         socklen_t fromlen;  
         struct sockaddr_storage from;  
         struct stat st;  
         time_t last_login_time;  
   
         if (s == NULL)          if (s == NULL)
                 fatal("do_exec_pty: no session");                  fatal("do_exec_pty: no session");
         ptyfd = s->ptyfd;          ptyfd = s->ptyfd;
         ttyfd = s->ttyfd;          ttyfd = s->ttyfd;
   
         /* Get remote host name. */  
         hostname = get_canonical_hostname();  
   
         /*  
          * Get the time when the user last logged in.  Buf will be set to  
          * contain the hostname the last login was from.  
          */  
         if (!options.use_login) {  
                 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,  
                                                       buf, sizeof(buf));  
         }  
   
         /* Fork the child. */          /* Fork the child. */
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
                 pid = getpid();                  /* Child.  Reinitialize the log because the pid has changed. */
   
                 /* Child.  Reinitialize the log because the pid has  
                    changed. */  
                 log_init(__progname, options.log_level, options.log_facility, log_stderr);                  log_init(__progname, options.log_level, options.log_facility, log_stderr);
   
                 /* Close the master side of the pseudo tty. */                  /* Close the master side of the pseudo tty. */
Line 551 
Line 537 
                 /* Close the extra descriptor for the pseudo tty. */                  /* Close the extra descriptor for the pseudo tty. */
                 close(ttyfd);                  close(ttyfd);
   
 /* XXXX ? move to do_child() ??*/                  /* record login, etc. similar to login(1) */
                 /*                  if (command == NULL && !options.use_login)
                  * Get IP address of client.  This is needed because we want                          do_login(s);
                  * to record where the user logged in from.  If the  
                  * connection is not a socket, let the ip address be 0.0.0.0.  
                  */  
                 memset(&from, 0, sizeof(from));  
                 if (packet_connection_is_on_socket()) {  
                         fromlen = sizeof(from);  
                         if (getpeername(packet_get_connection_in(),  
                              (struct sockaddr *) & from, &fromlen) < 0) {  
                                 debug("getpeername: %.100s", strerror(errno));  
                                 fatal_cleanup();  
                         }  
                 }  
                 /* Record that there was a login on that terminal. */  
                 record_login(pid, s->tty, pw->pw_name, pw->pw_uid, hostname,  
                              (struct sockaddr *)&from);  
   
                 /* Check if .hushlogin exists. */  
                 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);  
                 quiet_login = stat(line, &st) >= 0;  
   
                 /*  
                  * If the user has logged in before, display the time of last  
                  * login. However, don't display anything extra if a command  
                  * has been specified (so that ssh can be used to execute  
                  * commands on a remote machine without users knowing they  
                  * are going to another machine). Login(1) will do this for  
                  * us as well, so check if login(1) is used  
                  */  
                 if (command == NULL && last_login_time != 0 && !quiet_login &&  
                     !options.use_login) {  
                         /* Convert the date to a string. */  
                         time_string = ctime(&last_login_time);  
                         /* Remove the trailing newline. */  
                         if (strchr(time_string, '\n'))  
                                 *strchr(time_string, '\n') = 0;  
                         /* Display the last login time.  Host if displayed  
                            if known. */  
                         if (strcmp(buf, "") == 0)  
                                 printf("Last login: %s\r\n", time_string);  
                         else  
                                 printf("Last login: %s from %s\r\n", time_string, buf);  
                 }  
                 /*  
                  * Print /etc/motd unless a command was specified or printing  
                  * it was disabled in server options or login(1) will be  
                  * used.  Note that some machines appear to print it in  
                  * /etc/profile or similar.  
                  */  
                 if (command == NULL && options.print_motd && !quiet_login &&  
                     !options.use_login) {  
                         /* Print /etc/motd if it exists. */  
                         f = fopen("/etc/motd", "r");  
                         if (f) {  
                                 while (fgets(line, sizeof(line), f))  
                                         fputs(line, stdout);  
                                 fclose(f);  
                         }  
                 }  
                 /* 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, s->auth_data, s->tty);                  do_child(command, pw, s->term, s->display, s->auth_proto,
                       s->auth_data, s->tty);
                 /* NOTREACHED */                  /* NOTREACHED */
         }          }
         if (pid < 0)          if (pid < 0)
Line 648 
Line 578 
         }          }
 }  }
   
   const char *
   get_remote_name_or_ip(void)
   {
           static const char *remote = "";
           if (utmp_len > 0)
                   remote = get_canonical_hostname();
           if (utmp_len == 0 || strlen(remote) > utmp_len)
                   remote = get_remote_ipaddr();
           return remote;
   }
   
   /* administrative, login(1)-like work */
   void
   do_login(Session *s)
   {
           FILE *f;
           char *time_string;
           char buf[256];
           socklen_t fromlen;
           struct sockaddr_storage from;
           struct stat st;
           time_t last_login_time;
           struct passwd * pw = s->pw;
           pid_t pid = getpid();
   
           /*
            * Get IP address of client. If the connection is not a socket, let
            * the address be 0.0.0.0.
            */
           memset(&from, 0, sizeof(from));
           if (packet_connection_is_on_socket()) {
                   fromlen = sizeof(from);
                   if (getpeername(packet_get_connection_in(),
                        (struct sockaddr *) & from, &fromlen) < 0) {
                           debug("getpeername: %.100s", strerror(errno));
                           fatal_cleanup();
                   }
           }
   
           /* Record that there was a login on that tty from the remote host. */
           record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
               get_remote_name_or_ip(), (struct sockaddr *)&from);
   
           /* Done if .hushlogin exists. */
           snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
   #ifdef HAVE_LOGIN_CAP
           if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
   #else
           if (stat(buf, &st) >= 0)
   #endif
                   return;
           /*
            * Get the time when the user last logged in.  'buf' will be set
            * to contain the hostname the last login was from.
            */
           last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
               buf, sizeof(buf));
           if (last_login_time != 0) {
                   time_string = ctime(&last_login_time);
                   if (strchr(time_string, '\n'))
                           *strchr(time_string, '\n') = 0;
                   if (strcmp(buf, "") == 0)
                           printf("Last login: %s\r\n", time_string);
                   else
                           printf("Last login: %s from %s\r\n", time_string, buf);
           }
           if (options.print_motd) {
   #ifdef HAVE_LOGIN_CAP
                   f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
                       "/etc/motd"), "r");
   #else
                   f = fopen("/etc/motd", "r");
   #endif
                   if (f) {
                           while (fgets(buf, sizeof(buf), f))
                                   fputs(buf, stdout);
                           fclose(f);
                   }
           }
   }
   
 /*  /*
  * Sets the value of the given variable in the environment.  If the variable   * Sets the value of the given variable in the environment.  If the variable
  * already exists, its value is overriden.   * already exists, its value is overriden.
Line 717 
Line 728 
                         fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);                          fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
                         continue;                          continue;
                 }                  }
                 /* Replace the equals sign by nul, and advance value to the value string. */                  /*
                    * Replace the equals sign by nul, and advance value to
                    * the value string.
                    */
                 *value = '\0';                  *value = '\0';
                 value++;                  value++;
                 child_set_env(env, envsize, cp, value);                  child_set_env(env, envsize, cp, value);
Line 735 
Line 749 
          const char *display, const char *auth_proto,           const char *display, const char *auth_proto,
          const char *auth_data, const char *ttyname)           const char *auth_data, const char *ttyname)
 {  {
         const char *shell, *cp = NULL;          const char *shell, *hostname, *cp = NULL;
         char buf[256];          char buf[256];
         FILE *f;          char cmd[1024];
           FILE *f = NULL;
         unsigned int envsize, i;          unsigned 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];
   
         f = fopen("/etc/nologin", "r");          /* login(1) is only called if we execute the login shell */
         if (f) {          if (options.use_login && command != NULL)
                 /* /etc/nologin exists.  Print its contents and exit. */                  options.use_login = 0;
                 while (fgets(buf, sizeof(buf), f))  
                         fputs(buf, stderr);          if (!options.use_login) {
                 fclose(f);  #ifdef HAVE_LOGIN_CAP
                 if (pw->pw_uid != 0)                  if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
                           f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
                               _PATH_NOLOGIN), "r");
   #else
                   if (pw->pw_uid)
                           f = fopen(_PATH_NOLOGIN, "r");
   #endif
                   if (f) {
                           /* /etc/nologin exists.  Print its contents and exit. */
                           while (fgets(buf, sizeof(buf), f))
                                   fputs(buf, stderr);
                           fclose(f);
                         exit(254);                          exit(254);
                   }
         }          }
         /* Set login name in the kernel. */          /* Set login name, uid, gid, and groups. */
         if (setlogin(pw->pw_name) < 0)  
                 error("setlogin failed: %s", strerror(errno));  
   
         /* Set uid, gid, and groups. */  
         /* Login(1) does this as well, and it needs uid 0 for the "-h"          /* Login(1) does this as well, and it needs uid 0 for the "-h"
            switch, so we let login(1) to this for us. */             switch, so we let login(1) to this for us. */
         if (!options.use_login) {          if (!options.use_login) {
                 if (getuid() == 0 || geteuid() == 0) {                  if (getuid() == 0 || geteuid() == 0) {
   #ifdef HAVE_LOGIN_CAP
                           if (setusercontext(lc, pw, pw->pw_uid,
                               (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
                                   perror("unable to set user context");
                                   exit(1);
   
                           }
   #else
                           if (setlogin(pw->pw_name) < 0)
                                   error("setlogin failed: %s", strerror(errno));
                         if (setgid(pw->pw_gid) < 0) {                          if (setgid(pw->pw_gid) < 0) {
                                 perror("setgid");                                  perror("setgid");
                                 exit(1);                                  exit(1);
Line 775 
Line 808 
   
                         /* Permanently switch to the desired uid. */                          /* Permanently switch to the desired uid. */
                         permanently_set_uid(pw->pw_uid);                          permanently_set_uid(pw->pw_uid);
   #endif
                 }                  }
                 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)                  if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                         fatal("Failed to set uids to %d.", (int) pw->pw_uid);                          fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
         }          }
         /*          /*
          * Get the shell from the password data.  An empty shell field is           * Get the shell from the password data.  An empty shell field is
          * legal, and means /bin/sh.           * legal, and means /bin/sh.
          */           */
         shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;          shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
   #ifdef HAVE_LOGIN_CAP
           shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
   #endif
   
 #ifdef AFS  #ifdef AFS
         /* Try to get AFS tokens for the local cell. */          /* Try to get AFS tokens for the local cell. */
Line 807 
Line 844 
                 child_set_env(&env, &envsize, "USER", pw->pw_name);                  child_set_env(&env, &envsize, "USER", pw->pw_name);
                 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);                  child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
                 child_set_env(&env, &envsize, "HOME", pw->pw_dir);                  child_set_env(&env, &envsize, "HOME", pw->pw_dir);
   #ifdef HAVE_LOGIN_CAP
                   (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
                   child_set_env(&env, &envsize, "PATH", getenv("PATH"));
   #else
                 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);                  child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
   #endif
   
                 snprintf(buf, sizeof buf, "%.200s/%.50s",                  snprintf(buf, sizeof buf, "%.200s/%.50s",
                          _PATH_MAILDIR, pw->pw_name);                           _PATH_MAILDIR, pw->pw_name);
Line 862 
Line 904 
   
         /* read $HOME/.ssh/environment. */          /* read $HOME/.ssh/environment. */
         if (!options.use_login) {          if (!options.use_login) {
                 snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);                  snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
                       pw->pw_dir);
                 read_environment_file(&env, &envsize, buf);                  read_environment_file(&env, &envsize, buf);
         }          }
         if (debug_flag) {          if (debug_flag) {
Line 871 
Line 914 
                 for (i = 0; env[i]; i++)                  for (i = 0; env[i]; i++)
                         fprintf(stderr, "  %.200s\n", env[i]);                          fprintf(stderr, "  %.200s\n", env[i]);
         }          }
           /* we have to stash the hostname before we close our socket. */
           if (options.use_login)
                   hostname = get_remote_name_or_ip();
         /*          /*
          * Close the connection descriptors; note that this is the child, and           * Close the connection descriptors; note that this is the child, and
          * the server will still have the socket open, and it is important           * the server will still have the socket open, and it is important
Line 907 
Line 953 
                 close(i);                  close(i);
   
         /* Change current directory to the user\'s home directory. */          /* Change current directory to the user\'s home directory. */
         if (chdir(pw->pw_dir) < 0)          if (chdir(pw->pw_dir) < 0) {
                 fprintf(stderr, "Could not chdir to home directory %s: %s\n",                  fprintf(stderr, "Could not chdir to home directory %s: %s\n",
                         pw->pw_dir, strerror(errno));                          pw->pw_dir, strerror(errno));
   #ifdef HAVE_LOGIN_CAP
                   if (login_getcapbool(lc, "requirehome", 0))
                           exit(1);
   #endif
           }
   
         /*          /*
          * Must take new environment into use so that .ssh/rc, /etc/sshrc and           * Must take new environment into use so that .ssh/rc, /etc/sshrc and
Line 944 
Line 995 
                                 pclose(f);                                  pclose(f);
                         } else                          } else
                                 fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);                                  fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);
                 }                  } else if (options.xauth_location != NULL) {
 #ifdef XAUTH_PATH  
                 else {  
                         /* Add authority data to .Xauthority if appropriate. */                          /* Add authority data to .Xauthority if appropriate. */
                         if (auth_proto != NULL && auth_data != NULL) {                          if (auth_proto != NULL && auth_data != NULL) {
                                 if (debug_flag)                                  char *screen = strchr(display, ':');
                                         fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",                                  if (debug_flag) {
                                                 XAUTH_PATH, display, auth_proto, auth_data);                                          fprintf(stderr,
                                               "Running %.100s add %.100s %.100s %.100s\n",
                                 f = popen(XAUTH_PATH " -q -", "w");                                              options.xauth_location, display,
                                               auth_proto, auth_data);
                                           if (screen != NULL)
                                                   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) {                                  if (f) {
                                         fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);                                          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);                                          pclose(f);
                                 } else                                  } else {
                                         fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);                                          fprintf(stderr, "Could not run %s\n",
                                               cmd);
                                   }
                         }                          }
                 }                  }
 #endif /* XAUTH_PATH */  
   
                 /* Get the last component of the shell name. */                  /* Get the last component of the shell name. */
                 cp = strrchr(shell, '/');                  cp = strrchr(shell, '/');
                 if (cp)                  if (cp)
Line 988 
Line 1052 
                                 struct stat mailstat;                                  struct stat mailstat;
                                 mailbox = getenv("MAIL");                                  mailbox = getenv("MAIL");
                                 if (mailbox != NULL) {                                  if (mailbox != NULL) {
                                         if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)                                          if (stat(mailbox, &mailstat) != 0 ||
                                               mailstat.st_size == 0)
                                                 printf("No mail.\n");                                                  printf("No mail.\n");
                                         else if (mailstat.st_mtime < mailstat.st_atime)                                          else if (mailstat.st_mtime < mailstat.st_atime)
                                                 printf("You have mail.\n");                                                  printf("You have mail.\n");
Line 1013 
Line 1078 
                 } else {                  } else {
                         /* Launch login(1). */                          /* Launch login(1). */
   
                         execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(),                          execl("/usr/bin/login", "login", "-h", hostname,
                               "-p", "-f", "--", pw->pw_name, NULL);                               "-p", "-f", "--", pw->pw_name, NULL);
   
                         /* Login couldn't be executed, die. */                          /* Login couldn't be executed, die. */
   
Line 1152 
Line 1217 
         unsigned int len;          unsigned int len;
         char *term_modes;       /* encoded terminal modes */          char *term_modes;       /* encoded terminal modes */
   
           if (no_pty_flag)
                   return 0;
         if (s->ttyfd != -1)          if (s->ttyfd != -1)
                 return 0;                  return 0;
         s->term = packet_get_string(&len);          s->term = packet_get_string(&len);
Line 1199 
Line 1266 
         unsigned int len;          unsigned int len;
         int success = 0;          int success = 0;
         char *subsys = packet_get_string(&len);          char *subsys = packet_get_string(&len);
           int i;
   
         packet_done();          packet_done();
         log("subsystem request for %s", subsys);          log("subsystem request for %s", subsys);
   
           for (i = 0; i < options.num_subsystems; i++) {
                   if(strcmp(subsys, options.subsystem_name[i]) == 0) {
                           debug("subsystem: exec() %s", options.subsystem_command[i]);
                           do_exec_no_pty(s, options.subsystem_command[i], s->pw);
                           success = 1;
                   }
           }
   
           if (!success)
                   log("subsystem request for %s failed, subsystem not found", subsys);
   
         xfree(subsys);          xfree(subsys);
         return success;          return success;
 }  }
Line 1210 
Line 1289 
 int  int
 session_x11_req(Session *s)  session_x11_req(Session *s)
 {  {
           if (no_x11_forwarding_flag) {
                   debug("X11 forwarding disabled in user configuration file.");
                   return 0;
           }
         if (!options.x11_forwarding) {          if (!options.x11_forwarding) {
                 debug("X11 forwarding disabled in server configuration file.");                  debug("X11 forwarding disabled in server configuration file.");
                 return 0;                  return 0;
Line 1256 
Line 1339 
         return 1;          return 1;
 }  }
   
   int
   session_shell_req(Session *s)
   {
           /* if forced_command == NULL, the shell is execed */
           char *shell = forced_command;
           packet_done();
           s->extended = 1;
           if (s->ttyfd == -1)
                   do_exec_no_pty(s, shell, s->pw);
           else
                   do_exec_pty(s, shell, s->pw);
           return 1;
   }
   
   int
   session_exec_req(Session *s)
   {
           unsigned int len;
           char *command = packet_get_string(&len);
           packet_done();
           if (forced_command) {
                   xfree(command);
                   command = forced_command;
                   debug("Forced command '%.500s'", forced_command);
           }
           s->extended = 1;
           if (s->ttyfd == -1)
                   do_exec_no_pty(s, command, s->pw);
           else
                   do_exec_pty(s, command, s->pw);
           if (forced_command == NULL)
                   xfree(command);
           return 1;
   }
   
 void  void
 session_input_channel_req(int id, void *arg)  session_input_channel_req(int id, void *arg)
 {  {
Line 1285 
Line 1403 
          */           */
         if (c->type == SSH_CHANNEL_LARVAL) {          if (c->type == SSH_CHANNEL_LARVAL) {
                 if (strcmp(rtype, "shell") == 0) {                  if (strcmp(rtype, "shell") == 0) {
                         packet_done();                          success = session_shell_req(s);
                         s->extended = 1;  
                         if (s->ttyfd == -1)  
                                 do_exec_no_pty(s, NULL, s->pw);  
                         else  
                                 do_exec_pty(s, NULL, s->pw);  
                         success = 1;  
                 } else if (strcmp(rtype, "exec") == 0) {                  } else if (strcmp(rtype, "exec") == 0) {
                         char *command = packet_get_string(&len);                          success = session_exec_req(s);
                         packet_done();  
                         s->extended = 1;  
                         if (s->ttyfd == -1)  
                                 do_exec_no_pty(s, command, s->pw);  
                         else  
                                 do_exec_pty(s, command, s->pw);  
                         xfree(command);  
                         success = 1;  
                 } else if (strcmp(rtype, "pty-req") == 0) {                  } else if (strcmp(rtype, "pty-req") == 0) {
                         success =  session_pty_req(s);                          success =  session_pty_req(s);
                 } else if (strcmp(rtype, "x11-req") == 0) {                  } else if (strcmp(rtype, "x11-req") == 0) {
Line 1505 
Line 1609 
 void  void
 do_authenticated2(void)  do_authenticated2(void)
 {  {
           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.
          */           */
         alarm(0);          alarm(0);
           if (startup_pipe != -1) {
                   close(startup_pipe);
                   startup_pipe = -1;
           }
   #ifdef HAVE_LOGIN_CAP
           pw = auth_get_user();
           if ((lc = login_getclass(pw->pw_class)) == NULL) {
                   error("unable to get login class");
                   return;
           }
   #endif
         server_loop2();          server_loop2();
         if (xauthfile)          if (xauthfile)
                 xauthfile_cleanup_proc(NULL);                  xauthfile_cleanup_proc(NULL);

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.12.2.2