[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.200 and 1.200.2.1

version 1.200, 2004/01/19 09:24:21 version 1.200.2.1, 2004/08/19 04:13:26
Line 68 
Line 68 
  * Size of the channel array.  All slots of the array must always be   * Size of the channel array.  All slots of the array must always be
  * initialized (at least the type field); unused slots set to NULL   * initialized (at least the type field); unused slots set to NULL
  */   */
 static int channels_alloc = 0;  static u_int channels_alloc = 0;
   
 /*  /*
  * Maximum file descriptor value used in any of the channels.  This is   * Maximum file descriptor value used in any of the channels.  This is
Line 141 
Line 141 
 {  {
         Channel *c;          Channel *c;
   
         if (id < 0 || id >= channels_alloc) {          if (id < 0 || (u_int)id >= channels_alloc) {
                 logit("channel_lookup: %d: bad id", id);                  logit("channel_lookup: %d: bad id", id);
                 return NULL;                  return NULL;
         }          }
Line 172 
Line 172 
         c->rfd = rfd;          c->rfd = rfd;
         c->wfd = wfd;          c->wfd = wfd;
         c->sock = (rfd == wfd) ? rfd : -1;          c->sock = (rfd == wfd) ? rfd : -1;
           c->ctl_fd = -1; /* XXX: set elsewhere */
         c->efd = efd;          c->efd = efd;
         c->extended_usage = extusage;          c->extended_usage = extusage;
   
Line 207 
Line 208 
 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)      u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
 {  {
         int i, found;          int found;
           u_int i;
         Channel *c;          Channel *c;
   
         /* Do initial allocation if this is the first call. */          /* Do initial allocation if this is the first call. */
Line 221 
Line 223 
         for (found = -1, i = 0; i < channels_alloc; i++)          for (found = -1, i = 0; i < channels_alloc; i++)
                 if (channels[i] == NULL) {                  if (channels[i] == NULL) {
                         /* Found a free slot. */                          /* Found a free slot. */
                         found = i;                          found = (int)i;
                         break;                          break;
                 }                  }
         if (found == -1) {          if (found < 0) {
                 /* 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;
                 if (channels_alloc > 10000)                  if (channels_alloc > 10000)
Line 262 
Line 264 
         c->single_connection = 0;          c->single_connection = 0;
         c->detach_user = NULL;          c->detach_user = NULL;
         c->confirm = NULL;          c->confirm = NULL;
           c->confirm_ctx = NULL;
         c->input_filter = NULL;          c->input_filter = NULL;
         debug("channel %d: new [%s]", found, remote_name);          debug("channel %d: new [%s]", found, remote_name);
         return c;          return c;
Line 270 
Line 273 
 static int  static int
 channel_find_maxfd(void)  channel_find_maxfd(void)
 {  {
         int i, max = 0;          u_int i;
           int max = 0;
         Channel *c;          Channel *c;
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
Line 303 
Line 307 
 static void  static void
 channel_close_fds(Channel *c)  channel_close_fds(Channel *c)
 {  {
         debug3("channel %d: close_fds r %d w %d e %d",          debug3("channel %d: close_fds r %d w %d e %d c %d",
             c->self, c->rfd, c->wfd, c->efd);              c->self, c->rfd, c->wfd, c->efd, c->ctl_fd);
   
         channel_close_fd(&c->sock);          channel_close_fd(&c->sock);
           channel_close_fd(&c->ctl_fd);
         channel_close_fd(&c->rfd);          channel_close_fd(&c->rfd);
         channel_close_fd(&c->wfd);          channel_close_fd(&c->wfd);
         channel_close_fd(&c->efd);          channel_close_fd(&c->efd);
Line 318 
Line 323 
 channel_free(Channel *c)  channel_free(Channel *c)
 {  {
         char *s;          char *s;
         int i, n;          u_int i, n;
   
         for (n = 0, i = 0; i < channels_alloc; i++)          for (n = 0, i = 0; i < channels_alloc; i++)
                 if (channels[i])                  if (channels[i])
                         n++;                          n++;
         debug("channel %d: free: %s, nchannels %d", c->self,          debug("channel %d: free: %s, nchannels %u", c->self,
             c->remote_name ? c->remote_name : "???", n);              c->remote_name ? c->remote_name : "???", n);
   
         s = channel_open_message();          s = channel_open_message();
Line 332 
Line 337 
   
         if (c->sock != -1)          if (c->sock != -1)
                 shutdown(c->sock, SHUT_RDWR);                  shutdown(c->sock, SHUT_RDWR);
           if (c->ctl_fd != -1)
                   shutdown(c->ctl_fd, SHUT_RDWR);
         channel_close_fds(c);          channel_close_fds(c);
         buffer_free(&c->input);          buffer_free(&c->input);
         buffer_free(&c->output);          buffer_free(&c->output);
Line 347 
Line 354 
 void  void
 channel_free_all(void)  channel_free_all(void)
 {  {
         int i;          u_int i;
   
         for (i = 0; i < channels_alloc; i++)          for (i = 0; i < channels_alloc; i++)
                 if (channels[i] != NULL)                  if (channels[i] != NULL)
Line 362 
Line 369 
 void  void
 channel_close_all(void)  channel_close_all(void)
 {  {
         int i;          u_int i;
   
         for (i = 0; i < channels_alloc; i++)          for (i = 0; i < channels_alloc; i++)
                 if (channels[i] != NULL)                  if (channels[i] != NULL)
Line 376 
Line 383 
 void  void
 channel_stop_listening(void)  channel_stop_listening(void)
 {  {
         int i;          u_int i;
         Channel *c;          Channel *c;
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
Line 433 
Line 440 
 int  int
 channel_still_open(void)  channel_still_open(void)
 {  {
         int i;          u_int i;
         Channel *c;          Channel *c;
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
Line 476 
Line 483 
 int  int
 channel_find_open(void)  channel_find_open(void)
 {  {
         int i;          u_int i;
         Channel *c;          Channel *c;
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 c = channels[i];                  c = channels[i];
                 if (c == NULL)                  if (c == NULL || c->remote_id < 0)
                         continue;                          continue;
                 switch (c->type) {                  switch (c->type) {
                 case SSH_CHANNEL_CLOSED:                  case SSH_CHANNEL_CLOSED:
Line 524 
Line 531 
         Buffer buffer;          Buffer buffer;
         Channel *c;          Channel *c;
         char buf[1024], *cp;          char buf[1024], *cp;
         int i;          u_int i;
   
         buffer_init(&buffer);          buffer_init(&buffer);
         snprintf(buf, sizeof buf, "The following connections are open:\r\n");          snprintf(buf, sizeof buf, "The following connections are open:\r\n");
Line 549 
Line 556 
                 case SSH_CHANNEL_X11_OPEN:                  case SSH_CHANNEL_X11_OPEN:
                 case SSH_CHANNEL_INPUT_DRAINING:                  case SSH_CHANNEL_INPUT_DRAINING:
                 case SSH_CHANNEL_OUTPUT_DRAINING:                  case SSH_CHANNEL_OUTPUT_DRAINING:
                         snprintf(buf, sizeof buf, "  #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",                          snprintf(buf, sizeof buf,
                               "  #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n",
                             c->self, c->remote_name,                              c->self, c->remote_name,
                             c->type, c->remote_id,                              c->type, c->remote_id,
                             c->istate, buffer_len(&c->input),                              c->istate, buffer_len(&c->input),
                             c->ostate, buffer_len(&c->output),                              c->ostate, buffer_len(&c->output),
                             c->rfd, c->wfd);                              c->rfd, c->wfd, c->ctl_fd);
                         buffer_append(&buffer, buf, strlen(buf));                          buffer_append(&buffer, buf, strlen(buf));
                         continue;                          continue;
                 default:                  default:
Line 595 
Line 603 
                 logit("channel_request_start: %d: unknown channel id", id);                  logit("channel_request_start: %d: unknown channel id", id);
                 return;                  return;
         }          }
         debug2("channel %d: request %s", id, service) ;          debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
         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);
         packet_put_char(wantconfirm);          packet_put_char(wantconfirm);
 }  }
 void  void
 channel_register_confirm(int id, channel_callback_fn *fn)  channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
 {  {
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
Line 611 
Line 619 
                 return;                  return;
         }          }
         c->confirm = fn;          c->confirm = fn;
           c->confirm_ctx = ctx;
 }  }
 void  void
 channel_register_cleanup(int id, channel_callback_fn *fn)  channel_register_cleanup(int id, channel_callback_fn *fn)
Line 728 
Line 737 
                     buffer_len(&c->extended) < c->remote_window)                      buffer_len(&c->extended) < c->remote_window)
                         FD_SET(c->efd, readset);                          FD_SET(c->efd, readset);
         }          }
           /* XXX: What about efd? races? */
           if (compat20 && c->ctl_fd != -1 &&
               c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN)
                   FD_SET(c->ctl_fd, readset);
 }  }
   
 static void  static void
Line 1030 
Line 1043 
         buffer_get(&c->input, (char *)&dest_port, 2);          buffer_get(&c->input, (char *)&dest_port, 2);
         dest_addr[addrlen] = '\0';          dest_addr[addrlen] = '\0';
         if (s5_req.atyp == SSH_SOCKS5_DOMAIN)          if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
                 strlcpy(c->path, dest_addr, sizeof(c->path));                  strlcpy(c->path, (char *)dest_addr, sizeof(c->path));
         else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)          else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
                 return -1;                  return -1;
         c->host_port = ntohs(dest_port);          c->host_port = ntohs(dest_port);
Line 1476 
Line 1489 
         return 1;          return 1;
 }  }
 static int  static int
   channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
   {
           char buf[16];
           int len;
   
           /* Monitor control fd to detect if the slave client exits */
           if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) {
                   len = read(c->ctl_fd, buf, sizeof(buf));
                   if (len < 0 && (errno == EINTR || errno == EAGAIN))
                           return 1;
                   if (len <= 0) {
                           debug2("channel %d: ctl read<=0", c->self);
                           if (c->type != SSH_CHANNEL_OPEN) {
                                   debug2("channel %d: not open", c->self);
                                   chan_mark_dead(c);
                                   return -1;
                           } else {
                                   chan_read_failed(c);
                                   chan_write_failed(c);
                           }
                           return -1;
                   } else
                           fatal("%s: unexpected data on ctl fd", __func__);
           }
           return 1;
   }
   static int
 channel_check_window(Channel *c)  channel_check_window(Channel *c)
 {  {
         if (c->type == SSH_CHANNEL_OPEN &&          if (c->type == SSH_CHANNEL_OPEN &&
Line 1505 
Line 1545 
         if (!compat20)          if (!compat20)
                 return;                  return;
         channel_handle_efd(c, readset, writeset);          channel_handle_efd(c, readset, writeset);
           channel_handle_ctl(c, readset, writeset);
         channel_check_window(c);          channel_check_window(c);
 }  }
   
Line 1629 
Line 1670 
 channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)  channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
 {  {
         static int did_init = 0;          static int did_init = 0;
         int i;          u_int i;
         Channel *c;          Channel *c;
   
         if (!did_init) {          if (!did_init) {
Line 1652 
Line 1693 
  */   */
 void  void
 channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,  channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
     int *nallocp, int rekeying)      u_int *nallocp, int rekeying)
 {  {
         int n;          u_int n, sz;
         u_int sz;  
   
         n = MAX(*maxfdp, channel_max_fd);          n = MAX(*maxfdp, channel_max_fd);
   
Line 1691 
Line 1731 
 channel_output_poll(void)  channel_output_poll(void)
 {  {
         Channel *c;          Channel *c;
         int i;          u_int i, len;
         u_int len;  
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 c = channels[i];                  c = channels[i];
Line 2005 
Line 2044 
                 c->remote_maxpacket = packet_get_int();                  c->remote_maxpacket = packet_get_int();
                 if (c->confirm) {                  if (c->confirm) {
                         debug2("callback start");                          debug2("callback start");
                         c->confirm(c->self, NULL);                          c->confirm(c->self, c->confirm_ctx);
                         debug2("callback done");                          debug2("callback done");
                 }                  }
                 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,                  debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
Line 2218 
Line 2257 
         return success;          return success;
 }  }
   
   int
   channel_cancel_rport_listener(const char *host, u_short port)
   {
           u_int i;
           int found = 0;
   
           for(i = 0; i < channels_alloc; i++) {
                   Channel *c = channels[i];
   
                   if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
                       strncmp(c->path, host, sizeof(c->path)) == 0 &&
                       c->listening_port == port) {
                           debug2("%s: close clannel %d", __func__, i);
                           channel_free(c);
                           found = 1;
                   }
           }
   
           return (found);
   }
   
 /* protocol local port fwd, used by ssh (and sshd in v1) */  /* protocol local port fwd, used by ssh (and sshd in v1) */
 int  int
 channel_setup_local_fwd_listener(u_short listen_port,  channel_setup_local_fwd_listener(u_short listen_port,
Line 2295 
Line 2355 
 }  }
   
 /*  /*
    * Request cancellation of remote forwarding of connection host:port from
    * local side.
    */
   void
   channel_request_rforward_cancel(u_short port)
   {
           int i;
           const char *address_to_bind = "0.0.0.0";
   
           if (!compat20)
                   return;
   
           for (i = 0; i < num_permitted_opens; i++) {
                   if (permitted_opens[i].host_to_connect != NULL &&
                       permitted_opens[i].listen_port == port)
                           break;
           }
           if (i >= num_permitted_opens) {
                   debug("%s: requested forward not found", __func__);
                   return;
           }
           packet_start(SSH2_MSG_GLOBAL_REQUEST);
           packet_put_cstring("cancel-tcpip-forward");
           packet_put_char(0);
           packet_put_cstring(address_to_bind);
           packet_put_int(port);
           packet_send();
   
           permitted_opens[i].listen_port = 0;
           permitted_opens[i].port_to_connect = 0;
           free(permitted_opens[i].host_to_connect);
           permitted_opens[i].host_to_connect = NULL;
   }
   
   /*
  * This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates   * This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
  * listening for the port, and sends back a success reply (or disconnect   * listening for the port, and sends back a success reply (or disconnect
  * message if there was an error).  This never returns if there was an error.   * message if there was an error).  This never returns if there was an error.
Line 2361 
Line 2456 
         int i;          int i;
   
         for (i = 0; i < num_permitted_opens; i++)          for (i = 0; i < num_permitted_opens; i++)
                 xfree(permitted_opens[i].host_to_connect);                  if (permitted_opens[i].host_to_connect != NULL)
                           xfree(permitted_opens[i].host_to_connect);
         num_permitted_opens = 0;          num_permitted_opens = 0;
   
 }  }
Line 2401 
Line 2497 
                                 verbose("socket: %.100s", strerror(errno));                                  verbose("socket: %.100s", strerror(errno));
                         continue;                          continue;
                 }                  }
                 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)                  if (set_nonblock(sock) == -1)
                         fatal("connect_to: F_SETFL: %s", strerror(errno));                          fatal("%s: set_nonblock(%d)", __func__, sock);
                 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&                  if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
                     errno != EINPROGRESS) {                      errno != EINPROGRESS) {
                         error("connect_to %.100s port %s: %.100s", ntop, strport,                          error("connect_to %.100s port %s: %.100s", ntop, strport,
Line 2429 
Line 2525 
         int i;          int i;
   
         for (i = 0; i < num_permitted_opens; i++)          for (i = 0; i < num_permitted_opens; i++)
                 if (permitted_opens[i].listen_port == listen_port)                  if (permitted_opens[i].host_to_connect != NULL &&
                       permitted_opens[i].listen_port == listen_port)
                         return connect_to(                          return connect_to(
                             permitted_opens[i].host_to_connect,                              permitted_opens[i].host_to_connect,
                             permitted_opens[i].port_to_connect);                              permitted_opens[i].port_to_connect);
Line 2447 
Line 2544 
         permit = all_opens_permitted;          permit = all_opens_permitted;
         if (!permit) {          if (!permit) {
                 for (i = 0; i < num_permitted_opens; i++)                  for (i = 0; i < num_permitted_opens; i++)
                         if (permitted_opens[i].port_to_connect == port &&                          if (permitted_opens[i].host_to_connect != NULL &&
                               permitted_opens[i].port_to_connect == port &&
                             strcmp(permitted_opens[i].host_to_connect, host) == 0)                              strcmp(permitted_opens[i].host_to_connect, host) == 0)
                                 permit = 1;                                  permit = 1;
   
Line 2460 
Line 2558 
         return connect_to(host, port);          return connect_to(host, port);
 }  }
   
   void
   channel_send_window_changes(void)
   {
           u_int i;
           struct winsize ws;
   
           for (i = 0; i < channels_alloc; i++) {
                   if (channels[i] == NULL ||
                       channels[i]->type != SSH_CHANNEL_OPEN)
                           continue;
                   if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
                           continue;
                   channel_request_start(i, "window-change", 0);
                   packet_put_int(ws.ws_col);
                   packet_put_int(ws.ws_row);
                   packet_put_int(ws.ws_xpixel);
                   packet_put_int(ws.ws_ypixel);
                   packet_send();
           }
   }
   
 /* -- X11 forwarding */  /* -- X11 forwarding */
   
 /*  /*
Line 2498 
Line 2617 
                             ai->ai_protocol);                              ai->ai_protocol);
                         if (sock < 0) {                          if (sock < 0) {
                                 error("socket: %.100s", strerror(errno));                                  error("socket: %.100s", strerror(errno));
                                   freeaddrinfo(aitop);
                                 return -1;                                  return -1;
                         }                          }
                         if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {                          if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
Line 2749 
Line 2869 
         char *new_data;          char *new_data;
         int screen_number;          int screen_number;
         const char *cp;          const char *cp;
         u_int32_t rand = 0;          u_int32_t rnd = 0;
   
         cp = getenv("DISPLAY");          cp = getenv("DISPLAY");
         if (cp)          if (cp)
Line 2774 
Line 2894 
                 if (sscanf(data + 2 * i, "%2x", &value) != 1)                  if (sscanf(data + 2 * i, "%2x", &value) != 1)
                         fatal("x11_request_forwarding: bad authentication data: %.100s", data);                          fatal("x11_request_forwarding: bad authentication data: %.100s", data);
                 if (i % 4 == 0)                  if (i % 4 == 0)
                         rand = arc4random();                          rnd = arc4random();
                 x11_saved_data[i] = value;                  x11_saved_data[i] = value;
                 x11_fake_data[i] = rand & 0xff;                  x11_fake_data[i] = rnd & 0xff;
                 rand >>= 8;                  rnd >>= 8;
         }          }
         x11_saved_data_len = data_len;          x11_saved_data_len = data_len;
         x11_fake_data_len = data_len;          x11_fake_data_len = data_len;

Legend:
Removed from v.1.200  
changed lines
  Added in v.1.200.2.1