[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.2

version 1.200, 2004/01/19 09:24:21 version 1.200.2.2, 2005/03/10 17:15:04
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 2134 
Line 2173 
     const char *host_to_connect, u_short port_to_connect, int gateway_ports)      const char *host_to_connect, u_short port_to_connect, int gateway_ports)
 {  {
         Channel *c;          Channel *c;
         int success, sock, on = 1;          int sock, r, success = 0, on = 1, wildcard = 0, is_client;
         struct addrinfo hints, *ai, *aitop;          struct addrinfo hints, *ai, *aitop;
         const char *host;          const char *host, *addr;
         char ntop[NI_MAXHOST], strport[NI_MAXSERV];          char ntop[NI_MAXHOST], strport[NI_MAXSERV];
   
         success = 0;  
         host = (type == SSH_CHANNEL_RPORT_LISTENER) ?          host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
             listen_addr : host_to_connect;              listen_addr : host_to_connect;
           is_client = (type == SSH_CHANNEL_PORT_LISTENER);
   
         if (host == NULL) {          if (host == NULL) {
                 error("No forward host name.");                  error("No forward host name.");
Line 2153 
Line 2192 
         }          }
   
         /*          /*
            * Determine whether or not a port forward listens to loopback,
            * specified address or wildcard. On the client, a specified bind
            * address will always override gateway_ports. On the server, a
            * gateway_ports of 1 (``yes'') will override the client's
            * specification and force a wildcard bind, whereas a value of 2
            * (``clientspecified'') will bind to whatever address the client
            * asked for.
            *
            * Special-case listen_addrs are:
            *
            * "0.0.0.0"               -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
            * "" (empty string), "*"  -> wildcard v4/v6
            * "localhost"             -> loopback v4/v6
            */
           addr = NULL;
           if (listen_addr == NULL) {
                   /* No address specified: default to gateway_ports setting */
                   if (gateway_ports)
                           wildcard = 1;
           } else if (gateway_ports || is_client) {
                   if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
                       strcmp(listen_addr, "0.0.0.0") == 0) ||
                       *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
                       (!is_client && gateway_ports == 1))
                           wildcard = 1;
                   else if (strcmp(listen_addr, "localhost") != 0)
                           addr = listen_addr;
           }
   
           debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
               type, wildcard, (addr == NULL) ? "NULL" : addr);
   
           /*
          * getaddrinfo returns a loopback address if the hostname is           * getaddrinfo returns a loopback address if the hostname is
          * set to NULL and hints.ai_flags is not AI_PASSIVE           * set to NULL and hints.ai_flags is not AI_PASSIVE
          */           */
         memset(&hints, 0, sizeof(hints));          memset(&hints, 0, sizeof(hints));
         hints.ai_family = IPv4or6;          hints.ai_family = IPv4or6;
         hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;          hints.ai_flags = wildcard ? AI_PASSIVE : 0;
         hints.ai_socktype = SOCK_STREAM;          hints.ai_socktype = SOCK_STREAM;
         snprintf(strport, sizeof strport, "%d", listen_port);          snprintf(strport, sizeof strport, "%d", listen_port);
         if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)          if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
                 packet_disconnect("getaddrinfo: fatal error");                  if (addr == NULL) {
                           /* This really shouldn't happen */
                           packet_disconnect("getaddrinfo: fatal error: %s",
                               gai_strerror(r));
                   } else {
                           verbose("channel_setup_fwd_listener: "
                               "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
                           packet_send_debug("channel_setup_fwd_listener: "
                               "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
                   }
                   aitop = NULL;
           }
   
         for (ai = aitop; ai; ai = ai->ai_next) {          for (ai = aitop; ai; ai = ai->ai_next) {
                 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)                  if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
Line 2218 
Line 2301 
         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 channel %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(const char *listen_host, u_short listen_port,
     const char *host_to_connect, u_short port_to_connect, int gateway_ports)      const char *host_to_connect, u_short port_to_connect, int gateway_ports)
 {  {
         return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,          return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
             NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);              listen_host, listen_port, host_to_connect, port_to_connect,
               gateway_ports);
 }  }
   
 /* protocol v2 remote port fwd, used by sshd */  /* protocol v2 remote port fwd, used by sshd */
Line 2242 
Line 2347 
  */   */
   
 void  void
 channel_request_remote_forwarding(u_short listen_port,  channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
     const char *host_to_connect, u_short port_to_connect)      const char *host_to_connect, u_short port_to_connect)
 {  {
         int type, success = 0;          int type, success = 0;
Line 2253 
Line 2358 
   
         /* Send the forward request to the remote side. */          /* Send the forward request to the remote side. */
         if (compat20) {          if (compat20) {
                 const char *address_to_bind = "0.0.0.0";                  const char *address_to_bind;
                   if (listen_host == NULL)
                           address_to_bind = "localhost";
                   else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0)
                           address_to_bind = "";
                   else
                           address_to_bind = listen_host;
   
                 packet_start(SSH2_MSG_GLOBAL_REQUEST);                  packet_start(SSH2_MSG_GLOBAL_REQUEST);
                 packet_put_cstring("tcpip-forward");                  packet_put_cstring("tcpip-forward");
                 packet_put_char(1);                     /* boolean: want reply */                  packet_put_char(1);                     /* boolean: want reply */
Line 2295 
Line 2407 
 }  }
   
 /*  /*
    * Request cancellation of remote forwarding of connection host:port from
    * local side.
    */
   void
   channel_request_rforward_cancel(const char *host, u_short port)
   {
           int i;
   
           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(host == NULL ? "" : host);
           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 2323 
Line 2469 
                 packet_disconnect("Dynamic forwarding denied.");                  packet_disconnect("Dynamic forwarding denied.");
   
         /* Initiate forwarding */          /* Initiate forwarding */
         channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);          channel_setup_local_fwd_listener(NULL, port, hostname,
               host_port, gateway_ports);
   
         /* Free the argument string. */          /* Free the argument string. */
         xfree(hostname);          xfree(hostname);
Line 2361 
Line 2508 
         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 2549 
                                 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 2577 
         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 2596 
         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 2610 
         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]->client_tty ||
                       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 2669 
                             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 2921 
         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 2946 
                 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.2