[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.186 and 1.186.2.2

version 1.186, 2005/07/25 11:59:40 version 1.186.2.2, 2006/10/06 03:19:33
Line 1 
Line 1 
   /* $OpenBSD$ */
 /*  /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved   *                    All rights reserved
Line 32 
Line 33 
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 #include "includes.h"  #include <sys/types.h>
 RCSID("$OpenBSD$");  #include <sys/wait.h>
   #include <sys/un.h>
   #include <sys/stat.h>
   #include <sys/socket.h>
   #include <sys/param.h>
   
   #include <errno.h>
   #include <grp.h>
   #include <paths.h>
   #include <pwd.h>
   #include <signal.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   
   #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
 #include "ssh1.h"  #include "ssh1.h"
 #include "ssh2.h"  #include "ssh2.h"
 #include "xmalloc.h"  
 #include "sshpty.h"  #include "sshpty.h"
 #include "packet.h"  #include "packet.h"
 #include "buffer.h"  #include "buffer.h"
Line 46 
Line 61 
 #include "uidswap.h"  #include "uidswap.h"
 #include "compat.h"  #include "compat.h"
 #include "channels.h"  #include "channels.h"
 #include "bufaux.h"  #include "key.h"
   #include "cipher.h"
   #include "kex.h"
   #include "hostfile.h"
 #include "auth.h"  #include "auth.h"
 #include "auth-options.h"  #include "auth-options.h"
 #include "pathnames.h"  #include "pathnames.h"
Line 56 
Line 74 
 #include "serverloop.h"  #include "serverloop.h"
 #include "canohost.h"  #include "canohost.h"
 #include "session.h"  #include "session.h"
 #include "kex.h"  #ifdef GSSAPI
   #include "ssh-gss.h"
   #endif
 #include "monitor_wrap.h"  #include "monitor_wrap.h"
   
 #ifdef KRB5  #ifdef KRB5
 #include <kafs.h>  #include <kafs.h>
 #endif  #endif
   
 #ifdef GSSAPI  
 #include "ssh-gss.h"  
 #endif  
   
 /* func */  /* func */
   
 Session *session_new(void);  Session *session_new(void);
Line 172 
Line 188 
         sunaddr.sun_family = AF_UNIX;          sunaddr.sun_family = AF_UNIX;
         strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));          strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
   
         if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)          if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
                 packet_disconnect("bind: %.100s", strerror(errno));                  packet_disconnect("bind: %.100s", strerror(errno));
   
         /* Restore the privileged uid. */          /* Restore the privileged uid. */
Line 206 
Line 222 
 {  {
         setproctitle("%s", authctxt->pw->pw_name);          setproctitle("%s", authctxt->pw->pw_name);
   
         /*  
          * Cancel the alarm we set to limit the time taken for  
          * authentication.  
          */  
         alarm(0);  
         if (startup_pipe != -1) {  
                 close(startup_pipe);  
                 startup_pipe = -1;  
         }  
         /* setup the channel layer */          /* setup the channel layer */
         if (!no_port_forwarding_flag && options.allow_tcp_forwarding)          if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
                 channel_permit_all_opens();                  channel_permit_all_opens();
Line 328 
Line 335 
                                 break;                                  break;
                         }                          }
                         debug("Received TCP/IP port forwarding request.");                          debug("Received TCP/IP port forwarding request.");
                         channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);                          if (channel_input_port_forward_request(s->pw->pw_uid == 0,
                               options.gateway_ports) < 0) {
                                   debug("Port forwarding failed.");
                                   break;
                           }
                         success = 1;                          success = 1;
                         break;                          break;
   
Line 380 
Line 391 
 {  {
         pid_t pid;          pid_t pid;
   
 #ifdef USE_PIPES  
         int pin[2], pout[2], perr[2];  
         /* Allocate pipes for communicating with the program. */  
         if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)  
                 packet_disconnect("Could not create pipes: %.100s",  
                                   strerror(errno));  
 #else /* USE_PIPES */  
         int inout[2], err[2];          int inout[2], err[2];
         /* Uses socket pairs to communicate with the program. */          /* Uses socket pairs to communicate with the program. */
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||          if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
             socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)              socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
                 packet_disconnect("Could not create socket pairs: %.100s",                  packet_disconnect("Could not create socket pairs: %.100s",
                                   strerror(errno));                                    strerror(errno));
 #endif /* USE_PIPES */  
         if (s == NULL)          if (s == NULL)
                 fatal("do_exec_no_pty: no session");                  fatal("do_exec_no_pty: no session");
   
Line 413 
Line 416 
                 if (setsid() < 0)                  if (setsid() < 0)
                         error("setsid failed: %.100s", strerror(errno));                          error("setsid failed: %.100s", strerror(errno));
   
 #ifdef USE_PIPES  
                 /*                  /*
                  * Redirect stdin.  We close the parent side of the socket  
                  * pair, and make the child side the standard input.  
                  */  
                 close(pin[1]);  
                 if (dup2(pin[0], 0) < 0)  
                         perror("dup2 stdin");  
                 close(pin[0]);  
   
                 /* Redirect stdout. */  
                 close(pout[0]);  
                 if (dup2(pout[1], 1) < 0)  
                         perror("dup2 stdout");  
                 close(pout[1]);  
   
                 /* Redirect stderr. */  
                 close(perr[0]);  
                 if (dup2(perr[1], 2) < 0)  
                         perror("dup2 stderr");  
                 close(perr[1]);  
 #else /* USE_PIPES */  
                 /*  
                  * Redirect stdin, stdout, and stderr.  Stdin and stdout will                   * Redirect stdin, stdout, and stderr.  Stdin and stdout will
                  * use the same socket, as some programs (particularly rdist)                   * use the same socket, as some programs (particularly rdist)
                  * seem to depend on it.                   * seem to depend on it.
Line 448 
Line 429 
                         perror("dup2 stdout");                          perror("dup2 stdout");
                 if (dup2(err[0], 2) < 0)        /* stderr */                  if (dup2(err[0], 2) < 0)        /* stderr */
                         perror("dup2 stderr");                          perror("dup2 stderr");
 #endif /* USE_PIPES */  
   
                 /* Do processing for the child (exec command etc). */                  /* Do processing for the child (exec command etc). */
                 do_child(s, command);                  do_child(s, command);
Line 459 
Line 439 
         s->pid = pid;          s->pid = pid;
         /* Set interactive/non-interactive mode. */          /* Set interactive/non-interactive mode. */
         packet_set_interactive(s->display != NULL);          packet_set_interactive(s->display != NULL);
 #ifdef USE_PIPES  
         /* We are the parent.  Close the child sides of the pipes. */  
         close(pin[0]);  
         close(pout[1]);  
         close(perr[1]);  
   
         if (compat20) {  
                 if (s->is_subsystem) {  
                         close(perr[0]);  
                         perr[0] = -1;  
                 }  
                 session_set_fds(s, pin[1], pout[0], perr[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 /* USE_PIPES */  
         /* 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]);
         close(err[0]);          close(err[0]);
Line 491 
Line 454 
                 server_loop(pid, inout[1], inout[1], err[1]);                  server_loop(pid, inout[1], inout[1], err[1]);
                 /* server_loop has closed inout[1] and err[1]. */                  /* server_loop has closed inout[1] and err[1]. */
         }          }
 #endif /* USE_PIPES */  
 }  }
   
 /*  /*
Line 581 
Line 543 
 void  void
 do_exec(Session *s, const char *command)  do_exec(Session *s, const char *command)
 {  {
         if (forced_command) {          if (options.adm_forced_command) {
                 original_command = command;                  original_command = command;
                   command = options.adm_forced_command;
                   debug("Forced command (config) '%.900s'", command);
           } else if (forced_command) {
                   original_command = command;
                 command = forced_command;                  command = forced_command;
                 debug("Forced command '%.900s'", command);                  debug("Forced command (key option) '%.900s'", command);
         }          }
   
 #ifdef GSSAPI  #ifdef GSSAPI
Line 628 
Line 594 
         fromlen = sizeof(from);          fromlen = sizeof(from);
         if (packet_connection_is_on_socket()) {          if (packet_connection_is_on_socket()) {
                 if (getpeername(packet_get_connection_in(),                  if (getpeername(packet_get_connection_in(),
                     (struct sockaddr *) & from, &fromlen) < 0) {                      (struct sockaddr *)&from, &fromlen) < 0) {
                         debug("getpeername: %.100s", strerror(errno));                          debug("getpeername: %.100s", strerror(errno));
                         cleanup_exit(255);                          cleanup_exit(255);
                 }                  }
Line 730 
Line 696 
                         if (envsize >= 1000)                          if (envsize >= 1000)
                                 fatal("child_set_env: too many env vars");                                  fatal("child_set_env: too many env vars");
                         envsize += 50;                          envsize += 50;
                         env = (*envp) = xrealloc(env, envsize * sizeof(char *));                          env = (*envp) = xrealloc(env, envsize, sizeof(char *));
                         *envsizep = envsize;                          *envsizep = envsize;
                 }                  }
                 /* Need to set the NULL pointer at end of array beyond the new slot. */                  /* Need to set the NULL pointer at end of array beyond the new slot. */
Line 1082 
Line 1048 
         endpwent();          endpwent();
   
         /*          /*
          * Close any extra open file descriptors so that we don\'t have them           * Close any extra open file descriptors so that we don't have them
          * hanging around in clients.  Note that we want to do this after           * hanging around in clients.  Note that we want to do this after
          * initgroups, because at least on Solaris 2.3 it leaves file           * initgroups, because at least on Solaris 2.3 it leaves file
          * descriptors open.           * descriptors open.
Line 1190 
Line 1156 
         }          }
 #endif  #endif
   
         /* 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));
Line 1204 
Line 1170 
                 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);
   
         if (options.use_login) {          if (options.use_login) {
                 launch_login(pw, hostname);                  launch_login(pw, hostname);
Line 1468 
Line 1434 
         struct stat st;          struct stat st;
         u_int len;          u_int len;
         int success = 0;          int success = 0;
         char *cmd, *subsys = packet_get_string(&len);          char *prog, *cmd, *subsys = packet_get_string(&len);
         u_int i;          u_int i;
   
         packet_check_eom();          packet_check_eom();
Line 1476 
Line 1442 
   
         for (i = 0; i < options.num_subsystems; i++) {          for (i = 0; i < options.num_subsystems; i++) {
                 if (strcmp(subsys, options.subsystem_name[i]) == 0) {                  if (strcmp(subsys, options.subsystem_name[i]) == 0) {
                         cmd = options.subsystem_command[i];                          prog = options.subsystem_command[i];
                         if (stat(cmd, &st) < 0) {                          cmd = options.subsystem_args[i];
                                 error("subsystem: cannot stat %s: %s", cmd,                          if (stat(prog, &st) < 0) {
                                   error("subsystem: cannot stat %s: %s", prog,
                                     strerror(errno));                                      strerror(errno));
                                 break;                                  break;
                         }                          }
Line 1505 
Line 1472 
   
         if (s->auth_proto != NULL || s->auth_data != NULL) {          if (s->auth_proto != NULL || s->auth_data != NULL) {
                 error("session_x11_req: session %d: "                  error("session_x11_req: session %d: "
                     "x11 fowarding already active", s->self);                      "x11 forwarding already active", s->self);
                 return 0;                  return 0;
         }          }
         s->single_connection = packet_get_char();          s->single_connection = packet_get_char();
Line 1575 
Line 1542 
         for (i = 0; i < options.num_accept_env; i++) {          for (i = 0; i < options.num_accept_env; i++) {
                 if (match_pattern(name, options.accept_env[i])) {                  if (match_pattern(name, options.accept_env[i])) {
                         debug2("Setting env %d: %s=%s", s->num_env, name, val);                          debug2("Setting env %d: %s=%s", s->num_env, name, val);
                         s->env = xrealloc(s->env, sizeof(*s->env) *                          s->env = xrealloc(s->env, s->num_env + 1,
                             (s->num_env + 1));                              sizeof(*s->env));
                         s->env[s->num_env].name = name;                          s->env[s->num_env].name = name;
                         s->env[s->num_env].val = val;                          s->env[s->num_env].val = val;
                         s->num_env++;                          s->num_env++;
Line 1737 
Line 1704 
 {  {
         Channel *c;          Channel *c;
   
         if ((c = channel_lookup(id)) == NULL) {          if ((c = channel_by_id(id)) == NULL) {
                 debug("session_close_x11: x11 channel %d missing", id);                  debug("session_close_x11: x11 channel %d missing", id);
         } else {          } else {
                 /* Detach X11 listener */                  /* Detach X11 listener */
Line 1792 
Line 1759 
 session_exit_message(Session *s, int status)  session_exit_message(Session *s, int status)
 {  {
         Channel *c;          Channel *c;
         u_int i;  
   
         if ((c = channel_lookup(s->chanid)) == NULL)          if ((c = channel_lookup(s->chanid)) == NULL)
                 fatal("session_exit_message: session %d: no channel %d",                  fatal("session_exit_message: session %d: no channel %d",
Line 1818 
Line 1784 
   
         /* disconnect channel */          /* disconnect channel */
         debug("session_exit_message: release channel %d", s->chanid);          debug("session_exit_message: release channel %d", s->chanid);
         channel_cancel_cleanup(s->chanid);  
         /*          /*
            * Adjust cleanup callback attachment to send close messages when
            * the channel gets EOF. The session will be then be closed
            * by session_close_by_channel when the childs close their fds.
            */
           channel_register_cleanup(c->self, session_close_by_channel, 1);
   
           /*
          * emulate a write failure with 'chan_write_failed', nobody will be           * emulate a write failure with 'chan_write_failed', nobody will be
          * interested in data we write.           * interested in data we write.
          * Note that we must not call 'chan_read_failed', since there could           * Note that we must not call 'chan_read_failed', since there could
Line 1827 
Line 1800 
          */           */
         if (c->ostate != CHAN_OUTPUT_CLOSED)          if (c->ostate != CHAN_OUTPUT_CLOSED)
                 chan_write_failed(c);                  chan_write_failed(c);
         s->chanid = -1;  
   
         /* Close any X11 listeners associated with this session */  
         if (s->x11_chanids != NULL) {  
                 for (i = 0; s->x11_chanids[i] != -1; i++) {  
                         session_close_x11(s->x11_chanids[i]);  
                         s->x11_chanids[i] = -1;  
                 }  
         }  
 }  }
   
 void  void
Line 1859 
Line 1823 
         if (s->auth_proto)          if (s->auth_proto)
                 xfree(s->auth_proto);                  xfree(s->auth_proto);
         s->used = 0;          s->used = 0;
         for (i = 0; i < s->num_env; i++) {          if (s->env != NULL) {
                 xfree(s->env[i].name);                  for (i = 0; i < s->num_env; i++) {
                 xfree(s->env[i].val);                          xfree(s->env[i].name);
         }                          xfree(s->env[i].val);
         if (s->env != NULL)                  }
                 xfree(s->env);                  xfree(s->env);
           }
         session_proctitle(s);          session_proctitle(s);
 }  }
   
Line 1879 
Line 1844 
         }          }
         if (s->chanid != -1)          if (s->chanid != -1)
                 session_exit_message(s, status);                  session_exit_message(s, status);
         session_close(s);          if (s->ttyfd != -1)
                   session_pty_cleanup(s);
           s->pid = 0;
 }  }
   
 /*  /*
Line 1890 
Line 1857 
 session_close_by_channel(int id, void *arg)  session_close_by_channel(int id, void *arg)
 {  {
         Session *s = session_by_channel(id);          Session *s = session_by_channel(id);
           u_int i;
   
         if (s == NULL) {          if (s == NULL) {
                 debug("session_close_by_channel: no session for id %d", id);                  debug("session_close_by_channel: no session for id %d", id);
Line 1909 
Line 1877 
         }          }
         /* detach by removing callback */          /* detach by removing callback */
         channel_cancel_cleanup(s->chanid);          channel_cancel_cleanup(s->chanid);
   
           /* Close any X11 listeners associated with this session */
           if (s->x11_chanids != NULL) {
                   for (i = 0; s->x11_chanids[i] != -1; i++) {
                           session_close_x11(s->x11_chanids[i]);
                           s->x11_chanids[i] = -1;
                   }
           }
   
         s->chanid = -1;          s->chanid = -1;
         session_close(s);          session_close(s);
 }  }
Line 1994 
Line 1971 
         }          }
         for (i = 0; s->x11_chanids[i] != -1; i++) {          for (i = 0; s->x11_chanids[i] != -1; i++) {
                 channel_register_cleanup(s->x11_chanids[i],                  channel_register_cleanup(s->x11_chanids[i],
                     session_close_single_x11);                      session_close_single_x11, 0);
         }          }
   
         /* Set up a suitable value for the DISPLAY variable. */          /* Set up a suitable value for the DISPLAY variable. */
Line 2044 
Line 2021 
                 return;                  return;
         called = 1;          called = 1;
   
         if (authctxt == NULL)          if (authctxt == NULL || !authctxt->authenticated)
                 return;                  return;
 #ifdef KRB5  #ifdef KRB5
         if (options.kerberos_ticket_cleanup &&          if (options.kerberos_ticket_cleanup &&

Legend:
Removed from v.1.186  
changed lines
  Added in v.1.186.2.2