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

Diff for /src/usr.bin/ssh/channels.c between version 1.172.2.5 and 1.173

version 1.172.2.5, 2003/04/03 22:35:17 version 1.173, 2002/04/22 21:04:52
Line 46 
Line 46 
 #include "ssh2.h"  #include "ssh2.h"
 #include "packet.h"  #include "packet.h"
 #include "xmalloc.h"  #include "xmalloc.h"
   #include "uidswap.h"
 #include "log.h"  #include "log.h"
 #include "misc.h"  #include "misc.h"
 #include "channels.h"  #include "channels.h"
Line 128 
Line 129 
   
 #define NUM_SOCKS       10  #define NUM_SOCKS       10
   
   /* Name and directory of socket for authentication agent forwarding. */
   static char *auth_sock_name = NULL;
   static char *auth_sock_dir = NULL;
   
 /* AF_UNSPEC or AF_INET or AF_INET6 */  /* AF_UNSPEC or AF_INET or AF_INET6 */
 static int IPv4or6 = AF_UNSPEC;  static int IPv4or6 = AF_UNSPEC;
   
Line 205 
Line 210 
   
 Channel *  Channel *
 channel_new(char *ctype, int type, int rfd, int wfd, int efd,  channel_new(char *ctype, int type, int rfd, int wfd, int efd,
     u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)      int window, int maxpack, int extusage, char *remote_name, int nonblock)
 {  {
         int i, found;          int i, found;
         Channel *c;          Channel *c;
Line 229 
Line 234 
                 /* There are no free slots.  Take last+1 slot and expand the array.  */                  /* There are no free slots.  Take last+1 slot and expand the array.  */
                 found = channels_alloc;                  found = channels_alloc;
                 channels_alloc += 10;                  channels_alloc += 10;
                 if (channels_alloc > 10000)  
                         fatal("channel_new: internal error: channels_alloc %d "  
                             "too big.", channels_alloc);  
                 debug2("channel: expanding %d", channels_alloc);                  debug2("channel: expanding %d", channels_alloc);
                 channels = xrealloc(channels, channels_alloc * sizeof(Channel *));                  channels = xrealloc(channels, channels_alloc * sizeof(Channel *));
                 for (i = found; i < channels_alloc; i++)                  for (i = found; i < channels_alloc; i++)
Line 412 
Line 414 
 #if 0  #if 0
                         if (!compat20 &&                          if (!compat20 &&
                             buffer_len(&c->input) > packet_get_maxsize()) {                              buffer_len(&c->input) > packet_get_maxsize()) {
                                 debug2("channel %d: big input buffer %d",                                  debug("channel %d: big input buffer %d",
                                     c->self, buffer_len(&c->input));                                      c->self, buffer_len(&c->input));
                                 return 0;                                  return 0;
                         }                          }
 #endif  #endif
                         if (buffer_len(&c->output) > packet_get_maxsize()) {                          if (buffer_len(&c->output) > packet_get_maxsize()) {
                                 debug2("channel %d: big output buffer %d > %d",                                  debug("channel %d: big output buffer %d > %d",
                                     c->self, buffer_len(&c->output),                                      c->self, buffer_len(&c->output),
                                     packet_get_maxsize());                                      packet_get_maxsize());
                                 return 0;                                  return 0;
Line 572 
Line 574 
 channel_send_open(int id)  channel_send_open(int id)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_send_open: %d: bad id", id);                  log("channel_send_open: %d: bad id", id);
                 return;                  return;
         }          }
         debug2("channel %d: send open", id);          debug("send channel open %d", id);
         packet_start(SSH2_MSG_CHANNEL_OPEN);          packet_start(SSH2_MSG_CHANNEL_OPEN);
         packet_put_cstring(c->ctype);          packet_put_cstring(c->ctype);
         packet_put_int(c->self);          packet_put_int(c->self);
Line 587 
Line 588 
 }  }
   
 void  void
 channel_request_start(int id, char *service, int wantconfirm)  channel_request_start(int local_id, char *service, int wantconfirm)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(local_id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_request_start: %d: unknown channel id", id);                  log("channel_request_start: %d: unknown channel id", local_id);
                 return;                  return;
         }          }
         debug("channel %d: request %s", id, service) ;          debug("channel request %d: %s", local_id, service) ;
         packet_start(SSH2_MSG_CHANNEL_REQUEST);          packet_start(SSH2_MSG_CHANNEL_REQUEST);
         packet_put_int(c->remote_id);          packet_put_int(c->remote_id);
         packet_put_cstring(service);          packet_put_cstring(service);
Line 605 
Line 605 
 channel_register_confirm(int id, channel_callback_fn *fn)  channel_register_confirm(int id, channel_callback_fn *fn)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_comfirm: %d: bad id", id);                  log("channel_register_comfirm: %d: bad id", id);
                 return;                  return;
Line 616 
Line 615 
 channel_register_cleanup(int id, channel_callback_fn *fn)  channel_register_cleanup(int id, channel_callback_fn *fn)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_cleanup: %d: bad id", id);                  log("channel_register_cleanup: %d: bad id", id);
                 return;                  return;
Line 627 
Line 625 
 channel_cancel_cleanup(int id)  channel_cancel_cleanup(int id)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_cancel_cleanup: %d: bad id", id);                  log("channel_cancel_cleanup: %d: bad id", id);
                 return;                  return;
Line 638 
Line 635 
 channel_register_filter(int id, channel_filter_fn *fn)  channel_register_filter(int id, channel_filter_fn *fn)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_filter: %d: bad id", id);                  log("channel_register_filter: %d: bad id", id);
                 return;                  return;
Line 651 
Line 647 
     int extusage, int nonblock, u_int window_max)      int extusage, int nonblock, u_int window_max)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL || c->type != SSH_CHANNEL_LARVAL)          if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
                 fatal("channel_activate for non-larval channel %d.", id);                  fatal("channel_activate for non-larval channel %d.", id);
         channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);          channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
Line 712 
Line 707 
                         FD_SET(c->wfd, writeset);                          FD_SET(c->wfd, writeset);
                 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {                  } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
                         if (CHANNEL_EFD_OUTPUT_ACTIVE(c))                          if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
                                debug2("channel %d: obuf_empty delayed efd %d/(%d)",                                 debug2("channel %d: obuf_empty delayed efd %d/(%d)",
                                    c->self, c->efd, buffer_len(&c->extended));                                     c->self, c->efd, buffer_len(&c->extended));
                         else                          else
                                 chan_obuf_empty(c);                                  chan_obuf_empty(c);
                 }                  }
Line 822 
Line 817 
 channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)  channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
         int ret = x11_open_helper(&c->output);          int ret = x11_open_helper(&c->output);
   
         if (ret == 1) {          if (ret == 1) {
                 /* Start normal processing for the channel. */                  /* Start normal processing for the channel. */
                 c->type = SSH_CHANNEL_OPEN;                  c->type = SSH_CHANNEL_OPEN;
Line 874 
Line 868 
 static int  static int
 channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)  channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
         char *p, *host;          u_char *p, *host;
         int len, have, i, found;          int len, have, i, found;
         char username[256];          char username[256];
         struct {          struct {
Line 1403 
Line 1397 
 channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)  channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
         int len;          int len;
   
         /* Send buffered output data to the socket. */          /* Send buffered output data to the socket. */
         if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {          if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
                 len = write(c->sock, buffer_ptr(&c->output),                  len = write(c->sock, buffer_ptr(&c->output),
Line 1481 
Line 1474 
 channel_handler_init(void)  channel_handler_init(void)
 {  {
         int i;          int i;
   
         for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {          for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
                 channel_pre[i] = NULL;                  channel_pre[i] = NULL;
                 channel_post[i] = NULL;                  channel_post[i] = NULL;
Line 1581 
Line 1573 
 void  void
 channel_output_poll(void)  channel_output_poll(void)
 {  {
           int len, i;
         Channel *c;          Channel *c;
         int i;  
         u_int len;  
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 c = channels[i];                  c = channels[i];
Line 1650 
Line 1641 
                          * hack for extended data: delay EOF if EFD still in use.                           * hack for extended data: delay EOF if EFD still in use.
                          */                           */
                         if (CHANNEL_EFD_INPUT_ACTIVE(c))                          if (CHANNEL_EFD_INPUT_ACTIVE(c))
                                debug2("channel %d: ibuf_empty delayed efd %d/(%d)",                                 debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
                                    c->self, c->efd, buffer_len(&c->extended));                                     c->self, c->efd, buffer_len(&c->extended));
                         else                          else
                                 chan_ibuf_empty(c);                                  chan_ibuf_empty(c);
                 }                  }
Line 1661 
Line 1652 
                     c->remote_window > 0 &&                      c->remote_window > 0 &&
                     (len = buffer_len(&c->extended)) > 0 &&                      (len = buffer_len(&c->extended)) > 0 &&
                     c->extended_usage == CHAN_EXTENDED_READ) {                      c->extended_usage == CHAN_EXTENDED_READ) {
                         debug2("channel %d: rwin %u elen %u euse %d",                          debug2("channel %d: rwin %d elen %d euse %d",
                             c->self, c->remote_window, buffer_len(&c->extended),                              c->self, c->remote_window, buffer_len(&c->extended),
                             c->extended_usage);                              c->extended_usage);
                         if (len > c->remote_window)                          if (len > c->remote_window)
Line 1731 
Line 1722 
 channel_input_extended_data(int type, u_int32_t seq, void *ctxt)  channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
 {  {
         int id;          int id;
           int tcode;
         char *data;          char *data;
         u_int data_len, tcode;          u_int data_len;
         Channel *c;          Channel *c;
   
         /* Get the channel number and verify it. */          /* Get the channel number and verify it. */
Line 1887 
Line 1879 
                         c->confirm(c->self, NULL);                          c->confirm(c->self, NULL);
                         debug2("callback done");                          debug2("callback done");
                 }                  }
                 debug("channel %d: open confirm rwindow %u rmax %u", c->self,                  debug("channel %d: open confirm rwindow %d rmax %d", c->self,
                     c->remote_window, c->remote_maxpacket);                      c->remote_window, c->remote_maxpacket);
         }          }
         packet_check_eom();          packet_check_eom();
Line 1944 
Line 1936 
 channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)  channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 {  {
         Channel *c;          Channel *c;
         int id;          int id, adjust;
         u_int adjust;  
   
         if (!compat20)          if (!compat20)
                 return;                  return;
Line 1961 
Line 1952 
         }          }
         adjust = packet_get_int();          adjust = packet_get_int();
         packet_check_eom();          packet_check_eom();
         debug2("channel %d: rcvd adjust %u", id, adjust);          debug2("channel %d: rcvd adjust %d", id, adjust);
         c->remote_window += adjust;          c->remote_window += adjust;
 }  }
   
Line 1991 
Line 1982 
                 c->remote_id = remote_id;                  c->remote_id = remote_id;
         }          }
         if (c == NULL) {          if (c == NULL) {
                 xfree(originator_string);  
                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);                  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                 packet_put_int(remote_id);                  packet_put_int(remote_id);
                 packet_send();                  packet_send();
Line 2017 
Line 2007 
         struct addrinfo hints, *ai, *aitop;          struct addrinfo hints, *ai, *aitop;
         const char *host;          const char *host;
         char ntop[NI_MAXHOST], strport[NI_MAXSERV];          char ntop[NI_MAXHOST], strport[NI_MAXSERV];
           struct linger linger;
   
         success = 0;          success = 0;
         host = (type == SSH_CHANNEL_RPORT_LISTENER) ?          host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
Line 2059 
Line 2050 
                         continue;                          continue;
                 }                  }
                 /*                  /*
                  * Set socket options.                   * Set socket options.  We would like the socket to disappear
                  * Allow local port reuse in TIME_WAIT.                   * as soon as it has been closed for whatever reason.
                  */                   */
                 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,                  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
                     sizeof(on)) == -1)                  linger.l_onoff = 1;
                         error("setsockopt SO_REUSEADDR: %s", strerror(errno));                  linger.l_linger = 5;
                   setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
                 debug("Local forwarding listening on %s port %s.", ntop, strport);                  debug("Local forwarding listening on %s port %s.", ntop, strport);
   
                 /* Bind the socket to the address. */                  /* Bind the socket to the address. */
Line 2270 
Line 2261 
                 }                  }
                 sock = socket(ai->ai_family, SOCK_STREAM, 0);                  sock = socket(ai->ai_family, SOCK_STREAM, 0);
                 if (sock < 0) {                  if (sock < 0) {
                         if (ai->ai_next == NULL)                          error("socket: %.100s", strerror(errno));
                                 error("socket: %.100s", strerror(errno));  
                         else  
                                 verbose("socket: %.100s", strerror(errno));  
                         continue;                          continue;
                 }                  }
                 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)                  if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
Line 2339 
Line 2327 
   
 /*  /*
  * Creates an internet domain socket for listening for X11 connections.   * Creates an internet domain socket for listening for X11 connections.
  * Returns 0 and a suitable display number for the DISPLAY variable   * Returns a suitable display number for the DISPLAY variable, or -1 if
  * stored in display_numberp , or -1 if an error occurs.   * an error occurs.
  */   */
 int  int
 x11_create_display_inet(int x11_display_offset, int x11_use_localhost,  x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
     int single_connection, u_int *display_numberp)      int single_connection)
 {  {
         Channel *nc = NULL;          Channel *nc = NULL;
         int display_number, sock;          int display_number, sock;
Line 2377 
Line 2365 
                         if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {                          if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
                                 debug("bind port %d: %.100s", port, strerror(errno));                                  debug("bind port %d: %.100s", port, strerror(errno));
                                 close(sock);                                  close(sock);
   
                                 if (ai->ai_next)  
                                         continue;  
   
                                 for (n = 0; n < num_socks; n++) {                                  for (n = 0; n < num_socks; n++) {
                                         close(socks[n]);                                          close(socks[n]);
                                 }                                  }
Line 2420 
Line 2404 
         }          }
   
         /* Return the display number for the DISPLAY environment variable. */          /* Return the display number for the DISPLAY environment variable. */
         *display_numberp = display_number;          return display_number;
         return (0);  
 }  }
   
 static int  static int
Line 2576 
Line 2559 
                 /* Send refusal to the remote host. */                  /* Send refusal to the remote host. */
                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);                  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                 packet_put_int(remote_id);                  packet_put_int(remote_id);
                 xfree(remote_host);  
         } else {          } else {
                 /* Send a confirmation to the remote host. */                  /* Send a confirmation to the remote host. */
                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);                  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
Line 2591 
Line 2573 
 deny_input_open(int type, u_int32_t seq, void *ctxt)  deny_input_open(int type, u_int32_t seq, void *ctxt)
 {  {
         int rchan = packet_get_int();          int rchan = packet_get_int();
   
         switch (type) {          switch (type) {
         case SSH_SMSG_AGENT_OPEN:          case SSH_SMSG_AGENT_OPEN:
                 error("Warning: ssh server tried agent forwarding.");                  error("Warning: ssh server tried agent forwarding.");
Line 2689 
Line 2670 
         packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);          packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   }
   
   /*
    * Returns the name of the forwarded authentication socket.  Returns NULL if
    * there is no forwarded authentication socket.  The returned value points to
    * a static buffer.
    */
   
   char *
   auth_get_socket_name(void)
   {
           return auth_sock_name;
   }
   
   /* removes the agent forwarding socket */
   
   void
   auth_sock_cleanup_proc(void *_pw)
   {
           struct passwd *pw = _pw;
   
           if (auth_sock_name) {
                   temporarily_use_uid(pw);
                   unlink(auth_sock_name);
                   rmdir(auth_sock_dir);
                   auth_sock_name = NULL;
                   restore_uid();
           }
   }
   
   /*
    * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
    * This starts forwarding authentication requests.
    */
   
   int
   auth_input_request_forwarding(struct passwd * pw)
   {
           Channel *nc;
           int sock;
           struct sockaddr_un sunaddr;
   
           if (auth_get_socket_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.%d",
                    auth_sock_dir, (int) 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;
 }  }
   
 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */  /* This is called to process an SSH_SMSG_AGENT_OPEN message. */

Legend:
Removed from v.1.172.2.5  
changed lines
  Added in v.1.173