[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.134.2.3 and 1.135

version 1.134.2.3, 2003/04/03 22:35:17 version 1.135, 2002/05/16 22:09:59
Line 98 
Line 98 
 login_cap_t *lc;  login_cap_t *lc;
 #endif  #endif
   
 /* Name and directory of socket for authentication agent forwarding. */  
 static char *auth_sock_name = NULL;  
 static char *auth_sock_dir = NULL;  
   
 /* removes the agent forwarding socket */  
   
 static void  
 auth_sock_cleanup_proc(void *_pw)  
 {  
         struct passwd *pw = _pw;  
   
         if (auth_sock_name != NULL) {  
                 temporarily_use_uid(pw);  
                 unlink(auth_sock_name);  
                 rmdir(auth_sock_dir);  
                 auth_sock_name = NULL;  
                 restore_uid();  
         }  
 }  
   
 static int  
 auth_input_request_forwarding(struct passwd * pw)  
 {  
         Channel *nc;  
         int sock;  
         struct sockaddr_un sunaddr;  
   
         if (auth_sock_name != NULL) {  
                 error("authentication forwarding requested twice.");  
                 return 0;  
         }  
   
         /* Temporarily drop privileged uid for mkdir/bind. */  
         temporarily_use_uid(pw);  
   
         /* Allocate a buffer for the socket name, and format the name. */  
         auth_sock_name = xmalloc(MAXPATHLEN);  
         auth_sock_dir = xmalloc(MAXPATHLEN);  
         strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);  
   
         /* Create private directory for socket */  
         if (mkdtemp(auth_sock_dir) == NULL) {  
                 packet_send_debug("Agent forwarding disabled: "  
                     "mkdtemp() failed: %.100s", strerror(errno));  
                 restore_uid();  
                 xfree(auth_sock_name);  
                 xfree(auth_sock_dir);  
                 auth_sock_name = NULL;  
                 auth_sock_dir = NULL;  
                 return 0;  
         }  
         snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",  
                  auth_sock_dir, (long) getpid());  
   
         /* delete agent socket on fatal() */  
         fatal_add_cleanup(auth_sock_cleanup_proc, pw);  
   
         /* Create the socket. */  
         sock = socket(AF_UNIX, SOCK_STREAM, 0);  
         if (sock < 0)  
                 packet_disconnect("socket: %.100s", strerror(errno));  
   
         /* Bind it to the name. */  
         memset(&sunaddr, 0, sizeof(sunaddr));  
         sunaddr.sun_family = AF_UNIX;  
         strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));  
   
         if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)  
                 packet_disconnect("bind: %.100s", strerror(errno));  
   
         /* Restore the privileged uid. */  
         restore_uid();  
   
         /* Start listening on the socket. */  
         if (listen(sock, 5) < 0)  
                 packet_disconnect("listen: %.100s", strerror(errno));  
   
         /* Allocate a channel for the authentication agent socket. */  
         nc = channel_new("auth socket",  
             SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,  
             CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,  
             0, xstrdup("auth socket"), 1);  
         strlcpy(nc->path, auth_sock_name, sizeof(nc->path));  
         return 1;  
 }  
   
   
 void  void
 do_authenticated(Authctxt *authctxt)  do_authenticated(Authctxt *authctxt)
 {  {
         setproctitle("%s", authctxt->pw->pw_name);  
   
         /*          /*
          * Cancel the alarm we set to limit the time taken for           * Cancel the alarm we set to limit the time taken for
          * authentication.           * authentication.
Line 209 
Line 120 
                 do_authenticated1(authctxt);                  do_authenticated1(authctxt);
   
         /* remove agent socket */          /* remove agent socket */
         if (auth_sock_name != NULL)          if (auth_get_socket_name())
                 auth_sock_cleanup_proc(authctxt->pw);                  auth_sock_cleanup_proc(authctxt->pw);
 #ifdef KRB4  #ifdef KRB4
         if (options.kerberos_ticket_cleanup)          if (options.kerberos_ticket_cleanup)
Line 233 
Line 144 
         Session *s;          Session *s;
         char *command;          char *command;
         int success, type, screen_flag;          int success, type, screen_flag;
         int enable_compression_after_reply = 0;          int compression_level = 0, enable_compression_after_reply = 0;
         u_int proto_len, data_len, dlen, compression_level = 0;          u_int proto_len, data_len, dlen;
   
         s = session_new();          s = session_new();
         s->authctxt = authctxt;          s->authctxt = authctxt;
Line 260 
Line 171 
                                     compression_level);                                      compression_level);
                                 break;                                  break;
                         }                          }
                         if (!options.compression) {  
                                 debug2("compression disabled");  
                                 break;  
                         }  
                         /* Enable compression after we have responded with SUCCESS. */                          /* Enable compression after we have responded with SUCCESS. */
                         enable_compression_after_reply = 1;                          enable_compression_after_reply = 1;
                         success = 1;                          success = 1;
Line 420 
Line 327 
 void  void
 do_exec_no_pty(Session *s, const char *command)  do_exec_no_pty(Session *s, const char *command)
 {  {
         pid_t pid;          int pid;
   
 #ifdef USE_PIPES  #ifdef USE_PIPES
         int pin[2], pout[2], perr[2];          int pin[2], pout[2], perr[2];
Line 443 
Line 350 
   
         /* Fork the child. */          /* Fork the child. */
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
                 fatal_remove_all_cleanups();  
   
                 /* Child.  Reinitialize the log since the pid has changed. */                  /* Child.  Reinitialize the log since 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);
   
Line 551 
Line 456 
   
         /* Fork the child. */          /* Fork the child. */
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
                 fatal_remove_all_cleanups();  
   
                 /* 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);
Line 649 
Line 553 
          * the address be 0.0.0.0.           * the address be 0.0.0.0.
          */           */
         memset(&from, 0, sizeof(from));          memset(&from, 0, sizeof(from));
         fromlen = sizeof(from);  
         if (packet_connection_is_on_socket()) {          if (packet_connection_is_on_socket()) {
                   fromlen = sizeof(from);
                 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));
Line 663 
Line 567 
                 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,                      get_remote_name_or_ip(utmp_len,
                     options.verify_reverse_mapping),                      options.verify_reverse_mapping),
                     (struct sockaddr *)&from, fromlen);                      (struct sockaddr *)&from);
   
         if (check_quietlogin(s, command))          if (check_quietlogin(s, command))
                 return;                  return;
Line 758 
Line 662 
         } else {          } else {
                 /* New variable.  Expand if necessary. */                  /* New variable.  Expand if necessary. */
                 if (i >= (*envsizep) - 1) {                  if (i >= (*envsizep) - 1) {
                         if (*envsizep >= 1000)  
                                 fatal("child_set_env: too many env vars,"  
                                     " skipping: %.100s", name);  
                         (*envsizep) += 50;                          (*envsizep) += 50;
                         env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));                          env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
                 }                  }
Line 786 
Line 687 
         FILE *f;          FILE *f;
         char buf[4096];          char buf[4096];
         char *cp, *value;          char *cp, *value;
         u_int lineno = 0;  
   
         f = fopen(filename, "r");          f = fopen(filename, "r");
         if (!f)          if (!f)
                 return;                  return;
   
         while (fgets(buf, sizeof(buf), f)) {          while (fgets(buf, sizeof(buf), f)) {
                 if (++lineno > 1000)  
                         fatal("Too many lines in environment file %s", filename);  
                 for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)                  for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
                         ;                          ;
                 if (!*cp || *cp == '#' || *cp == '\n')                  if (!*cp || *cp == '#' || *cp == '\n')
Line 803 
Line 701 
                         *strchr(cp, '\n') = '\0';                          *strchr(cp, '\n') = '\0';
                 value = strchr(cp, '=');                  value = strchr(cp, '=');
                 if (value == NULL) {                  if (value == NULL) {
                         fprintf(stderr, "Bad line %u in %.100s\n", lineno,                          fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
                             filename);  
                         continue;                          continue;
                 }                  }
                 /*                  /*
Line 823 
Line 720 
 {  {
         char buf[256];          char buf[256];
         u_int i, envsize;          u_int i, envsize;
         char **env, *laddr;          char **env;
         struct passwd *pw = s->pw;          struct passwd *pw = s->pw;
   
         /* Initialize the environment. */          /* Initialize the environment. */
Line 837 
Line 734 
                 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  #ifdef HAVE_LOGIN_CAP
                 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)                  (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
                         child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);                  child_set_env(&env, &envsize, "PATH", getenv("PATH"));
                 else  
                         child_set_env(&env, &envsize, "PATH", getenv("PATH"));  
 #else  #else
                 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);                  child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
 #endif  #endif
Line 859 
Line 754 
         if (!options.use_login) {          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 *s = ce->s;
   
                         for (i = 0; str[i] != '=' && str[i]; i++)                          for (i = 0; s[i] != '=' && s[i]; i++)
                                 ;                                  ;
                         if (str[i] == '=') {                          if (s[i] == '=') {
                                 str[i] = 0;                                  s[i] = 0;
                                 child_set_env(&env, &envsize, str, str + i + 1);                                  child_set_env(&env, &envsize, s, s + i + 1);
                         }                          }
                         custom_environment = ce->next;                          custom_environment = ce->next;
                         xfree(ce->s);                          xfree(ce->s);
Line 873 
Line 768 
                 }                  }
         }          }
   
         /* 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());              get_remote_ipaddr(), get_remote_port(), get_local_port());
         child_set_env(&env, &envsize, "SSH_CLIENT", buf);          child_set_env(&env, &envsize, "SSH_CLIENT", buf);
   
         laddr = get_local_ipaddr(packet_get_connection_in());  
         snprintf(buf, sizeof buf, "%.50s %d %.50s %d",  
             get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());  
         xfree(laddr);  
         child_set_env(&env, &envsize, "SSH_CONNECTION", buf);  
   
         if (s->ttyfd != -1)          if (s->ttyfd != -1)
                 child_set_env(&env, &envsize, "SSH_TTY", s->tty);                  child_set_env(&env, &envsize, "SSH_TTY", s->tty);
         if (s->term)          if (s->term)
Line 903 
Line 791 
                 child_set_env(&env, &envsize, "KRB5CCNAME",                  child_set_env(&env, &envsize, "KRB5CCNAME",
                     s->authctxt->krb5_ticket_file);                      s->authctxt->krb5_ticket_file);
 #endif  #endif
         if (auth_sock_name != NULL)          if (auth_get_socket_name() != NULL)
                 child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,                  child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
                     auth_sock_name);                      auth_get_socket_name());
   
         /* read $HOME/.ssh/environment. */          /* read $HOME/.ssh/environment. */
         if (options.permit_user_env && !options.use_login) {          if (!options.use_login) {
                 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 969 
Line 857 
                 /* Add authority data to .Xauthority if appropriate. */                  /* Add authority data to .Xauthority if appropriate. */
                 if (debug_flag) {                  if (debug_flag) {
                         fprintf(stderr,                          fprintf(stderr,
                             "Running %.500s remove %.100s\n",                              "Running %.500s add "
                             options.xauth_location, s->auth_display);                              "%.100s %.100s %.100s\n",
                         fprintf(stderr,  
                             "%.500s add %.100s %.100s %.100s\n",  
                             options.xauth_location, s->auth_display,                              options.xauth_location, s->auth_display,
                             s->auth_proto, s->auth_data);                              s->auth_proto, s->auth_data);
                 }                  }
Line 980 
Line 866 
                     options.xauth_location);                      options.xauth_location);
                 f = popen(cmd, "w");                  f = popen(cmd, "w");
                 if (f) {                  if (f) {
                         fprintf(f, "remove %s\n",  
                             s->auth_display);  
                         fprintf(f, "add %s %s %s\n",                          fprintf(f, "add %s %s %s\n",
                             s->auth_display, s->auth_proto,                              s->auth_display, s->auth_proto,
                             s->auth_data);                              s->auth_data);
Line 1009 
Line 893 
 #endif  #endif
         if (f) {          if (f) {
                 /* /etc/nologin exists.  Print its contents and exit. */                  /* /etc/nologin exists.  Print its contents and exit. */
                 log("User %.100s not allowed because %s exists",  
                     pw->pw_name, _PATH_NOLOGIN);  
                 while (fgets(buf, sizeof(buf), f))                  while (fgets(buf, sizeof(buf), f))
                         fputs(buf, stderr);                          fputs(buf, stderr);
                 fclose(f);                  fclose(f);
Line 1101 
Line 983 
          * 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;
   
         /*  
          * Make sure $SHELL points to the shell from the password file,  
          * even if shell is overridden from login.conf  
          */  
         env = do_setup_env(s, shell);  
   
 #ifdef HAVE_LOGIN_CAP  #ifdef HAVE_LOGIN_CAP
         shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);          shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
 #endif  #endif
   
           env = do_setup_env(s, shell);
   
         /* we have to stash the hostname before we close our socket. */          /* we have to stash the hostname before we close our socket. */
         if (options.use_login)          if (options.use_login)
                 hostname = get_remote_name_or_ip(utmp_len,                  hostname = get_remote_name_or_ip(utmp_len,
Line 1270 
Line 1147 
         int i;          int i;
         for (i = 0; i < MAX_SESSIONS; i++) {          for (i = 0; i < MAX_SESSIONS; i++) {
                 Session *s = &sessions[i];                  Session *s = &sessions[i];
                 debug("dump: used %d session %d %p channel %d pid %ld",                  debug("dump: used %d session %d %p channel %d pid %d",
                     s->used,                      s->used,
                     s->self,                      s->self,
                     s,                      s,
                     s->chanid,                      s->chanid,
                     (long)s->pid);                      s->pid);
         }          }
 }  }
   
Line 1333 
Line 1210 
 session_by_pid(pid_t pid)  session_by_pid(pid_t pid)
 {  {
         int i;          int i;
         debug("session_by_pid: pid %ld", (long)pid);          debug("session_by_pid: pid %d", pid);
         for (i = 0; i < MAX_SESSIONS; i++) {          for (i = 0; i < MAX_SESSIONS; i++) {
                 Session *s = &sessions[i];                  Session *s = &sessions[i];
                 if (s->used && s->pid == pid)                  if (s->used && s->pid == pid)
                         return s;                          return s;
         }          }
         error("session_by_pid: unknown pid %ld", (long)pid);          error("session_by_pid: unknown pid %d", pid);
         session_dump();          session_dump();
         return NULL;          return NULL;
 }  }
Line 1621 
Line 1498 
         PRIVSEP(session_pty_cleanup2(session));          PRIVSEP(session_pty_cleanup2(session));
 }  }
   
 static char *  
 sig2name(int sig)  
 {  
 #define SSH_SIG(x) if (sig == SIG ## x) return #x  
         SSH_SIG(ABRT);  
         SSH_SIG(ALRM);  
         SSH_SIG(FPE);  
         SSH_SIG(HUP);  
         SSH_SIG(ILL);  
         SSH_SIG(INT);  
         SSH_SIG(KILL);  
         SSH_SIG(PIPE);  
         SSH_SIG(QUIT);  
         SSH_SIG(SEGV);  
         SSH_SIG(TERM);  
         SSH_SIG(USR1);  
         SSH_SIG(USR2);  
 #undef  SSH_SIG  
         return "SIG@openssh.com";  
 }  
   
 static void  static void
 session_exit_message(Session *s, int status)  session_exit_message(Session *s, int status)
 {  {
Line 1650 
Line 1506 
         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",
                     s->self, s->chanid);                      s->self, s->chanid);
         debug("session_exit_message: session %d channel %d pid %ld",          debug("session_exit_message: session %d channel %d pid %d",
             s->self, s->chanid, (long)s->pid);              s->self, s->chanid, s->pid);
   
         if (WIFEXITED(status)) {          if (WIFEXITED(status)) {
                 channel_request_start(s->chanid, "exit-status", 0);                  channel_request_start(s->chanid, "exit-status", 0);
Line 1659 
Line 1515 
                 packet_send();                  packet_send();
         } else if (WIFSIGNALED(status)) {          } else if (WIFSIGNALED(status)) {
                 channel_request_start(s->chanid, "exit-signal", 0);                  channel_request_start(s->chanid, "exit-signal", 0);
                 packet_put_cstring(sig2name(WTERMSIG(status)));                  packet_put_int(WTERMSIG(status));
                 packet_put_char(WCOREDUMP(status));                  packet_put_char(WCOREDUMP(status));
                 packet_put_cstring("");                  packet_put_cstring("");
                 packet_put_cstring("");                  packet_put_cstring("");
Line 1686 
Line 1542 
 void  void
 session_close(Session *s)  session_close(Session *s)
 {  {
         debug("session_close: session %d pid %ld", s->self, (long)s->pid);          debug("session_close: session %d pid %d", s->self, s->pid);
         if (s->ttyfd != -1) {          if (s->ttyfd != -1) {
                 fatal_remove_cleanup(session_pty_cleanup, (void *)s);                  fatal_remove_cleanup(session_pty_cleanup, (void *)s);
                 session_pty_cleanup(s);                  session_pty_cleanup(s);
Line 1710 
Line 1566 
 {  {
         Session *s = session_by_pid(pid);          Session *s = session_by_pid(pid);
         if (s == NULL) {          if (s == NULL) {
                 debug("session_close_by_pid: no session for pid %ld",                  debug("session_close_by_pid: no session for pid %d", pid);
                     (long)pid);  
                 return;                  return;
         }          }
         if (s->chanid != -1)          if (s->chanid != -1)
Line 1731 
Line 1586 
                 debug("session_close_by_channel: no session for id %d", id);                  debug("session_close_by_channel: no session for id %d", id);
                 return;                  return;
         }          }
         debug("session_close_by_channel: channel %d child %ld",          debug("session_close_by_channel: channel %d child %d", id, s->pid);
             id, (long)s->pid);  
         if (s->pid != 0) {          if (s->pid != 0) {
                 debug("session_close_by_channel: channel %d: has child", id);                  debug("session_close_by_channel: channel %d: has child", id);
                 /*                  /*
Line 1823 
Line 1677 
                 debug("X11 display already set.");                  debug("X11 display already set.");
                 return 0;                  return 0;
         }          }
         if (x11_create_display_inet(options.x11_display_offset,          s->display_number = x11_create_display_inet(options.x11_display_offset,
             options.x11_use_localhost, s->single_connection,              options.x11_use_localhost, s->single_connection);
             &s->display_number) == -1) {          if (s->display_number == -1) {
                 debug("x11_create_display_inet failed.");                  debug("x11_create_display_inet failed.");
                 return 0;                  return 0;
         }          }
Line 1839 
Line 1693 
          * different than the DISPLAY string for localhost displays.           * different than the DISPLAY string for localhost displays.
          */           */
         if (options.x11_use_localhost) {          if (options.x11_use_localhost) {
                 snprintf(display, sizeof display, "localhost:%u.%u",                  snprintf(display, sizeof display, "localhost:%d.%d",
                     s->display_number, s->screen);                      s->display_number, s->screen);
                 snprintf(auth_display, sizeof auth_display, "unix:%u.%u",                  snprintf(auth_display, sizeof auth_display, "unix:%d.%d",
                     s->display_number, s->screen);                      s->display_number, s->screen);
                 s->display = xstrdup(display);                  s->display = xstrdup(display);
                 s->auth_display = xstrdup(auth_display);                  s->auth_display = xstrdup(auth_display);
         } else {          } else {
                 snprintf(display, sizeof display, "%.400s:%u.%u", hostname,                  snprintf(display, sizeof display, "%.400s:%d.%d", hostname,
                     s->display_number, s->screen);                      s->display_number, s->screen);
                 s->display = xstrdup(display);                  s->display = xstrdup(display);
                 s->auth_display = xstrdup(display);                  s->auth_display = xstrdup(display);

Legend:
Removed from v.1.134.2.3  
changed lines
  Added in v.1.135