[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.187 and 1.187.2.2

version 1.187, 2003/03/05 22:33:43 version 1.187.2.2, 2003/09/16 21:30:49
Line 54 
Line 54 
 #include "key.h"  #include "key.h"
 #include "authfd.h"  #include "authfd.h"
 #include "pathnames.h"  #include "pathnames.h"
   #include "bufaux.h"
   
   
 /* -- channel core */  /* -- channel core */
   
 /*  /*
Line 142 
Line 142 
         Channel *c;          Channel *c;
   
         if (id < 0 || id >= channels_alloc) {          if (id < 0 || id >= channels_alloc) {
                 log("channel_lookup: %d: bad id", id);                  logit("channel_lookup: %d: bad id", id);
                 return NULL;                  return NULL;
         }          }
         c = channels[id];          c = channels[id];
         if (c == NULL) {          if (c == NULL) {
                 log("channel_lookup: %d: bad id: channel free", id);                  logit("channel_lookup: %d: bad id: channel free", id);
                 return NULL;                  return NULL;
         }          }
         return c;          return c;
Line 177 
Line 177 
   
         /* XXX ugly hack: nonblock is only set by the server */          /* XXX ugly hack: nonblock is only set by the server */
         if (nonblock && isatty(c->rfd)) {          if (nonblock && isatty(c->rfd)) {
                 debug("channel %d: rfd %d isatty", c->self, c->rfd);                  debug2("channel %d: rfd %d isatty", c->self, c->rfd);
                 c->isatty = 1;                  c->isatty = 1;
                 if (!isatty(c->wfd)) {                  if (!isatty(c->wfd)) {
                         error("channel %d: wfd %d is not a tty?",                          error("channel %d: wfd %d is not a tty?",
Line 228 
Line 228 
         if (found == -1) {          if (found == -1) {
                 /* There are no free slots.  Take last+1 slot and expand the array.  */                  /* There are no free slots.  Take last+1 slot and expand the array.  */
                 found = channels_alloc;                  found = channels_alloc;
                 channels_alloc += 10;  
                 if (channels_alloc > 10000)                  if (channels_alloc > 10000)
                         fatal("channel_new: internal error: channels_alloc %d "                          fatal("channel_new: internal error: channels_alloc %d "
                             "too big.", channels_alloc);                              "too big.", channels_alloc);
                   channels = xrealloc(channels,
                       (channels_alloc + 10) * sizeof(Channel *));
                   channels_alloc += 10;
                 debug2("channel: expanding %d", channels_alloc);                  debug2("channel: expanding %d", channels_alloc);
                 channels = xrealloc(channels, channels_alloc * sizeof(Channel *));  
                 for (i = found; i < channels_alloc; i++)                  for (i = found; i < channels_alloc; i++)
                         channels[i] = NULL;                          channels[i] = NULL;
         }          }
Line 255 
Line 256 
         c->local_consumed = 0;          c->local_consumed = 0;
         c->local_maxpacket = maxpack;          c->local_maxpacket = maxpack;
         c->remote_id = -1;          c->remote_id = -1;
         c->remote_name = remote_name;          c->remote_name = xstrdup(remote_name);
         c->remote_window = 0;          c->remote_window = 0;
         c->remote_maxpacket = 0;          c->remote_maxpacket = 0;
         c->force_drain = 0;          c->force_drain = 0;
Line 303 
Line 304 
 static void  static void
 channel_close_fds(Channel *c)  channel_close_fds(Channel *c)
 {  {
         debug3("channel_close_fds: channel %d: r %d w %d e %d",          debug3("channel %d: close_fds r %d w %d e %d",
             c->self, c->rfd, c->wfd, c->efd);              c->self, c->rfd, c->wfd, c->efd);
   
         channel_close_fd(&c->sock);          channel_close_fd(&c->sock);
Line 323 
Line 324 
         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_free: channel %d: %s, nchannels %d", c->self,          debug("channel %d: free: %s, nchannels %d", c->self,
             c->remote_name ? c->remote_name : "???", n);              c->remote_name ? c->remote_name : "???", n);
   
         s = channel_open_message();          s = channel_open_message();
         debug3("channel_free: status: %s", s);          debug3("channel %d: status: %s", c->self, s);
         xfree(s);          xfree(s);
   
         if (c->sock != -1)          if (c->sock != -1)
Line 418 
Line 419 
                         }                          }
 #endif  #endif
                         if (buffer_len(&c->output) > packet_get_maxsize()) {                          if (buffer_len(&c->output) > packet_get_maxsize()) {
                                 debug2("channel %d: big output buffer %d > %d",                                  debug2("channel %d: big output buffer %u > %u",
                                     c->self, buffer_len(&c->output),                                      c->self, buffer_len(&c->output),
                                     packet_get_maxsize());                                      packet_get_maxsize());
                                 return 0;                                  return 0;
Line 574 
Line 575 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_send_open: %d: bad id", id);                  logit("channel_send_open: %d: bad id", id);
                 return;                  return;
         }          }
         debug2("channel %d: send open", id);          debug2("channel %d: send open", id);
Line 592 
Line 593 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_request_start: %d: unknown channel id", id);                  logit("channel_request_start: %d: unknown channel id", id);
                 return;                  return;
         }          }
         debug("channel %d: request %s", id, service) ;          debug2("channel %d: request %s", id, service) ;
         packet_start(SSH2_MSG_CHANNEL_REQUEST);          packet_start(SSH2_MSG_CHANNEL_REQUEST);
         packet_put_int(c->remote_id);          packet_put_int(c->remote_id);
         packet_put_cstring(service);          packet_put_cstring(service);
Line 607 
Line 608 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_comfirm: %d: bad id", id);                  logit("channel_register_comfirm: %d: bad id", id);
                 return;                  return;
         }          }
         c->confirm = fn;          c->confirm = fn;
Line 618 
Line 619 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_cleanup: %d: bad id", id);                  logit("channel_register_cleanup: %d: bad id", id);
                 return;                  return;
         }          }
         c->detach_user = fn;          c->detach_user = fn;
Line 629 
Line 630 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_cancel_cleanup: %d: bad id", id);                  logit("channel_cancel_cleanup: %d: bad id", id);
                 return;                  return;
         }          }
         c->detach_user = NULL;          c->detach_user = NULL;
Line 640 
Line 641 
         Channel *c = channel_lookup(id);          Channel *c = channel_lookup(id);
   
         if (c == NULL) {          if (c == NULL) {
                 log("channel_register_filter: %d: bad id", id);                  logit("channel_register_filter: %d: bad id", id);
                 return;                  return;
         }          }
         c->input_filter = fn;          c->input_filter = fn;
Line 738 
Line 739 
                 packet_put_int(c->remote_id);                  packet_put_int(c->remote_id);
                 packet_send();                  packet_send();
                 c->type = SSH_CHANNEL_CLOSED;                  c->type = SSH_CHANNEL_CLOSED;
                 debug("channel %d: closing after input drain.", c->self);                  debug2("channel %d: closing after input drain.", c->self);
         }          }
 }  }
   
Line 779 
Line 780 
                 proto_len = ucp[6] + 256 * ucp[7];                  proto_len = ucp[6] + 256 * ucp[7];
                 data_len = ucp[8] + 256 * ucp[9];                  data_len = ucp[8] + 256 * ucp[9];
         } else {          } else {
                 debug("Initial X11 packet contains bad byte order byte: 0x%x",                  debug2("Initial X11 packet contains bad byte order byte: 0x%x",
                     ucp[0]);                      ucp[0]);
                 return -1;                  return -1;
         }          }
Line 792 
Line 793 
         /* Check if authentication protocol matches. */          /* Check if authentication protocol matches. */
         if (proto_len != strlen(x11_saved_proto) ||          if (proto_len != strlen(x11_saved_proto) ||
             memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {              memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
                 debug("X11 connection uses different authentication protocol.");                  debug2("X11 connection uses different authentication protocol.");
                 return -1;                  return -1;
         }          }
         /* Check if authentication data matches our fake data. */          /* Check if authentication data matches our fake data. */
         if (data_len != x11_fake_data_len ||          if (data_len != x11_fake_data_len ||
             memcmp(ucp + 12 + ((proto_len + 3) & ~3),              memcmp(ucp + 12 + ((proto_len + 3) & ~3),
                 x11_fake_data, x11_fake_data_len) != 0) {                  x11_fake_data, x11_fake_data_len) != 0) {
                 debug("X11 auth data does not match fake data.");                  debug2("X11 auth data does not match fake data.");
                 return -1;                  return -1;
         }          }
         /* Check fake data length */          /* Check fake data length */
Line 832 
Line 833 
                  * We have received an X11 connection that has bad                   * We have received an X11 connection that has bad
                  * authentication information.                   * authentication information.
                  */                   */
                 log("X11 connection rejected because of wrong authentication.");                  logit("X11 connection rejected because of wrong authentication.");
                 buffer_clear(&c->input);                  buffer_clear(&c->input);
                 buffer_clear(&c->output);                  buffer_clear(&c->output);
                 channel_close_fd(&c->sock);                  channel_close_fd(&c->sock);
Line 855 
Line 856 
                 c->type = SSH_CHANNEL_OPEN;                  c->type = SSH_CHANNEL_OPEN;
                 channel_pre_open(c, readset, writeset);                  channel_pre_open(c, readset, writeset);
         } else if (ret == -1) {          } else if (ret == -1) {
                 log("X11 connection rejected because of wrong authentication.");                  logit("X11 connection rejected because of wrong authentication.");
                 debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);                  debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
                 chan_read_failed(c);                  chan_read_failed(c);
                 buffer_clear(&c->input);                  buffer_clear(&c->input);
                 chan_ibuf_empty(c);                  chan_ibuf_empty(c);
Line 866 
Line 867 
                         chan_write_failed(c);                          chan_write_failed(c);
                 else                  else
                         c->type = SSH_CHANNEL_OPEN;                          c->type = SSH_CHANNEL_OPEN;
                 debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);                  debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
         }          }
 }  }
   
Line 924 
Line 925 
         strlcpy(c->path, host, sizeof(c->path));          strlcpy(c->path, host, sizeof(c->path));
         c->host_port = ntohs(s4_req.dest_port);          c->host_port = ntohs(s4_req.dest_port);
   
         debug("channel %d: dynamic request: socks4 host %s port %u command %u",          debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
             c->self, host, c->host_port, s4_req.command);              c->self, host, c->host_port, s4_req.command);
   
         if (s4_req.command != 1) {          if (s4_req.command != 1) {
Line 940 
Line 941 
         return 1;          return 1;
 }  }
   
   /* try to decode a socks5 header */
   #define SSH_SOCKS5_AUTHDONE     0x1000
   #define SSH_SOCKS5_NOAUTH       0x00
   #define SSH_SOCKS5_IPV4         0x01
   #define SSH_SOCKS5_DOMAIN       0x03
   #define SSH_SOCKS5_IPV6         0x04
   #define SSH_SOCKS5_CONNECT      0x01
   #define SSH_SOCKS5_SUCCESS      0x00
   
   static int
   channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
   {
           struct {
                   u_int8_t version;
                   u_int8_t command;
                   u_int8_t reserved;
                   u_int8_t atyp;
           } s5_req, s5_rsp;
           u_int16_t dest_port;
           u_char *p, dest_addr[255+1];
           int i, have, found, nmethods, addrlen, af;
   
           debug2("channel %d: decode socks5", c->self);
           p = buffer_ptr(&c->input);
           if (p[0] != 0x05)
                   return -1;
           have = buffer_len(&c->input);
           if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
                   /* format: ver | nmethods | methods */
                   if (have < 2)
                           return 0;
                   nmethods = p[1];
                   if (have < nmethods + 2)
                           return 0;
                   /* look for method: "NO AUTHENTICATION REQUIRED" */
                   for (found = 0, i = 2 ; i < nmethods + 2; i++) {
                           if (p[i] == SSH_SOCKS5_NOAUTH ) {
                                   found = 1;
                                   break;
                           }
                   }
                   if (!found) {
                           debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
                               c->self);
                           return -1;
                   }
                   buffer_consume(&c->input, nmethods + 2);
                   buffer_put_char(&c->output, 0x05);              /* version */
                   buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */
                   FD_SET(c->sock, writeset);
                   c->flags |= SSH_SOCKS5_AUTHDONE;
                   debug2("channel %d: socks5 auth done", c->self);
                   return 0;                               /* need more */
           }
           debug2("channel %d: socks5 post auth", c->self);
           if (have < sizeof(s5_req)+1)
                   return 0;                       /* need more */
           memcpy((char *)&s5_req, p, sizeof(s5_req));
           if (s5_req.version != 0x05 ||
               s5_req.command != SSH_SOCKS5_CONNECT ||
               s5_req.reserved != 0x00) {
                   debug2("channel %d: only socks5 connect supported", c->self);
                   return -1;
           }
           switch(s5_req.atyp){
           case SSH_SOCKS5_IPV4:
                   addrlen = 4;
                   af = AF_INET;
                   break;
           case SSH_SOCKS5_DOMAIN:
                   addrlen = p[sizeof(s5_req)];
                   af = -1;
                   break;
           case SSH_SOCKS5_IPV6:
                   addrlen = 16;
                   af = AF_INET6;
                   break;
           default:
                   debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
                   return -1;
           }
           if (have < 4 + addrlen + 2)
                   return 0;
           buffer_consume(&c->input, sizeof(s5_req));
           if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
                   buffer_consume(&c->input, 1);    /* host string length */
           buffer_get(&c->input, (char *)&dest_addr, addrlen);
           buffer_get(&c->input, (char *)&dest_port, 2);
           dest_addr[addrlen] = '\0';
           if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
                   strlcpy(c->path, dest_addr, sizeof(c->path));
           else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
                   return -1;
           c->host_port = ntohs(dest_port);
   
           debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
               c->self, c->path, c->host_port, s5_req.command);
   
           s5_rsp.version = 0x05;
           s5_rsp.command = SSH_SOCKS5_SUCCESS;
           s5_rsp.reserved = 0;                    /* ignored */
           s5_rsp.atyp = SSH_SOCKS5_IPV4;
           ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
           dest_port = 0;                          /* ignored */
   
           buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
           buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
           buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
           return 1;
   }
   
 /* dynamic port forwarding */  /* dynamic port forwarding */
 static void  static void
 channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)  channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
Line 952 
Line 1064 
         debug2("channel %d: pre_dynamic: have %d", c->self, have);          debug2("channel %d: pre_dynamic: have %d", c->self, have);
         /* buffer_dump(&c->input); */          /* buffer_dump(&c->input); */
         /* check if the fixed size part of the packet is in buffer. */          /* check if the fixed size part of the packet is in buffer. */
         if (have < 4) {          if (have < 3) {
                 /* need more */                  /* need more */
                 FD_SET(c->sock, readset);                  FD_SET(c->sock, readset);
                 return;                  return;
Line 963 
Line 1075 
         case 0x04:          case 0x04:
                 ret = channel_decode_socks4(c, readset, writeset);                  ret = channel_decode_socks4(c, readset, writeset);
                 break;                  break;
           case 0x05:
                   ret = channel_decode_socks5(c, readset, writeset);
                   break;
         default:          default:
                 ret = -1;                  ret = -1;
                 break;                  break;
Line 996 
Line 1111 
                 addrlen = sizeof(addr);                  addrlen = sizeof(addr);
                 newsock = accept(c->sock, &addr, &addrlen);                  newsock = accept(c->sock, &addr, &addrlen);
                 if (c->single_connection) {                  if (c->single_connection) {
                         debug("single_connection: closing X11 listener.");                          debug2("single_connection: closing X11 listener.");
                         channel_close_fd(&c->sock);                          channel_close_fd(&c->sock);
                         chan_mark_dead(c);                          chan_mark_dead(c);
                 }                  }
Line 1012 
Line 1127 
   
                 nc = channel_new("accepted x11 socket",                  nc = channel_new("accepted x11 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, buf, 1);
                     0, xstrdup(buf), 1);  
                 if (compat20) {                  if (compat20) {
                         packet_start(SSH2_MSG_CHANNEL_OPEN);                          packet_start(SSH2_MSG_CHANNEL_OPEN);
                         packet_put_cstring("x11");                          packet_put_cstring("x11");
Line 1023 
Line 1137 
                         /* originator ipaddr and port */                          /* originator ipaddr and port */
                         packet_put_cstring(remote_ipaddr);                          packet_put_cstring(remote_ipaddr);
                         if (datafellows & SSH_BUG_X11FWD) {                          if (datafellows & SSH_BUG_X11FWD) {
                                 debug("ssh2 x11 bug compat mode");                                  debug2("ssh2 x11 bug compat mode");
                         } else {                          } else {
                                 packet_put_int(remote_port);                                  packet_put_int(remote_port);
                         }                          }
Line 1128 
Line 1242 
                         return;                          return;
                 }                  }
                 set_nodelay(newsock);                  set_nodelay(newsock);
                 nc = channel_new(rtype,                  nc = channel_new(rtype, nextstate, newsock, newsock, -1,
                     nextstate, newsock, newsock, -1,                      c->local_window_max, c->local_maxpacket, 0, rtype, 1);
                     c->local_window_max, c->local_maxpacket,  
                     0, xstrdup(rtype), 1);  
                 nc->listening_port = c->listening_port;                  nc->listening_port = c->listening_port;
                 nc->host_port = c->host_port;                  nc->host_port = c->host_port;
                 strlcpy(nc->path, c->path, sizeof(nc->path));                  strlcpy(nc->path, c->path, sizeof(nc->path));
Line 1157 
Line 1269 
 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;          Channel *nc;
         char *name;  
         int newsock;          int newsock;
         struct sockaddr addr;          struct sockaddr addr;
         socklen_t addrlen;          socklen_t addrlen;
Line 1169 
Line 1280 
                         error("accept from auth socket: %.100s", strerror(errno));                          error("accept from auth socket: %.100s", strerror(errno));
                         return;                          return;
                 }                  }
                 name = xstrdup("accepted auth socket");  
                 nc = channel_new("accepted auth socket",                  nc = 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, name, 1);                      0, "accepted auth socket", 1);
                 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");
Line 1246 
Line 1356 
                 if (len < 0 && (errno == EINTR || errno == EAGAIN))                  if (len < 0 && (errno == EINTR || errno == EAGAIN))
                         return 1;                          return 1;
                 if (len <= 0) {                  if (len <= 0) {
                         debug("channel %d: read<=0 rfd %d len %d",                          debug2("channel %d: read<=0 rfd %d len %d",
                             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);                                  debug2("channel %d: not open", c->self);
                                 chan_mark_dead(c);                                  chan_mark_dead(c);
                                 return -1;                                  return -1;
                         } else if (compat13) {                          } else if (compat13) {
                                 buffer_clear(&c->output);                                  buffer_clear(&c->output);
                                 c->type = SSH_CHANNEL_INPUT_DRAINING;                                  c->type = SSH_CHANNEL_INPUT_DRAINING;
                                 debug("channel %d: input draining.", c->self);                                  debug2("channel %d: input draining.", c->self);
                         } else {                          } else {
                                 chan_read_failed(c);                                  chan_read_failed(c);
                         }                          }
Line 1263 
Line 1373 
                 }                  }
                 if (c->input_filter != NULL) {                  if (c->input_filter != NULL) {
                         if (c->input_filter(c, buf, len) == -1) {                          if (c->input_filter(c, buf, len) == -1) {
                                 debug("channel %d: filter stops", c->self);                                  debug2("channel %d: filter stops", c->self);
                                 chan_read_failed(c);                                  chan_read_failed(c);
                         }                          }
                 } else {                  } else {
Line 1291 
Line 1401 
                         return 1;                          return 1;
                 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);                                  debug2("channel %d: not open", c->self);
                                 chan_mark_dead(c);                                  chan_mark_dead(c);
                                 return -1;                                  return -1;
                         } else if (compat13) {                          } else if (compat13) {
                                 buffer_clear(&c->output);                                  buffer_clear(&c->output);
                                 debug("channel %d: input draining.", c->self);                                  debug2("channel %d: input draining.", c->self);
                                 c->type = SSH_CHANNEL_INPUT_DRAINING;                                  c->type = SSH_CHANNEL_INPUT_DRAINING;
                         } else {                          } else {
                                 chan_write_failed(c);                                  chan_write_failed(c);
Line 1503 
Line 1613 
         if (c->detach_user != NULL) {          if (c->detach_user != NULL) {
                 if (!chan_is_dead(c, 0))                  if (!chan_is_dead(c, 0))
                         return;                          return;
                 debug("channel %d: gc: notify user", c->self);                  debug2("channel %d: gc: notify user", c->self);
                 c->detach_user(c->self, NULL);                  c->detach_user(c->self, NULL);
                 /* if we still have a callback */                  /* if we still have a callback */
                 if (c->detach_user != NULL)                  if (c->detach_user != NULL)
                         return;                          return;
                 debug("channel %d: gc: user detached", c->self);                  debug2("channel %d: gc: user detached", c->self);
         }          }
         if (!chan_is_dead(c, 1))          if (!chan_is_dead(c, 1))
                 return;                  return;
         debug("channel %d: garbage collecting", c->self);          debug2("channel %d: garbage collecting", c->self);
         channel_free(c);          channel_free(c);
 }  }
   
Line 1711 
Line 1821 
   
         if (compat20) {          if (compat20) {
                 if (data_len > c->local_maxpacket) {                  if (data_len > c->local_maxpacket) {
                         log("channel %d: rcvd big packet %d, maxpack %d",                          logit("channel %d: rcvd big packet %d, maxpack %d",
                             c->self, data_len, c->local_maxpacket);                              c->self, data_len, c->local_maxpacket);
                 }                  }
                 if (data_len > c->local_window) {                  if (data_len > c->local_window) {
                         log("channel %d: rcvd too much data %d, win %d",                          logit("channel %d: rcvd too much data %d, win %d",
                             c->self, data_len, c->local_window);                              c->self, data_len, c->local_window);
                         xfree(data);                          xfree(data);
                         return;                          return;
Line 1742 
Line 1852 
         if (c == NULL)          if (c == NULL)
                 packet_disconnect("Received extended_data for bad channel %d.", id);                  packet_disconnect("Received extended_data for bad channel %d.", id);
         if (c->type != SSH_CHANNEL_OPEN) {          if (c->type != SSH_CHANNEL_OPEN) {
                 log("channel %d: ext data for non open", id);                  logit("channel %d: ext data for non open", id);
                 return;                  return;
         }          }
         if (c->flags & CHAN_EOF_RCVD) {          if (c->flags & CHAN_EOF_RCVD) {
Line 1756 
Line 1866 
         if (c->efd == -1 ||          if (c->efd == -1 ||
             c->extended_usage != CHAN_EXTENDED_WRITE ||              c->extended_usage != CHAN_EXTENDED_WRITE ||
             tcode != SSH2_EXTENDED_DATA_STDERR) {              tcode != SSH2_EXTENDED_DATA_STDERR) {
                 log("channel %d: bad ext data", c->self);                  logit("channel %d: bad ext data", c->self);
                 return;                  return;
         }          }
         data = packet_get_string(&data_len);          data = packet_get_string(&data_len);
         packet_check_eom();          packet_check_eom();
         if (data_len > c->local_window) {          if (data_len > c->local_window) {
                 log("channel %d: rcvd too much extended_data %d, win %d",                  logit("channel %d: rcvd too much extended_data %d, win %d",
                     c->self, data_len, c->local_window);                      c->self, data_len, c->local_window);
                 xfree(data);                  xfree(data);
                 return;                  return;
Line 1887 
Line 1997 
                         c->confirm(c->self, NULL);                          c->confirm(c->self, NULL);
                         debug2("callback done");                          debug2("callback done");
                 }                  }
                 debug("channel %d: open confirm rwindow %u rmax %u", c->self,                  debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
                     c->remote_window, c->remote_maxpacket);                      c->remote_window, c->remote_maxpacket);
         }          }
         packet_check_eom();          packet_check_eom();
Line 1928 
Line 2038 
                         msg  = packet_get_string(NULL);                          msg  = packet_get_string(NULL);
                         lang = packet_get_string(NULL);                          lang = packet_get_string(NULL);
                 }                  }
                 log("channel %d: open failed: %s%s%s", id,                  logit("channel %d: open failed: %s%s%s", id,
                     reason2txt(reason), msg ? ": ": "", msg ? msg : "");                      reason2txt(reason), msg ? ": ": "", msg ? msg : "");
                 if (msg != NULL)                  if (msg != NULL)
                         xfree(msg);                          xfree(msg);
Line 1955 
Line 2065 
         c = channel_lookup(id);          c = channel_lookup(id);
   
         if (c == NULL || c->type != SSH_CHANNEL_OPEN) {          if (c == NULL || c->type != SSH_CHANNEL_OPEN) {
                 log("Received window adjust for "                  logit("Received window adjust for "
                     "non-open channel %d.", id);                      "non-open channel %d.", id);
                 return;                  return;
         }          }
Line 1990 
Line 2100 
                     originator_string, 1);                      originator_string, 1);
                 c->remote_id = remote_id;                  c->remote_id = remote_id;
         }          }
           xfree(originator_string);
         if (c == NULL) {          if (c == NULL) {
                 xfree(originator_string);  
                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);                  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                 packet_put_int(remote_id);                  packet_put_int(remote_id);
                 packet_send();                  packet_send();
Line 2052 
Line 2162 
                         continue;                          continue;
                 }                  }
                 /* Create a port to listen for the host. */                  /* Create a port to listen for the host. */
                 sock = socket(ai->ai_family, SOCK_STREAM, 0);                  sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                 if (sock < 0) {                  if (sock < 0) {
                         /* this is no error since kernel may not support ipv6 */                          /* this is no error since kernel may not support ipv6 */
                         verbose("socket: %.100s", strerror(errno));                          verbose("socket: %.100s", strerror(errno));
Line 2084 
Line 2194 
                 /* Allocate a channel number for the socket. */                  /* Allocate a channel number for the socket. */
                 c = channel_new("port listener", type, sock, sock, -1,                  c = channel_new("port listener", type, 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, "port listener", 1);
                 strlcpy(c->path, host, sizeof(c->path));                  strlcpy(c->path, host, sizeof(c->path));
                 c->host_port = port_to_connect;                  c->host_port = port_to_connect;
                 c->listening_port = listen_port;                  c->listening_port = listen_port;
Line 2157 
Line 2267 
                         success = 1;                          success = 1;
                         break;                          break;
                 case SSH_SMSG_FAILURE:                  case SSH_SMSG_FAILURE:
                         log("Warning: Server denied remote port forwarding.");                          logit("Warning: Server denied remote port forwarding.");
                         break;                          break;
                 default:                  default:
                         /* Unknown packet */                          /* Unknown packet */
Line 2195 
Line 2305 
          * privileged port.           * privileged port.
          */           */
         if (port < IPPORT_RESERVED && !is_root)          if (port < IPPORT_RESERVED && !is_root)
                 packet_disconnect("Requested forwarding of port %d but user is not root.",                  packet_disconnect(
                                   port);                      "Requested forwarding of port %d but user is not root.",
                       port);
           if (host_port == 0)
                   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(port, hostname, host_port, gateway_ports);
   
Line 2268 
Line 2382 
                         error("connect_to: getnameinfo failed");                          error("connect_to: getnameinfo failed");
                         continue;                          continue;
                 }                  }
                 sock = socket(ai->ai_family, SOCK_STREAM, 0);                  sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                 if (sock < 0) {                  if (sock < 0) {
                         if (ai->ai_next == NULL)                          if (ai->ai_next == NULL)
                                 error("socket: %.100s", strerror(errno));                                  error("socket: %.100s", strerror(errno));
Line 2328 
Line 2442 
   
         }          }
         if (!permit) {          if (!permit) {
                 log("Received request to connect to host %.100s port %d, "                  logit("Received request to connect to host %.100s port %d, "
                     "but the request was denied.", host, port);                      "but the request was denied.", host, port);
                 return -1;                  return -1;
         }          }
Line 2369 
Line 2483 
                 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)
                                 continue;                                  continue;
                         sock = socket(ai->ai_family, SOCK_STREAM, 0);                          sock = socket(ai->ai_family, ai->ai_socktype,
                               ai->ai_protocol);
                         if (sock < 0) {                          if (sock < 0) {
                                 error("socket: %.100s", strerror(errno));                                  error("socket: %.100s", strerror(errno));
                                 return -1;                                  return -1;
                         }                          }
                         if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {                          if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
                                 debug("bind port %d: %.100s", port, strerror(errno));                                  debug2("bind port %d: %.100s", port, strerror(errno));
                                 close(sock);                                  close(sock);
   
                                 if (ai->ai_next)                                  if (ai->ai_next)
Line 2415 
Line 2530 
                 nc = channel_new("x11 listener",                  nc = channel_new("x11 listener",
                     SSH_CHANNEL_X11_LISTENER, sock, sock, -1,                      SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
                     CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,                      CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
                     0, xstrdup("X11 inet listener"), 1);                      0, "X11 inet listener", 1);
                 nc->single_connection = single_connection;                  nc->single_connection = single_connection;
         }          }
   
Line 2513 
Line 2628 
         }          }
         for (ai = aitop; ai; ai = ai->ai_next) {          for (ai = aitop; ai; ai = ai->ai_next) {
                 /* Create a socket. */                  /* Create a socket. */
                 sock = socket(ai->ai_family, SOCK_STREAM, 0);                  sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                 if (sock < 0) {                  if (sock < 0) {
                         debug("socket: %.100s", strerror(errno));                          debug2("socket: %.100s", strerror(errno));
                         continue;                          continue;
                 }                  }
                 /* Connect it to the display. */                  /* Connect it to the display. */
                 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {                  if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
                         debug("connect %.100s port %d: %.100s", buf,                          debug2("connect %.100s port %d: %.100s", buf,
                             6000 + display_number, strerror(errno));                              6000 + display_number, strerror(errno));
                         close(sock);                          close(sock);
                         continue;                          continue;
Line 2572 
Line 2687 
                 c->remote_id = remote_id;                  c->remote_id = remote_id;
                 c->force_drain = 1;                  c->force_drain = 1;
         }          }
           xfree(remote_host);
         if (c == NULL) {          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_id);                  packet_put_int(remote_id);
                 xfree(remote_host);  
         } else {          } else {
                 /* Send a confirmation to the remote host. */                  /* Send a confirmation to the remote host. */
                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);                  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
Line 2698 
Line 2813 
 {  {
         Channel *c = NULL;          Channel *c = NULL;
         int remote_id, sock;          int remote_id, sock;
         char *name;  
   
         /* Read the remote channel number from the message. */          /* Read the remote channel number from the message. */
         remote_id = packet_get_int();          remote_id = packet_get_int();
Line 2717 
Line 2831 
          * agent.           * agent.
          */           */
         if (sock >= 0) {          if (sock >= 0) {
                 name = xstrdup("authentication agent connection");  
                 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,                  c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
                     -1, 0, 0, 0, name, 1);                      -1, 0, 0, 0, "authentication agent connection", 1);
                 c->remote_id = remote_id;                  c->remote_id = remote_id;
                 c->force_drain = 1;                  c->force_drain = 1;
         }          }

Legend:
Removed from v.1.187  
changed lines
  Added in v.1.187.2.2