[BACK]Return to session.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / crypto / external / bsd / openssh / dist

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/crypto/external/bsd/openssh/dist/session.c between version 1.19 and 1.19.2.3

version 1.19, 2016/04/14 16:42:09 version 1.19.2.3, 2017/04/26 02:52:15
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
 /* $OpenBSD: session.c,v 1.280 2016/02/16 03:37:48 djm Exp $ */  /* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */
   
 /*  /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Line 44  __RCSID("$NetBSD$");
Line 44  __RCSID("$NetBSD$");
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/queue.h>  #include <sys/queue.h>
   
   #include <ctype.h>
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <grp.h>  #include <grp.h>
Line 60  __RCSID("$NetBSD$");
Line 61  __RCSID("$NetBSD$");
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
 #include "ssh1.h"  
 #include "ssh2.h"  #include "ssh2.h"
 #include "sshpty.h"  #include "sshpty.h"
 #include "packet.h"  #include "packet.h"
Line 115  __dead void do_child(Session *, const ch
Line 115  __dead void do_child(Session *, const ch
 void    do_motd(void);  void    do_motd(void);
 int     check_quietlogin(Session *, const char *);  int     check_quietlogin(Session *, const char *);
   
 static void do_authenticated1(Authctxt *);  
 static void do_authenticated2(Authctxt *);  static void do_authenticated2(Authctxt *);
   
 static int session_pty_req(Session *);  static int session_pty_req(Session *);
Line 247  do_authenticated(Authctxt *authctxt)
Line 246  do_authenticated(Authctxt *authctxt)
   
         /* setup the channel layer */          /* setup the channel layer */
         /* XXX - streamlocal? */          /* XXX - streamlocal? */
         if (no_port_forwarding_flag ||          if (no_port_forwarding_flag || options.disable_forwarding ||
             (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)              (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
                 channel_disable_adm_local_opens();                  channel_disable_adm_local_opens();
         else          else
Line 255  do_authenticated(Authctxt *authctxt)
Line 254  do_authenticated(Authctxt *authctxt)
   
         auth_debug_send();          auth_debug_send();
   
         if (compat20)          do_authenticated2(authctxt);
                 do_authenticated2(authctxt);  
         else  
                 do_authenticated1(authctxt);  
   
         do_cleanup(authctxt);          do_cleanup(authctxt);
 }  }
   
 /*  /* Check untrusted xauth strings for metacharacters */
  * Prepares for an interactive session.  This is called after the user has  static int
  * been successfully authenticated.  During this message exchange, pseudo  xauth_valid_string(const char *s)
  * terminals are allocated, X11, TCP/IP, and authentication agent forwardings  
  * are requested, etc.  
  */  
 static void  
 do_authenticated1(Authctxt *authctxt)  
 {  {
         Session *s;          size_t i;
         char *command;  
         int success, type, screen_flag;  
         int enable_compression_after_reply = 0;  
         u_int proto_len, data_len, dlen, compression_level = 0;  
   
         s = session_new();  
         if (s == NULL) {  
                 error("no more sessions");  
                 return;  
         }  
         s->authctxt = authctxt;  
         s->pw = authctxt->pw;  
   
         /*  
          * We stay in this loop until the client requests to execute a shell  
          * or a command.  
          */  
         for (;;) {  
                 success = 0;  
   
                 /* Get a packet from the client. */  
                 type = packet_read();  
   
                 /* Process the packet. */  
                 switch (type) {  
                 case SSH_CMSG_REQUEST_COMPRESSION:  
                         compression_level = packet_get_int();  
                         packet_check_eom();  
                         if (compression_level < 1 || compression_level > 9) {  
                                 packet_send_debug("Received invalid compression level %d.",  
                                     compression_level);  
                                 break;  
                         }  
                         if (options.compression == COMP_NONE) {  
                                 debug2("compression disabled");  
                                 break;  
                         }  
                         /* Enable compression after we have responded with SUCCESS. */  
                         enable_compression_after_reply = 1;  
                         success = 1;  
                         break;  
   
                 case SSH_CMSG_REQUEST_PTY:  
                         success = session_pty_req(s);  
                         break;  
   
                 case SSH_CMSG_X11_REQUEST_FORWARDING:  
                         s->auth_proto = packet_get_string(&proto_len);  
                         s->auth_data = packet_get_string(&data_len);  
   
                         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");  
                                 s->screen = packet_get_int();  
                         } else {  
                                 s->screen = 0;  
                         }  
                         packet_check_eom();  
                         success = session_setup_x11fwd(s);  
                         if (!success) {  
                                 free(s->auth_proto);  
                                 free(s->auth_data);  
                                 s->auth_proto = NULL;  
                                 s->auth_data = NULL;  
                         }  
                         break;  
   
                 case SSH_CMSG_AGENT_REQUEST_FORWARDING:  
                         if (!options.allow_agent_forwarding ||  
                             no_agent_forwarding_flag || compat13) {  
                                 debug("Authentication agent forwarding not permitted for this authentication.");  
                                 break;  
                         }  
                         debug("Received authentication agent forwarding request.");  
                         success = auth_input_request_forwarding(s->pw);  
                         break;  
   
                 case SSH_CMSG_PORT_FORWARD_REQUEST:          for (i = 0; s[i] != '\0'; i++) {
                         if (no_port_forwarding_flag) {                  if (!isalnum((u_char)s[i]) &&
                                 debug("Port forwarding not permitted for this authentication.");                      s[i] != '.' && s[i] != ':' && s[i] != '/' &&
                                 break;                      s[i] != '-' && s[i] != '_')
                         }                  return 0;
                         if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) {  
                                 debug("Port forwarding not permitted.");  
                                 break;  
                         }  
                         debug("Received TCP/IP port forwarding request.");  
                         if (channel_input_port_forward_request(s->pw->pw_uid == 0,  
                             &options.fwd_opts) < 0) {  
                                 debug("Port forwarding failed.");  
                                 break;  
                         }  
                         success = 1;  
                         break;  
   
                 case SSH_CMSG_MAX_PACKET_SIZE:  
                         if (packet_set_maxsize(packet_get_int()) > 0)  
                                 success = 1;  
                         break;  
   
 #if defined(AFS) || defined(KRB5)  
                 case SSH_CMSG_HAVE_KERBEROS_TGT:  
                         if (!options.kerberos_tgt_passing) {  
                                 verbose("Kerberos TGT passing disabled.");  
                         } else {  
                                 char *kdata = packet_get_string(&dlen);  
                                 packet_check_eom();  
   
                                 /* XXX - 0x41, see creds_to_radix version */  
                                 if (kdata[0] != 0x41) {  
 #ifdef KRB5  
                                         krb5_data tgt;  
                                         tgt.data = kdata;  
                                         tgt.length = dlen;  
   
                                         if (auth_krb5_tgt(s->authctxt, &tgt))  
                                                 success = 1;  
                                         else  
                                                 verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);  
 #endif /* KRB5 */  
                                 } else {  
 #ifdef AFS  
                                         if (auth_krb4_tgt(s->authctxt, kdata))  
                                                 success = 1;  
                                         else  
                                                 verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);  
 #endif /* AFS */  
                                 }  
                                 free(kdata);  
                         }  
                         break;  
 #endif /* AFS || KRB5 */  
   
 #ifdef AFS  
                 case SSH_CMSG_HAVE_AFS_TOKEN:  
                         if (!options.afs_token_passing || !k_hasafs()) {  
                                 verbose("AFS token passing disabled.");  
                         } else {  
                                 /* Accept AFS token. */  
                                 char *token = packet_get_string(&dlen);  
                                 packet_check_eom();  
   
                                 if (auth_afs_token(s->authctxt, token))  
                                         success = 1;  
                                 else  
                                         verbose("AFS token refused for %.100s",  
                                             s->authctxt->user);  
                                 free(token);  
                         }  
                         break;  
 #endif /* AFS */  
   
                 case SSH_CMSG_EXEC_SHELL:  
                 case SSH_CMSG_EXEC_CMD:  
                         if (type == SSH_CMSG_EXEC_CMD) {  
                                 command = packet_get_string(&dlen);  
                                 debug("Exec command '%.500s'", command);  
                                 if (do_exec(s, command) != 0)  
                                         packet_disconnect(  
                                             "command execution failed");  
                                 free(command);  
                         } else {  
                                 if (do_exec(s, NULL) != 0)  
                                         packet_disconnect(  
                                             "shell execution failed");  
                         }  
                         packet_check_eom();  
                         session_close(s);  
                         return;  
   
                 default:  
                         /*  
                          * Any unknown messages in this phase are ignored,  
                          * and a failure message is returned.  
                          */  
                         logit("Unknown packet type received after authentication: %d", type);  
                 }  
                 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);  
                 packet_send();  
                 packet_write_wait();  
   
                 /* Enable compression now that we have replied if appropriate. */  
                 if (enable_compression_after_reply) {  
                         enable_compression_after_reply = 0;  
                         packet_start_compression(compression_level);  
                 }  
         }          }
           return 1;
 }  }
   
 #define USE_PIPES 1  #define USE_PIPES 1
Line 621  do_exec_no_pty(Session *s, const char *c
Line 427  do_exec_no_pty(Session *s, const char *c
         close(pout[1]);          close(pout[1]);
         close(perr[1]);          close(perr[1]);
   
         if (compat20) {          session_set_fds(s, pin[1], pout[0], perr[0],
                 session_set_fds(s, pin[1], pout[0], perr[0],              s->is_subsystem, 0);
                     s->is_subsystem, 0);  
         } else {  
                 /* Enter the interactive session. */  
                 server_loop(pid, pin[1], pout[0], perr[0]);  
                 /* server_loop has closed pin[1], pout[0], and perr[0]. */  
         }  
 #else  #else
         /* We are the parent.  Close the child sides of the socket pairs. */          /* We are the parent.  Close the child sides of the socket pairs. */
         close(inout[0]);          close(inout[0]);
Line 638  do_exec_no_pty(Session *s, const char *c
Line 438  do_exec_no_pty(Session *s, const char *c
          * Enter the interactive session.  Note: server_loop must be able to           * Enter the interactive session.  Note: server_loop must be able to
          * handle the case that fdin and fdout are the same.           * handle the case that fdin and fdout are the same.
          */           */
         if (compat20) {          session_set_fds(s, inout[1], inout[1], err[1],
                 session_set_fds(s, inout[1], inout[1], err[1],              s->is_subsystem, 0);
                     s->is_subsystem, 0);  
         } else {  
                 server_loop(pid, inout[1], inout[1], err[1]);  
                 /* server_loop has closed inout[1] and err[1]. */  
         }  
 #endif  #endif
         return 0;          return 0;
 }  }
Line 732  do_exec_pty(Session *s, const char *comm
Line 527  do_exec_pty(Session *s, const char *comm
                 close(ttyfd);                  close(ttyfd);
   
                 /* record login, etc. similar to login(1) */                  /* record login, etc. similar to login(1) */
                 if (!(options.use_login && command == NULL))                  do_login(s, command);
                         do_login(s, command);  
   
                 /*                  /*
                  * Do common processing for the child, such as execing                   * Do common processing for the child, such as execing
Line 753  do_exec_pty(Session *s, const char *comm
Line 547  do_exec_pty(Session *s, const char *comm
         s->ptymaster = ptymaster;          s->ptymaster = ptymaster;
         packet_set_interactive(1,          packet_set_interactive(1,
             options.ip_qos_interactive, options.ip_qos_bulk);              options.ip_qos_interactive, options.ip_qos_bulk);
         if (compat20) {          session_set_fds(s, ptyfd, fdout, -1, 1, 1);
                 session_set_fds(s, ptyfd, fdout, -1, 1, 1);  
         } else {  
                 server_loop(pid, ptyfd, fdout, -1);  
                 /* server_loop _has_ closed ptyfd and fdout. */  
         }  
         return 0;          return 0;
 }  }
   
Line 769  do_exec_pty(Session *s, const char *comm
Line 558  do_exec_pty(Session *s, const char *comm
 int  int
 do_exec(Session *s, const char *command)  do_exec(Session *s, const char *command)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         int ret;          int ret;
         const char *forced = NULL, *tty = NULL;          const char *forced = NULL, *tty = NULL;
         char session_type[1024];          char session_type[1024];
Line 811  do_exec(Session *s, const char *command)
Line 601  do_exec(Session *s, const char *command)
             tty == NULL ? "" : " on ",              tty == NULL ? "" : " on ",
             tty == NULL ? "" : tty,              tty == NULL ? "" : tty,
             s->pw->pw_name,              s->pw->pw_name,
             get_remote_ipaddr(),              ssh_remote_ipaddr(ssh),
             get_remote_port(),              ssh_remote_port(ssh),
             s->self);              s->self);
   
 #ifdef GSSAPI  #ifdef GSSAPI
Line 844  do_exec(Session *s, const char *command)
Line 634  do_exec(Session *s, const char *command)
 void  void
 do_login(Session *s, const char *command)  do_login(Session *s, const char *command)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         socklen_t fromlen;          socklen_t fromlen;
         struct sockaddr_storage from;          struct sockaddr_storage from;
         struct passwd * pw = s->pw;          struct passwd * pw = s->pw;
Line 866  do_login(Session *s, const char *command
Line 657  do_login(Session *s, const char *command
         /* Record that there was a login on that tty from the remote host. */          /* Record that there was a login on that tty from the remote host. */
         if (!use_privsep)          if (!use_privsep)
                 record_login(pid, s->tty, pw->pw_name, pw->pw_uid,                  record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
                     get_remote_name_or_ip(utmp_len,                      session_get_remote_name_or_ip(ssh, utmp_len,
                     options.use_dns),                      options.use_dns),
                     (struct sockaddr *)&from, fromlen);                      (struct sockaddr *)&from, fromlen);
   
Line 989  child_set_env(char ***envp, u_int *envsi
Line 780  child_set_env(char ***envp, u_int *envsi
         snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);          snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
 }  }
   
 #ifdef HAVE_LOGIN_CAP  
 /*  
  * Sets any environment variables specified in login.conf.  
  * Taken from:  
  *      NetBSD: login_cap.c,v 1.11 2001/07/22 13:34:01 wiz Exp  
  * Modified to use child_set_env instead of setenv.  
  */  
 static void  
 lc_setuserenv(char ***env, u_int *envsize, login_cap_t *lcp)  
 {  
         const char *stop = ", \t";  
         int i, count;  
         char *ptr;  
         char **res;  
         char *str = login_getcapstr(lcp, "setenv", NULL, NULL);  
   
         if (str == NULL || *str == '\0')  
                 return;  
   
         /* count the sub-strings */  
         for (i = 1, ptr = str; *ptr; i++) {  
                 ptr += strcspn(ptr, stop);  
                 if (*ptr)  
                         ptr++;  
         }  
   
         /* allocate ptr array and string */  
         count = i;  
         res = malloc(count * sizeof(char *) + strlen(str) + 1);  
   
         if (!res)  
                 return;  
   
         ptr = (char *)res + count * sizeof(char *);  
         strcpy(ptr, str);  
   
         /* split string */  
         for (i = 0; *ptr && i < count; i++) {  
                 res[i] = ptr;  
                 ptr += strcspn(ptr, stop);  
                 if (*ptr)  
                         *ptr++ = '\0';  
         }  
   
         res[i] = NULL;  
   
         for (i = 0; i < count && res[i]; i++) {  
                 if (*res[i] != '\0') {  
                         if ((ptr = strchr(res[i], '=')) != NULL)  
                                 *ptr++ = '\0';  
                         else  
                                 ptr = __UNCONST("");  
                         child_set_env(env, envsize, res[i], ptr);  
                 }  
         }  
   
         free(res);  
         return;  
 }  
 #endif  
   
 /*  /*
  * Reads environment variables from the given file and adds/overrides them   * Reads environment variables from the given file and adds/overrides them
  * into the environment.  If the file does not exist, this does nothing.   * into the environment.  If the file does not exist, this does nothing.
Line 1125  void copy_environment(char **source, cha
Line 855  void copy_environment(char **source, cha
 static char **  static char **
 do_setup_env(Session *s, const char *shell)  do_setup_env(Session *s, const char *shell)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         char buf[256];          char buf[256];
         u_int i, envsize;          u_int i, envsize;
         char **env, *laddr;          char **env, *laddr;
Line 1142  do_setup_env(Session *s, const char *she
Line 873  do_setup_env(Session *s, const char *she
         ssh_gssapi_do_child(&env, &envsize);          ssh_gssapi_do_child(&env, &envsize);
 #endif  #endif
   
         if (!options.use_login) {          /* Set basic environment. */
 #ifdef HAVE_LOGIN_CAP          for (i = 0; i < s->num_env; i++)
                 lc_setuserenv(&env, &envsize, lc);                  child_set_env(&env, &envsize, s->env[i].name, s->env[i].val);
 #endif  
                 /* Set basic environment. */          child_set_env(&env, &envsize, "USER", pw->pw_name);
                 for (i = 0; i < s->num_env; i++)          child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
                         child_set_env(&env, &envsize, s->env[i].name,          child_set_env(&env, &envsize, "HOME", pw->pw_dir);
                             s->env[i].val);          if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
   
                 child_set_env(&env, &envsize, "USER", pw->pw_name);  
                 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);  
                 child_set_env(&env, &envsize, "HOME", pw->pw_dir);  
 #ifdef HAVE_LOGIN_CAP  
                 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)  
                         child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);  
                 else  
                         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          else
                   child_set_env(&env, &envsize, "PATH", getenv("PATH"));
   
                 snprintf(buf, sizeof buf, "%.200s/%.50s",          snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name);
                          _PATH_MAILDIR, pw->pw_name);          child_set_env(&env, &envsize, "MAIL", buf);
                 child_set_env(&env, &envsize, "MAIL", buf);  
           /* Normal systems set SHELL by default. */
           child_set_env(&env, &envsize, "SHELL", shell);
   
                 /* Normal systems set SHELL by default. */  
                 child_set_env(&env, &envsize, "SHELL", shell);  
         }  
         if (getenv("TZ"))          if (getenv("TZ"))
                 child_set_env(&env, &envsize, "TZ", getenv("TZ"));                  child_set_env(&env, &envsize, "TZ", getenv("TZ"));
   
         /* Set custom environment options from RSA authentication. */          /* Set custom environment options from RSA authentication. */
         if (!options.use_login) {          while (custom_environment) {
                 while (custom_environment) {                  struct envstring *ce = custom_environment;
                         struct envstring *ce = custom_environment;                  char *str = ce->s;
                         char *str = ce->s;  
                   for (i = 0; str[i] != '=' && str[i]; i++)
                         for (i = 0; str[i] != '=' && str[i]; i++)                          ;
                                 ;                  if (str[i] == '=') {
                         if (str[i] == '=') {                          str[i] = 0;
                                 str[i] = 0;                          child_set_env(&env, &envsize, str, str + i + 1);
                                 child_set_env(&env, &envsize, str, str + i + 1);                  }
                         }                  custom_environment = ce->next;
                         custom_environment = ce->next;                  free(ce->s);
                         free(ce->s);                  free(ce);
                         free(ce);  
                 }  
         }          }
   
         /* SSH_CLIENT deprecated */          /* SSH_CLIENT deprecated */
         snprintf(buf, sizeof buf, "%.50s %d %d",          snprintf(buf, sizeof buf, "%.50s %d %d",
             get_remote_ipaddr(), get_remote_port(), get_local_port());              ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
               ssh_local_port(ssh));
         child_set_env(&env, &envsize, "SSH_CLIENT", buf);          child_set_env(&env, &envsize, "SSH_CLIENT", buf);
   
         laddr = get_local_ipaddr(packet_get_connection_in());          laddr = get_local_ipaddr(packet_get_connection_in());
         snprintf(buf, sizeof buf, "%.50s %d %.50s %d",          snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
             get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());              ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
               laddr, ssh_local_port(ssh));
         free(laddr);          free(laddr);
         child_set_env(&env, &envsize, "SSH_CONNECTION", buf);          child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
   
Line 1226  do_setup_env(Session *s, const char *she
Line 947  do_setup_env(Session *s, const char *she
          * Pull in any environment variables that may have           * Pull in any environment variables that may have
          * been set by PAM.           * been set by PAM.
          */           */
         if (options.use_pam && !options.use_login) {          if (options.use_pam) {
                 char **p;                  char **p;
   
                 p = fetch_pam_child_environment();                  p = fetch_pam_child_environment();
Line 1244  do_setup_env(Session *s, const char *she
Line 965  do_setup_env(Session *s, const char *she
                     auth_sock_name);                      auth_sock_name);
   
         /* read $HOME/.ssh/environment. */          /* read $HOME/.ssh/environment. */
         if (options.permit_user_env && !options.use_login) {          if (options.permit_user_env) {
                 snprintf(buf, sizeof buf, "%.200s/.ssh/environment",                  snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
                     pw->pw_dir);                      pw->pw_dir);
                 read_environment_file(&env, &envsize, buf);                  read_environment_file(&env, &envsize, buf);
Line 1513  do_pwchange(Session *s)
Line 1234  do_pwchange(Session *s)
         exit(1);          exit(1);
 }  }
   
 __dead static void  
 launch_login(struct passwd *pw, const char *hostname)  
 {  
         /* Launch login(1). */  
   
         execl("/usr/bin/login", "login", "-h", hostname,  
             "-p", "-f", "--", pw->pw_name, (char *)NULL);  
   
         /* Login couldn't be executed, die. */  
   
         perror("login");  
         exit(1);  
 }  
   
 static void  static void
 child_close_fds(void)  child_close_fds(void)
 {  {
Line 1577  do_child(Session *s, const char *command
Line 1284  do_child(Session *s, const char *command
         extern char **environ;          extern char **environ;
         char **env;          char **env;
         char *argv[ARGV_MAX];          char *argv[ARGV_MAX];
         const char *shell, *shell0, *hostname = NULL;          const char *shell, *shell0;
         struct passwd *pw = s->pw;          struct passwd *pw = s->pw;
         int r = 0;          int r = 0;
   
Line 1591  do_child(Session *s, const char *command
Line 1298  do_child(Session *s, const char *command
                 do_pwchange(s);                  do_pwchange(s);
         }          }
   
         /* login(1) is only called if we execute the login shell */  
         if (options.use_login && command != NULL)  
                 options.use_login = 0;  
   
         /*          /*
          * 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) {  
                 do_nologin(pw);  
                 do_setusercontext(pw);  
                 /*  
                  * PAM session modules in do_setusercontext may have  
                  * generated messages, so if this in an interactive  
                  * login then display them too.  
                  */  
                 if (!check_quietlogin(s, command))  
                         display_loginmsg();  
         }  
 #ifdef USE_PAM  #ifdef USE_PAM
         if (options.use_pam && !is_pam_session_open()) {          if (options.use_pam && !is_pam_session_open()) {
                 debug3("PAM session not opened, exiting");                  debug3("PAM session not opened, exiting");
Line 1617  do_child(Session *s, const char *command
Line 1309  do_child(Session *s, const char *command
                 exit(254);                  exit(254);
         }          }
 #endif  #endif
           do_nologin(pw);
           do_setusercontext(pw);
   
         /*          /*
          * Get the shell from the password data.  An empty shell field is           * Get the shell from the password data.  An empty shell field is
Line 1635  do_child(Session *s, const char *command
Line 1329  do_child(Session *s, const char *command
             __UNCONST(shell));              __UNCONST(shell));
 #endif  #endif
   
         /* we have to stash the hostname before we close our socket. */  
         if (options.use_login)  
                 hostname = get_remote_name_or_ip(utmp_len,  
                     options.use_dns);  
         /*          /*
          * 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
          * that we do not shutdown it.  Note that the descriptors cannot be           * that we do not shutdown it.  Note that the descriptors cannot be
          * closed before building the environment, as we call           * closed before building the environment, as we call
          * get_remote_ipaddr there.           * ssh_remote_ipaddr there.
          */           */
         child_close_fds();          child_close_fds();
   
Line 1695  do_child(Session *s, const char *command
Line 1385  do_child(Session *s, const char *command
   
         (void)closefrom(STDERR_FILENO + 1);          (void)closefrom(STDERR_FILENO + 1);
   
         if (!options.use_login)          do_rc_files(s, shell);
                 do_rc_files(s, shell);  
   
         /* restore SIGPIPE for child */          /* restore SIGPIPE for child */
         signal(SIGPIPE, SIG_DFL);          signal(SIGPIPE, SIG_DFL);
Line 1723  do_child(Session *s, const char *command
Line 1412  do_child(Session *s, const char *command
   
         fflush(NULL);          fflush(NULL);
   
         if (options.use_login) {  
                 launch_login(pw, hostname);  
                 /* NEVERREACHED */  
         }  
   
         /* Get the last component of the shell name. */          /* Get the last component of the shell name. */
         if ((shell0 = strrchr(shell, '/')) != NULL)          if ((shell0 = strrchr(shell, '/')) != NULL)
                 shell0++;                  shell0++;
Line 1971  session_pty_req(Session *s)
Line 1655  session_pty_req(Session *s)
         }          }
   
         s->term = packet_get_string(&len);          s->term = packet_get_string(&len);
           s->col = packet_get_int();
         if (compat20) {          s->row = packet_get_int();
                 s->col = packet_get_int();  
                 s->row = packet_get_int();  
         } else {  
                 s->row = packet_get_int();  
                 s->col = packet_get_int();  
         }  
         s->xpixel = packet_get_int();          s->xpixel = packet_get_int();
         s->ypixel = packet_get_int();          s->ypixel = packet_get_int();
   
Line 2000  session_pty_req(Session *s)
Line 1678  session_pty_req(Session *s)
         }          }
         debug("session_pty_req: session %d alloc %s", s->self, s->tty);          debug("session_pty_req: session %d alloc %s", s->self, s->tty);
   
         /* for SSH1 the tty modes length is not given */          n_bytes = packet_remaining();
         if (!compat20)  
                 n_bytes = packet_remaining();  
         tty_parse_modes(s->ttyfd, &n_bytes);          tty_parse_modes(s->ttyfd, &n_bytes);
   
         if (!use_privsep)          if (!use_privsep)
Line 2072  session_x11_req(Session *s)
Line 1748  session_x11_req(Session *s)
         s->screen = packet_get_int();          s->screen = packet_get_int();
         packet_check_eom();          packet_check_eom();
   
         success = session_setup_x11fwd(s);          if (xauth_valid_string(s->auth_proto) &&
               xauth_valid_string(s->auth_data))
                   success = session_setup_x11fwd(s);
           else {
                   success = 0;
                   error("Invalid X11 forwarding data");
           }
         if (!success) {          if (!success) {
                 free(s->auth_proto);                  free(s->auth_proto);
                 free(s->auth_data);                  free(s->auth_data);
Line 2212  void
Line 1894  void
 session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,  session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
     int is_tty)      int is_tty)
 {  {
         if (!compat20)  
                 fatal("session_set_fds: called for proto != 2.0");  
         /*          /*
          * now that have a child and a pipe to the child,           * now that have a child and a pipe to the child,
          * we can activate our channel and register the fd's           * we can activate our channel and register the fd's
Line 2394  session_exit_message(Session *s, int sta
Line 2074  session_exit_message(Session *s, int sta
 void  void
 session_close(Session *s)  session_close(Session *s)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         u_int i;          u_int i;
   
         verbose("Close session: user %s from %.200s port %d id %d",          verbose("Close session: user %s from %.200s port %d id %d",
             s->pw->pw_name,              s->pw->pw_name,
             get_remote_ipaddr(),              ssh_remote_ipaddr(ssh),
             get_remote_port(),              ssh_remote_port(ssh),
             s->self);              s->self);
   
         if (s->ttyfd != -1)          if (s->ttyfd != -1)
Line 2552  session_setup_x11fwd(Session *s)
Line 2233  session_setup_x11fwd(Session *s)
                 packet_send_debug("No xauth program; cannot forward with spoofing.");                  packet_send_debug("No xauth program; cannot forward with spoofing.");
                 return 0;                  return 0;
         }          }
         if (options.use_login) {  
                 packet_send_debug("X11 forwarding disabled; "  
                     "not compatible with UseLogin=yes.");  
                 return 0;  
         }  
         if (s->display != NULL) {          if (s->display != NULL) {
                 debug("X11 display already set.");                  debug("X11 display already set.");
                 return 0;                  return 0;
Line 2632  do_cleanup(Authctxt *authctxt)
Line 2308  do_cleanup(Authctxt *authctxt)
 #endif  #endif
   
 #ifdef GSSAPI  #ifdef GSSAPI
         if (compat20 && options.gss_cleanup_creds)          if (options.gss_cleanup_creds)
                 ssh_gssapi_cleanup_creds();                  ssh_gssapi_cleanup_creds();
 #endif  #endif
   
Line 2653  do_cleanup(Authctxt *authctxt)
Line 2329  do_cleanup(Authctxt *authctxt)
         if (!use_privsep || mm_is_monitor())          if (!use_privsep || mm_is_monitor())
                 session_destroy_all(session_pty_cleanup2);                  session_destroy_all(session_pty_cleanup2);
 }  }
   
   /* Return a name for the remote host that fits inside utmp_size */
   
   const char *
   session_get_remote_name_or_ip(struct ssh *ssh, u_int utmp_size, int use_dns)
   {
           const char *remote = "";
   
           if (utmp_size > 0)
                   remote = auth_get_canonical_hostname(ssh, use_dns);
           if (utmp_size == 0 || strlen(remote) > utmp_size)
                   remote = ssh_remote_ipaddr(ssh);
           return remote;
   }
   

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.19.2.3

CVSweb <webmaster@jp.NetBSD.org>