[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.112 and 1.113

version 1.112, 2001/05/04 14:34:34 version 1.113, 2001/05/04 23:47:33
Line 72 
Line 72 
  * Pointer to an array containing all allocated channels.  The array is   * Pointer to an array containing all allocated channels.  The array is
  * dynamically extended as needed.   * dynamically extended as needed.
  */   */
 static Channel *channels = NULL;  static Channel **channels = NULL;
   
 /*  /*
  * 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 are marked with type   * initialized (at least the type field); unused slots set to NULL
  * SSH_CHANNEL_FREE.  
  */   */
 static int channels_alloc = 0;  static 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
  * updated in channel_allocate.   * updated in channel_new.
  */   */
 static int channel_max_fd = 0;  static int channel_max_fd = 0;
   
Line 150 
Line 149 
 channel_lookup(int id)  channel_lookup(int id)
 {  {
         Channel *c;          Channel *c;
   
         if (id < 0 || id > channels_alloc) {          if (id < 0 || id > channels_alloc) {
                 log("channel_lookup: %d: bad id", id);                  log("channel_lookup: %d: bad id", id);
                 return NULL;                  return NULL;
         }          }
         c = &channels[id];          c = channels[id];
         if (c->type == SSH_CHANNEL_FREE) {          if (c == NULL) {
                 log("channel_lookup: %d: bad id: channel free", id);                  log("channel_lookup: %d: bad id: channel free", id);
                 return NULL;                  return NULL;
         }          }
Line 212 
Line 212 
  * remote_name to be freed.   * remote_name to be freed.
  */   */
   
 int  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,
     int window, int maxpack, int extusage, char *remote_name, int nonblock)      int window, int maxpack, int extusage, char *remote_name, int nonblock)
 {  {
Line 223 
Line 223 
         if (channels_alloc == 0) {          if (channels_alloc == 0) {
                 chan_init();                  chan_init();
                 channels_alloc = 10;                  channels_alloc = 10;
                 channels = xmalloc(channels_alloc * sizeof(Channel));                  channels = xmalloc(channels_alloc * sizeof(Channel *));
                 for (i = 0; i < channels_alloc; i++)                  for (i = 0; i < channels_alloc; i++)
                         channels[i].type = SSH_CHANNEL_FREE;                          channels[i] = NULL;
                 /*                  /*
                  * Kludge: arrange a call to channel_stop_listening if we                   * Kludge: arrange a call to channel_stop_listening if we
                  * terminate with fatal().                   * terminate with fatal().
Line 234 
Line 234 
         }          }
         /* Try to find a free slot where to put the new channel. */          /* Try to find a free slot where to put the new channel. */
         for (found = -1, i = 0; i < channels_alloc; i++)          for (found = -1, i = 0; i < channels_alloc; i++)
                 if (channels[i].type == SSH_CHANNEL_FREE) {                  if (channels[i] == NULL) {
                         /* Found a free slot. */                          /* Found a free slot. */
                         found = i;                          found = i;
                         break;                          break;
Line 244 
Line 244 
                 found = channels_alloc;                  found = channels_alloc;
                 channels_alloc += 10;                  channels_alloc += 10;
                 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++)
                         channels[i].type = SSH_CHANNEL_FREE;                          channels[i] = NULL;
         }          }
         /* Initialize and return new channel number. */          /* Initialize and return new channel. */
         c = &channels[found];          c = channels[found] = xmalloc(sizeof(Channel));
         buffer_init(&c->input);          buffer_init(&c->input);
         buffer_init(&c->output);          buffer_init(&c->output);
         buffer_init(&c->extended);          buffer_init(&c->extended);
Line 272 
Line 272 
         c->dettach_user = NULL;          c->dettach_user = 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 found;          return c;
 }  }
 /* old interface XXX */  
 int  
 channel_allocate(int type, int sock, char *remote_name)  
 {  
         return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name, 1);  
 }  
   
   
 /* Close all channel fd/socket. */  /* Close all channel fd/socket. */
   
 void  void
Line 308 
Line 301 
 /* Free the channel and close its fd/socket. */  /* Free the channel and close its fd/socket. */
   
 void  void
 channel_free(int id)  channel_free(Channel *c)
 {  {
         Channel *c = channel_lookup(id);          char *s;
         char *s = channel_open_message();  
   
         if (c == NULL)          s = channel_open_message();
                 packet_disconnect("channel free: bad local channel %d", id);          debug("channel_free: channel %d: status: %s", c->self, s);
         debug("channel_free: channel %d: status: %s", id, s);  
         xfree(s);          xfree(s);
   
         if (c->dettach_user != NULL) {          if (c->dettach_user != NULL) {
                 debug("channel_free: channel %d: dettaching channel user", id);                  debug("channel_free: channel %d: dettaching channel user", c->self);
                 c->dettach_user(c->self, NULL);                  c->dettach_user(c->self, NULL);
         }          }
         if (c->sock != -1)          if (c->sock != -1)
Line 328 
Line 319 
         buffer_free(&c->input);          buffer_free(&c->input);
         buffer_free(&c->output);          buffer_free(&c->output);
         buffer_free(&c->extended);          buffer_free(&c->extended);
         c->type = SSH_CHANNEL_FREE;  
         if (c->remote_name) {          if (c->remote_name) {
                 xfree(c->remote_name);                  xfree(c->remote_name);
                 c->remote_name = NULL;                  c->remote_name = NULL;
         }          }
           channels[c->self] = NULL;
           xfree(c);
 }  }
   
 /*  /*
Line 428 
Line 420 
 channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)  channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
         if (buffer_len(&c->output) == 0)          if (buffer_len(&c->output) == 0)
                 channel_free(c->self);                  chan_mark_dead(c);
         else          else
                 FD_SET(c->sock, writeset);                  FD_SET(c->sock, writeset);
 }  }
Line 640 
Line 632 
                 break;                  break;
         }          }
         if (ret < 0) {          if (ret < 0) {
                 channel_free(c->self);                  chan_mark_dead(c);
         } else if (ret == 0) {          } else if (ret == 0) {
                 debug2("channel %d: pre_dynamic: need more", c->self);                  debug2("channel %d: pre_dynamic: need more", c->self);
                 /* need more */                  /* need more */
Line 656 
Line 648 
 void  void
 channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)  channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
           Channel *nc;
         struct sockaddr addr;          struct sockaddr addr;
         int newsock, newch, oldch;          int newsock;
         socklen_t addrlen;          socklen_t addrlen;
         char buf[16384], *remote_ipaddr;          char buf[16384], *remote_ipaddr;
         int remote_port;          int remote_port;
Line 675 
Line 668 
                 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",                  snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
                     remote_ipaddr, remote_port);                      remote_ipaddr, remote_port);
   
                 oldch = c->self;                  nc = channel_new("accepted x11 socket",
                 newch = channel_new("x11",  
                     SSH_CHANNEL_OPENING, newsock, newsock, -1,                      SSH_CHANNEL_OPENING, newsock, newsock, -1,
                     c->local_window_max, c->local_maxpacket,                      c->local_window_max, c->local_maxpacket,
                     0, xstrdup(buf), 1);                      0, xstrdup(buf), 1);
                 c = channel_lookup(oldch);                  if (nc == NULL) {
                           close(newsock);
                           xfree(remote_ipaddr);
                           return;
                   }
                 if (compat20) {                  if (compat20) {
                         packet_start(SSH2_MSG_CHANNEL_OPEN);                          packet_start(SSH2_MSG_CHANNEL_OPEN);
                         packet_put_cstring("x11");                          packet_put_cstring("x11");
                         packet_put_int(newch);                          packet_put_int(nc->self);
                         packet_put_int(c->local_window_max);                          packet_put_int(c->local_window_max);
                         packet_put_int(c->local_maxpacket);                          packet_put_int(c->local_maxpacket);
                         /* originator ipaddr and port */                          /* originator ipaddr and port */
Line 697 
Line 693 
                         packet_send();                          packet_send();
                 } else {                  } else {
                         packet_start(SSH_SMSG_X11_OPEN);                          packet_start(SSH_SMSG_X11_OPEN);
                         packet_put_int(newch);                          packet_put_int(nc->self);
                         if (have_hostname_in_open)                          if (have_hostname_in_open)
                                 packet_put_string(buf, strlen(buf));                                  packet_put_string(buf, strlen(buf));
                         packet_send();                          packet_send();
Line 764 
Line 760 
 {  {
         Channel *nc;          Channel *nc;
         struct sockaddr addr;          struct sockaddr addr;
         int newsock, newch, nextstate, oldch;          int newsock, nextstate;
         socklen_t addrlen;          socklen_t addrlen;
         char *rtype;          char *rtype;
   
Line 784 
Line 780 
                         error("accept: %.100s", strerror(errno));                          error("accept: %.100s", strerror(errno));
                         return;                          return;
                 }                  }
                 oldch = c->self;                  nc = channel_new(rtype,
                 newch = channel_new(rtype,  
                     nextstate, newsock, newsock, -1,                      nextstate, newsock, newsock, -1,
                     c->local_window_max, c->local_maxpacket,                      c->local_window_max, c->local_maxpacket,
                     0, xstrdup(rtype), 1);                      0, xstrdup(rtype), 1);
   
                 c = channel_lookup(oldch);  
                 nc = channel_lookup(newch);  
                 if (nc == NULL) {                  if (nc == NULL) {
                         error("xxx: no new channel:");                          error("channel_post_port_listener: no new channel:");
                           close(newsock);
                         return;                          return;
                 }                  }
                 nc->listening_port = c->listening_port;                  nc->listening_port = c->listening_port;
Line 812 
Line 805 
 void  void
 channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)  channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
 {  {
           Channel *nc;
           int newsock;
         struct sockaddr addr;          struct sockaddr addr;
         int newsock, newch, oldch;  
         socklen_t addrlen;          socklen_t addrlen;
   
         if (FD_ISSET(c->sock, readset)) {          if (FD_ISSET(c->sock, readset)) {
Line 823 
Line 817 
                         error("accept from auth socket: %.100s", strerror(errno));                          error("accept from auth socket: %.100s", strerror(errno));
                         return;                          return;
                 }                  }
                 oldch = c->self;                  nc = channel_new("accepted auth socket",
                 newch = channel_new("accepted auth socket",  
                     SSH_CHANNEL_OPENING, newsock, newsock, -1,                      SSH_CHANNEL_OPENING, newsock, newsock, -1,
                     c->local_window_max, c->local_maxpacket,                      c->local_window_max, c->local_maxpacket,
                     0, xstrdup("accepted auth socket"), 1);                      0, xstrdup("accepted auth socket"), 1);
                 c = channel_lookup(oldch);                  if (nc == NULL) {
                           error("channel_post_auth_listener: channel_new failed");
                           close(newsock);
                   }
                 if (compat20) {                  if (compat20) {
                         packet_start(SSH2_MSG_CHANNEL_OPEN);                          packet_start(SSH2_MSG_CHANNEL_OPEN);
                         packet_put_cstring("auth-agent@openssh.com");                          packet_put_cstring("auth-agent@openssh.com");
                         packet_put_int(newch);                          packet_put_int(nc->self);
                         packet_put_int(c->local_window_max);                          packet_put_int(c->local_window_max);
                         packet_put_int(c->local_maxpacket);                          packet_put_int(c->local_maxpacket);
                 } else {                  } else {
                         packet_start(SSH_SMSG_AGENT_OPEN);                          packet_start(SSH_SMSG_AGENT_OPEN);
                         packet_put_int(newch);                          packet_put_int(nc->self);
                 }                  }
                 packet_send();                  packet_send();
         }          }
Line 881 
Line 877 
                             c->self, c->rfd, len);                              c->self, c->rfd, len);
                         if (c->type != SSH_CHANNEL_OPEN) {                          if (c->type != SSH_CHANNEL_OPEN) {
                                 debug("channel %d: not open", c->self);                                  debug("channel %d: not open", c->self);
                                 channel_free(c->self);                                  chan_mark_dead(c);
                                 return -1;                                  return -1;
                         } else if (compat13) {                          } else if (compat13) {
                                 buffer_consume(&c->output, buffer_len(&c->output));                                  buffer_consume(&c->output, buffer_len(&c->output));
Line 920 
Line 916 
                 if (len <= 0) {                  if (len <= 0) {
                         if (c->type != SSH_CHANNEL_OPEN) {                          if (c->type != SSH_CHANNEL_OPEN) {
                                 debug("channel %d: not open", c->self);                                  debug("channel %d: not open", c->self);
                                 channel_free(c->self);                                  chan_mark_dead(c);
                                 return -1;                                  return -1;
                         } else if (compat13) {                          } else if (compat13) {
                                 buffer_consume(&c->output, buffer_len(&c->output));                                  buffer_consume(&c->output, buffer_len(&c->output));
Line 1138 
Line 1134 
                 did_init = 1;                  did_init = 1;
         }          }
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 c = &channels[i];                  c = channels[i];
                 if (c->type == SSH_CHANNEL_FREE)                  if (c == NULL)
                         continue;                          continue;
                 if (ftab[c->type] == NULL)                  if (ftab[c->type] == NULL)
                         continue;                          continue;
                 (*ftab[c->type])(c, readset, writeset);                  (*ftab[c->type])(c, readset, writeset);
                 c = &channels[i]; /* XXX realloc */  
                 if (chan_is_dead(c)) {                  if (chan_is_dead(c)) {
                         /*                          /*
                          * we have to remove the fd's from the select mask                           * we have to remove the fd's from the select mask
Line 1161 
Line 1156 
                                 if (c->extended_usage == CHAN_EXTENDED_WRITE)                                  if (c->extended_usage == CHAN_EXTENDED_WRITE)
                                         FD_CLR(c->efd, writeset);                                          FD_CLR(c->efd, writeset);
                         }                          }
                         channel_free(c->self);                          channel_free(c);
                 }                  }
         }          }
 }  }
Line 1207 
Line 1202 
         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)
                           continue;
   
                 /* We are only interested in channels that can have buffered incoming data. */                  /* We are only interested in channels that can have buffered incoming data. */
                 if (compat13) {                  if (compat13) {
                         if (c->type != SSH_CHANNEL_OPEN &&                          if (c->type != SSH_CHANNEL_OPEN &&
Line 1391 
Line 1389 
         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->type == SSH_CHANNEL_OPEN) {                  if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
                         if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {                          if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {
                                 debug("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));
Line 1486 
Line 1484 
         if (c->type != SSH_CHANNEL_CLOSED)          if (c->type != SSH_CHANNEL_CLOSED)
                 packet_disconnect("Received close confirmation for "                  packet_disconnect("Received close confirmation for "
                     "non-closed channel %d (type %d).", id, c->type);                      "non-closed channel %d (type %d).", id, c->type);
         channel_free(c->self);          channel_free(c);
 }  }
   
 void  void
Line 1554 
Line 1552 
                         xfree(lang);                          xfree(lang);
         }          }
         /* Free the channel.  This will also close the socket. */          /* Free the channel.  This will also close the socket. */
         channel_free(id);          channel_free(c);
 }  }
   
 void  void
Line 1615 
Line 1613 
 channel_stop_listening()  channel_stop_listening()
 {  {
         int i;          int i;
           Channel *c;
   
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 switch (channels[i].type) {                  c = channels[i];
                 case SSH_CHANNEL_AUTH_SOCKET:                  if (c != NULL) {
                         close(channels[i].sock);                          switch (c->type) {
                         unlink(channels[i].path);                          case SSH_CHANNEL_AUTH_SOCKET:
                         channel_free(i);                                  close(c->sock);
                         break;                                  unlink(c->path);
                 case SSH_CHANNEL_PORT_LISTENER:                                  channel_free(c);
                 case SSH_CHANNEL_RPORT_LISTENER:                                  break;
                 case SSH_CHANNEL_X11_LISTENER:                          case SSH_CHANNEL_PORT_LISTENER:
                         close(channels[i].sock);                          case SSH_CHANNEL_RPORT_LISTENER:
                         channel_free(i);                          case SSH_CHANNEL_X11_LISTENER:
                         break;                                  close(c->sock);
                 default:                                  channel_free(c);
                         break;                                  break;
                           default:
                                   break;
                           }
                 }                  }
         }          }
 }  }
Line 1643 
Line 1646 
 channel_close_all()  channel_close_all()
 {  {
         int i;          int i;
   
         for (i = 0; i < channels_alloc; i++)          for (i = 0; i < channels_alloc; i++)
                 if (channels[i].type != SSH_CHANNEL_FREE)                  if (channels[i] != NULL)
                         channel_close_fds(&channels[i]);                          channel_close_fds(channels[i]);
 }  }
   
 /* Returns true if any channel is still open. */  /* Returns true if any channel is still open. */
Line 1653 
Line 1657 
 int  int
 channel_still_open()  channel_still_open()
 {  {
         u_int i;          int i;
         for (i = 0; i < channels_alloc; i++)          Channel *c;
                 switch (channels[i].type) {  
                 case SSH_CHANNEL_FREE:          for (i = 0; i < channels_alloc; i++) {
                   c = channels[i];
                   if (c == NULL)
                           continue;
                   switch (c->type) {
                 case SSH_CHANNEL_X11_LISTENER:                  case SSH_CHANNEL_X11_LISTENER:
                 case SSH_CHANNEL_PORT_LISTENER:                  case SSH_CHANNEL_PORT_LISTENER:
                 case SSH_CHANNEL_RPORT_LISTENER:                  case SSH_CHANNEL_RPORT_LISTENER:
Line 1679 
Line 1687 
                                 fatal("cannot happen: OUT_DRAIN");                                  fatal("cannot happen: OUT_DRAIN");
                         return 1;                          return 1;
                 default:                  default:
                         fatal("channel_still_open: bad channel type %d", channels[i].type);                          fatal("channel_still_open: bad channel type %d", c->type);
                         /* NOTREACHED */                          /* NOTREACHED */
                 }                  }
           }
         return 0;          return 0;
 }  }
   
Line 1690 
Line 1699 
 int  int
 channel_find_open()  channel_find_open()
 {  {
         u_int i;          int i;
         for (i = 0; i < channels_alloc; i++)          Channel *c;
                 switch (channels[i].type) {  
           for (i = 0; i < channels_alloc; i++) {
                   c = channels[i];
                   if (c == NULL)
                           continue;
                   switch (c->type) {
                 case SSH_CHANNEL_CLOSED:                  case SSH_CHANNEL_CLOSED:
                 case SSH_CHANNEL_DYNAMIC:                  case SSH_CHANNEL_DYNAMIC:
                 case SSH_CHANNEL_FREE:  
                 case SSH_CHANNEL_X11_LISTENER:                  case SSH_CHANNEL_X11_LISTENER:
                 case SSH_CHANNEL_PORT_LISTENER:                  case SSH_CHANNEL_PORT_LISTENER:
                 case SSH_CHANNEL_RPORT_LISTENER:                  case SSH_CHANNEL_RPORT_LISTENER:
Line 1713 
Line 1726 
                                 fatal("cannot happen: OUT_DRAIN");                                  fatal("cannot happen: OUT_DRAIN");
                         return i;                          return i;
                 default:                  default:
                         fatal("channel_find_open: bad channel type %d", channels[i].type);                          fatal("channel_find_open: bad channel type %d", c->type);
                         /* NOTREACHED */                          /* NOTREACHED */
                 }                  }
           }
         return -1;          return -1;
 }  }
   
Line 1730 
Line 1744 
 channel_open_message()  channel_open_message()
 {  {
         Buffer buffer;          Buffer buffer;
           Channel *c;
           char buf[1024], *cp;
         int i;          int i;
         char buf[512], *cp;  
   
         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");
         buffer_append(&buffer, buf, strlen(buf));          buffer_append(&buffer, buf, strlen(buf));
         for (i = 0; i < channels_alloc; i++) {          for (i = 0; i < channels_alloc; i++) {
                 Channel *c = &channels[i];                  c = channels[i];
                   if (c == NULL)
                           continue;
                 switch (c->type) {                  switch (c->type) {
                 case SSH_CHANNEL_FREE:  
                 case SSH_CHANNEL_X11_LISTENER:                  case SSH_CHANNEL_X11_LISTENER:
                 case SSH_CHANNEL_PORT_LISTENER:                  case SSH_CHANNEL_PORT_LISTENER:
                 case SSH_CHANNEL_RPORT_LISTENER:                  case SSH_CHANNEL_RPORT_LISTENER:
Line 1797 
Line 1813 
     const char *host_to_connect, u_short port_to_connect,      const char *host_to_connect, u_short port_to_connect,
     int gateway_ports, int remote_fwd)      int gateway_ports, int remote_fwd)
 {  {
         int success, ch, sock, on = 1, ctype;          Channel *c;
           int success, sock, on = 1, ctype;
         struct addrinfo hints, *ai, *aitop;          struct addrinfo hints, *ai, *aitop;
         char ntop[NI_MAXHOST], strport[NI_MAXSERV];          char ntop[NI_MAXHOST], strport[NI_MAXSERV];
         const char *host;          const char *host;
Line 1813 
Line 1830 
                 ctype  =SSH_CHANNEL_PORT_LISTENER;                  ctype  =SSH_CHANNEL_PORT_LISTENER;
         }          }
   
         if (strlen(host) > sizeof(channels[0].path) - 1) {          if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
                 error("Forward host name too long.");                  error("Forward host name too long.");
                 return success;                  return success;
         }          }
Line 1870 
Line 1887 
                         continue;                          continue;
                 }                  }
                 /* Allocate a channel number for the socket. */                  /* Allocate a channel number for the socket. */
                 ch = channel_new("port listener", ctype, sock, sock, -1,                  c = channel_new("port listener", ctype, sock, sock, -1,
                     CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,                      CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
                     0, xstrdup("port listener"), 1);                      0, xstrdup("port listener"), 1);
                 strlcpy(channels[ch].path, host, sizeof(channels[ch].path));                  if (c == NULL) {
                 channels[ch].host_port = port_to_connect;                          error("channel_request_forwarding: channel_new failed");
                 channels[ch].listening_port = listen_port;                          close(sock);
                           continue;
                   }
                   strlcpy(c->path, host, sizeof(c->path));
                   c->host_port = port_to_connect;
                   c->listening_port = listen_port;
                 success = 1;                  success = 1;
         }          }
         if (success == 0)          if (success == 0)
Line 2110 
Line 2132 
 void  void
 channel_input_port_open(int type, int plen, void *ctxt)  channel_input_port_open(int type, int plen, void *ctxt)
 {  {
           Channel *c = NULL;
         u_short host_port;          u_short host_port;
         char *host, *originator_string;          char *host, *originator_string;
         int remote_channel, sock = -1, newch;          int remote_id, sock = -1;
   
         remote_channel = packet_get_int();          remote_id = packet_get_int();
         host = packet_get_string(NULL);          host = packet_get_string(NULL);
         host_port = packet_get_int();          host_port = packet_get_int();
   
Line 2126 
Line 2149 
         packet_done();          packet_done();
         sock = channel_connect_to(host, host_port);          sock = channel_connect_to(host, host_port);
         if (sock != -1) {          if (sock != -1) {
                 newch = channel_allocate(SSH_CHANNEL_CONNECTING,                  c = channel_new("connected socket",
                     sock, originator_string);                      SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
                 channels[newch].remote_id = remote_channel;                      originator_string, 1);
                   if (c == NULL) {
                           error("channel_input_port_open: channel_new failed");
                           close(sock);
                   } else {
                           c->remote_id = remote_id;
                   }
           }
           if (c == NULL) {
                   packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                   packet_put_int(remote_id);
           } else {
                 /*XXX delay answer? */                  /*XXX delay answer? */
                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);                  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
                 packet_put_int(remote_channel);                  packet_put_int(remote_id);
                 packet_put_int(newch);                  packet_put_int(c->self);
                 packet_send();  
         } else {  
                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);  
                 packet_put_int(remote_channel);  
                 packet_send();  
         }          }
           packet_send();
         xfree(host);          xfree(host);
 }  }
   
Line 2373 
Line 2402 
 void  void
 x11_input_open(int type, int plen, void *ctxt)  x11_input_open(int type, int plen, void *ctxt)
 {  {
         int remote_channel, sock = 0, newch;          Channel *c = NULL;
           int remote_id, sock = 0;
         char *remote_host;          char *remote_host;
         u_int remote_len;  
   
         /* Get remote channel number. */          debug("Received X11 open request.");
         remote_channel = packet_get_int();  
   
         /* Get remote originator name. */          remote_id = packet_get_int();
         if (have_hostname_in_open) {          if (have_hostname_in_open) {
                 remote_host = packet_get_string(&remote_len);                  remote_host = packet_get_string(NULL);
                 remote_len += 4;  
         } else {          } else {
                 remote_host = xstrdup("unknown (remote did not supply name)");                  remote_host = xstrdup("unknown (remote did not supply name)");
                 remote_len = 0;  
         }          }
           packet_done();
   
         debug("Received X11 open request.");  
         packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);  
   
         /* Obtain a connection to the real X display. */          /* Obtain a connection to the real X display. */
         sock = x11_connect_display();          sock = x11_connect_display();
         if (sock == -1) {          if (sock != -1) {
                   /* Allocate a channel for this connection. */
                   c = channel_new("connected x11 socket",
                       SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
                       remote_host, 1);
                   if (c == NULL) {
                           error("x11_input_open: channel_new failed");
                           close(sock);
                   } else {
                           c->remote_id = remote_id;
                   }
           }
           if (c == NULL) {
                 /* 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_channel);                  packet_put_int(remote_id);
                 packet_send();  
         } else {          } else {
                 /* Allocate a channel for this connection. */  
                 newch = channel_allocate(  
                      (x11_saved_proto == NULL) ?  
                      SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN,  
                      sock, remote_host);  
                 channels[newch].remote_id = remote_channel;  
   
                 /* 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);
                 packet_put_int(remote_channel);                  packet_put_int(remote_id);
                 packet_put_int(newch);                  packet_put_int(c->self);
                 packet_send();  
         }          }
           packet_send();
 }  }
   
 /* dummy protocol handler that denies SSH-1 requests (agent/x11) */  /* dummy protocol handler that denies SSH-1 requests (agent/x11) */
Line 2545 
Line 2573 
 int  int
 auth_input_request_forwarding(struct passwd * pw)  auth_input_request_forwarding(struct passwd * pw)
 {  {
         int sock, newch;          Channel *nc;
           int sock;
         struct sockaddr_un sunaddr;          struct sockaddr_un sunaddr;
   
         if (auth_get_socket_name() != NULL)          if (auth_get_socket_name() != NULL)
Line 2600 
Line 2629 
                 packet_disconnect("listen: %.100s", strerror(errno));                  packet_disconnect("listen: %.100s", strerror(errno));
   
         /* Allocate a channel for the authentication agent socket. */          /* Allocate a channel for the authentication agent socket. */
         newch = channel_new("auth socket",          nc = channel_new("auth socket",
             SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,              SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
             CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,              CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
             0, xstrdup("auth socket"), 1);              0, xstrdup("auth socket"), 1);
           if (nc == NULL) {
         strlcpy(channels[newch].path, channel_forwarded_auth_socket_name,                  error("auth_input_request_forwarding: channel_new failed");
             sizeof(channels[newch].path));                  close(sock);
                   return 0;
           }
           strlcpy(nc->path, channel_forwarded_auth_socket_name, sizeof(nc->path));
         return 1;          return 1;
 }  }
   
Line 2615 
Line 2647 
 void  void
 auth_input_open_request(int type, int plen, void *ctxt)  auth_input_open_request(int type, int plen, void *ctxt)
 {  {
         int remch, sock, newch;          Channel *c = NULL;
           int remote_id, sock;
         char *dummyname;          char *dummyname;
   
         packet_integrity_check(plen, 4, type);          packet_integrity_check(plen, 4, type);
   
         /* Read the remote channel number from the message. */          /* Read the remote channel number from the message. */
         remch = packet_get_int();          remote_id = packet_get_int();
   
         /*          /*
          * Get a connection to the local authentication agent (this may again           * Get a connection to the local authentication agent (this may again
Line 2635 
Line 2668 
          * because authentication forwarding is only enabled if we have an           * because authentication forwarding is only enabled if we have an
          * agent.           * agent.
          */           */
         if (sock < 0) {          if (sock >= 0) {
                   dummyname = xstrdup("authentication agent connection");
                   c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, -1, 0, 0, 0, dummyname, 1);
                   if (c == NULL) {
                           error("auth_input_open_request: channel_new failed");
                           close(sock);
                   } else {
                           c->remote_id = remote_id;
                   }
           }
           if (c == NULL) {
                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);                  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                 packet_put_int(remch);                  packet_put_int(remote_id);
                 packet_send();          } else {
                 return;                  /* Send a confirmation to the remote host. */
                   debug("Forwarding authentication connection.");
                   packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
                   packet_put_int(remote_id);
                   packet_put_int(c->self);
         }          }
         debug("Forwarding authentication connection.");  
   
         /*  
          * Dummy host name.  This will be freed when the channel is freed; it  
          * will still be valid in the packet_put_string below since the  
          * channel cannot yet be freed at that point.  
          */  
         dummyname = xstrdup("authentication agent connection");  
   
         newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);  
         channels[newch].remote_id = remch;  
   
         /* Send a confirmation to the remote host. */  
         packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);  
         packet_put_int(remch);  
         packet_put_int(newch);  
         packet_send();          packet_send();
 }  }
   

Legend:
Removed from v.1.112  
changed lines
  Added in v.1.113