[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.402 and 1.403

version 1.402, 2020/09/20 05:47:25 version 1.403, 2020/10/18 11:32:01
Line 222 
Line 222 
         struct ssh_channels *sc;          struct ssh_channels *sc;
   
         if ((sc = calloc(1, sizeof(*sc))) == NULL)          if ((sc = calloc(1, sizeof(*sc))) == NULL)
                 fatal("%s: allocation failed", __func__);                  fatal_f("allocation failed");
         sc->channels_alloc = 10;          sc->channels_alloc = 10;
         sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));          sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
         sc->IPv4or6 = AF_UNSPEC;          sc->IPv4or6 = AF_UNSPEC;
Line 237 
Line 237 
         Channel *c;          Channel *c;
   
         if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {          if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
                 logit("%s: %d: bad id", __func__, id);                  logit_f("%d: bad id", id);
                 return NULL;                  return NULL;
         }          }
         c = ssh->chanctxt->channels[id];          c = ssh->chanctxt->channels[id];
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: bad id: channel free", __func__, id);                  logit_f("%d: bad id: channel free", id);
                 return NULL;                  return NULL;
         }          }
         return c;          return c;
Line 361 
Line 361 
                  */                   */
                 found = sc->channels_alloc;                  found = sc->channels_alloc;
                 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)                  if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
                         fatal("%s: internal error: channels_alloc %d too big",                          fatal_f("internal error: channels_alloc %d too big",
                             __func__, sc->channels_alloc);                              sc->channels_alloc);
                 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,                  sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,
                     sc->channels_alloc + 10, sizeof(*sc->channels));                      sc->channels_alloc + 10, sizeof(*sc->channels));
                 sc->channels_alloc += 10;                  sc->channels_alloc += 10;
Line 373 
Line 373 
         if ((c->input = sshbuf_new()) == NULL ||          if ((c->input = sshbuf_new()) == NULL ||
             (c->output = sshbuf_new()) == NULL ||              (c->output = sshbuf_new()) == NULL ||
             (c->extended = sshbuf_new()) == NULL)              (c->extended = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new failed", __func__);                  fatal_f("sshbuf_new failed");
         if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)          if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
                 fatal("%s: sshbuf_set_max_size: %s", __func__, ssh_err(r));                  fatal_fr(r, "sshbuf_set_max_size");
         c->ostate = CHAN_OUTPUT_OPEN;          c->ostate = CHAN_OUTPUT_OPEN;
         c->istate = CHAN_INPUT_OPEN;          c->istate = CHAN_INPUT_OPEN;
         channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);          channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
Line 482 
Line 482 
                 return &sc->remote_perms;                  return &sc->remote_perms;
                 break;                  break;
         default:          default:
                 fatal("%s: invalid forwarding direction %d", __func__, where);                  fatal_f("invalid forwarding direction %d", where);
         }          }
 }  }
   
Line 503 
Line 503 
                 *npermpp = &pset->num_permitted_admin;                  *npermpp = &pset->num_permitted_admin;
                 break;                  break;
         default:          default:
                 fatal("%s: invalid forwarding client %d", __func__, who);                  fatal_f("invalid forwarding client %d", who);
         }          }
 }  }
   
Line 520 
Line 520 
         permission_set_get_array(ssh, who, where, &permp, &npermp);          permission_set_get_array(ssh, who, where, &permp, &npermp);
   
         if (*npermp >= INT_MAX)          if (*npermp >= INT_MAX)
                 fatal("%s: %s overflow", __func__, fwd_ident(who, where));                  fatal_f("%s overflow", fwd_ident(who, where));
   
         *permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));          *permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));
         n = (*npermp)++;          n = (*npermp)++;
Line 560 
Line 560 
                     channel_rfwd_bind_host(perm->listen_host))) != 0 ||                      channel_rfwd_bind_host(perm->listen_host))) != 0 ||
                     (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||                      (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0) {                      (r = sshpkt_send(ssh)) != 0) {
                         fatal("%s: channel %i: %s", __func__,                          fatal_fr(r, "channel %i", c->self);
                             c->self, ssh_err(r));  
                 }                  }
                 fwd_perm_clear(perm); /* unregister */                  fwd_perm_clear(perm); /* unregister */
         }          }
Line 761 
Line 760 
                 case SSH_CHANNEL_MUX_PROXY:                  case SSH_CHANNEL_MUX_PROXY:
                         return 1;                          return 1;
                 default:                  default:
                         fatal("%s: bad channel type %d", __func__, c->type);                          fatal_f("bad channel type %d", c->type);
                         /* NOTREACHED */                          /* NOTREACHED */
                 }                  }
         }          }
Line 803 
Line 802 
                 case SSH_CHANNEL_X11_OPEN:                  case SSH_CHANNEL_X11_OPEN:
                         return i;                          return i;
                 default:                  default:
                         fatal("%s: bad channel type %d", __func__, c->type);                          fatal_f("bad channel type %d", c->type);
                         /* NOTREACHED */                          /* NOTREACHED */
                 }                  }
         }          }
Line 860 
Line 859 
         char *cp, *ret;          char *cp, *ret;
   
         if ((buf = sshbuf_new()) == NULL)          if ((buf = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_putf(buf,          if ((r = sshbuf_putf(buf,
             "The following connections are open:\r\n")) != 0)              "The following connections are open:\r\n")) != 0)
                 fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));                  fatal_fr(r, "sshbuf_putf");
         for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {          for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
                 c = ssh->chanctxt->channels[i];                  c = ssh->chanctxt->channels[i];
                 if (c == NULL)                  if (c == NULL)
Line 894 
Line 893 
                         if ((r = sshbuf_putf(buf, "  #%d %.300s (%s)\r\n",                          if ((r = sshbuf_putf(buf, "  #%d %.300s (%s)\r\n",
                             c->self, c->remote_name, cp)) != 0) {                              c->self, c->remote_name, cp)) != 0) {
                                 free(cp);                                  free(cp);
                                 fatal("%s: sshbuf_putf: %s",                                  fatal_fr(r, "sshbuf_putf");
                                     __func__, ssh_err(r));  
                         }                          }
                         free(cp);                          free(cp);
                         continue;                          continue;
                 default:                  default:
                         fatal("%s: bad channel type %d", __func__, c->type);                          fatal_f("bad channel type %d", c->type);
                         /* NOTREACHED */                          /* NOTREACHED */
                 }                  }
         }          }
         if ((ret = sshbuf_dup_string(buf)) == NULL)          if ((ret = sshbuf_dup_string(buf)) == NULL)
                 fatal("%s: sshbuf_dup_string", __func__);                  fatal_f("sshbuf_dup_string");
         sshbuf_free(buf);          sshbuf_free(buf);
         return ret;          return ret;
 }  }
Line 920 
Line 918 
             (r = sshpkt_put_u32(ssh, c->self)) != 0 ||              (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||              (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {              (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
                 fatal("%s: channel %i: open: %s", where, c->self, ssh_err(r));                  fatal_r(r, "%s: channel %i: open", where, c->self);
         }          }
 }  }
   
Line 937 
Line 935 
         debug2("channel %d: send open", id);          debug2("channel %d: send open", id);
         open_preamble(ssh, __func__, c, c->ctype);          open_preamble(ssh, __func__, c, c->ctype);
         if ((r = sshpkt_send(ssh)) != 0)          if ((r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i", c->self);
 }  }
   
 void  void
Line 947 
Line 945 
         int r;          int r;
   
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: unknown channel id", __func__, id);                  logit_f("%d: unknown channel id", id);
                 return;                  return;
         }          }
         if (!c->have_remote_id)          if (!c->have_remote_id)
                 fatal(":%s: channel %d: no remote id", __func__, c->self);                  fatal_f("channel %d: no remote id", c->self);
   
         debug2("channel %d: request %s confirm %d", id, service, wantconfirm);          debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
         if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
             (r = sshpkt_put_cstring(ssh, service)) != 0 ||              (r = sshpkt_put_cstring(ssh, service)) != 0 ||
             (r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {              (r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {
                 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i", c->self);
         }          }
 }  }
   
Line 970 
Line 968 
         Channel *c;          Channel *c;
   
         if ((c = channel_lookup(ssh, id)) == NULL)          if ((c = channel_lookup(ssh, id)) == NULL)
                 fatal("%s: %d: bad id", __func__, id);                  fatal_f("%d: bad id", id);
   
         cc = xcalloc(1, sizeof(*cc));          cc = xcalloc(1, sizeof(*cc));
         cc->cb = cb;          cc->cb = cb;
Line 986 
Line 984 
         Channel *c = channel_lookup(ssh, id);          Channel *c = channel_lookup(ssh, id);
   
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: bad id", __func__, id);                  logit_f("%d: bad id", id);
                 return;                  return;
         }          }
         c->open_confirm = fn;          c->open_confirm = fn;
Line 1000 
Line 998 
         Channel *c = channel_by_id(ssh, id);          Channel *c = channel_by_id(ssh, id);
   
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: bad id", __func__, id);                  logit_f("%d: bad id", id);
                 return;                  return;
         }          }
         c->detach_user = fn;          c->detach_user = fn;
Line 1013 
Line 1011 
         Channel *c = channel_by_id(ssh, id);          Channel *c = channel_by_id(ssh, id);
   
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: bad id", __func__, id);                  logit_f("%d: bad id", id);
                 return;                  return;
         }          }
         c->detach_user = NULL;          c->detach_user = NULL;
Line 1027 
Line 1025 
         Channel *c = channel_lookup(ssh, id);          Channel *c = channel_lookup(ssh, id);
   
         if (c == NULL) {          if (c == NULL) {
                 logit("%s: %d: bad id", __func__, id);                  logit_f("%d: bad id", id);
                 return;                  return;
         }          }
         c->input_filter = ifn;          c->input_filter = ifn;
Line 1046 
Line 1044 
         if (c == NULL || c->type != SSH_CHANNEL_LARVAL)          if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
                 fatal("channel_activate for non-larval channel %d.", id);                  fatal("channel_activate for non-larval channel %d.", id);
         if (!c->have_remote_id)          if (!c->have_remote_id)
                 fatal(":%s: channel %d: no remote id", __func__, c->self);                  fatal_f("channel %d: no remote id", c->self);
   
         channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);          channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
         c->type = SSH_CHANNEL_OPEN;          c->type = SSH_CHANNEL_OPEN;
Line 1056 
Line 1054 
             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||              (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i", c->self);
 }  }
   
 static void  static void
Line 1285 
Line 1283 
             (r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||              (r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||
             (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||              (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||
             (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {              (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {
                 debug("channels %d: decode socks4: %s", c->self, ssh_err(r));                  debug_r(r, "channels %d: decode socks4", c->self);
                 return -1;                  return -1;
         }          }
         have = sshbuf_len(input);          have = sshbuf_len(input);
         p = sshbuf_ptr(input);          p = sshbuf_ptr(input);
         if (memchr(p, '\0', have) == NULL) {          if (memchr(p, '\0', have) == NULL) {
                 error("channel %d: decode socks4: user not nul terminated",                  error("channel %d: decode socks4: unterminated user", c->self);
                     c->self);  
                 return -1;                  return -1;
         }          }
         len = strlen(p);          len = strlen(p);
         debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);          debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
         len++; /* trailing '\0' */          len++; /* trailing '\0' */
         strlcpy(username, p, sizeof(username));          strlcpy(username, p, sizeof(username));
         if ((r = sshbuf_consume(input, len)) != 0) {          if ((r = sshbuf_consume(input, len)) != 0)
                 fatal("%s: channel %d: consume: %s", __func__,                  fatal_fr(r, "channel %d: consume", c->self);
                     c->self, ssh_err(r));  
         }  
         free(c->path);          free(c->path);
         c->path = NULL;          c->path = NULL;
         if (need == 1) {                        /* SOCKS4: one string */          if (need == 1) {                        /* SOCKS4: one string */
Line 1326 
Line 1321 
                         return -1;                          return -1;
                 }                  }
                 c->path = xstrdup(p);                  c->path = xstrdup(p);
                 if ((r = sshbuf_consume(input, len)) != 0) {                  if ((r = sshbuf_consume(input, len)) != 0)
                         fatal("%s: channel %d: consume: %s", __func__,                          fatal_fr(r, "channel %d: consume", c->self);
                             c->self, ssh_err(r));  
                 }  
         }          }
         c->host_port = ntohs(s4_req.dest_port);          c->host_port = ntohs(s4_req.dest_port);
   
Line 1345 
Line 1338 
         s4_rsp.command = 90;                    /* cd: req granted */          s4_rsp.command = 90;                    /* cd: req granted */
         s4_rsp.dest_port = 0;                   /* ignored */          s4_rsp.dest_port = 0;                   /* ignored */
         s4_rsp.dest_addr.s_addr = INADDR_ANY;   /* ignored */          s4_rsp.dest_addr.s_addr = INADDR_ANY;   /* ignored */
         if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0) {          if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0)
                 fatal("%s: channel %d: append reply: %s", __func__,                  fatal_fr(r, "channel %d: append reply", c->self);
                     c->self, ssh_err(r));  
         }  
         return 1;          return 1;
 }  }
   
Line 1401 
Line 1392 
                             c->self);                              c->self);
                         return -1;                          return -1;
                 }                  }
                 if ((r = sshbuf_consume(input, nmethods + 2)) != 0) {                  if ((r = sshbuf_consume(input, nmethods + 2)) != 0)
                         fatal("%s: channel %d: consume: %s", __func__,                          fatal_fr(r, "channel %d: consume", c->self);
                             c->self, ssh_err(r));  
                 }  
                 /* version, method */                  /* version, method */
                 if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||                  if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||
                     (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) {                      (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0)
                         fatal("%s: channel %d: append reply: %s", __func__,                          fatal_fr(r, "channel %d: append reply", c->self);
                             c->self, ssh_err(r));  
                 }  
                 c->flags |= SSH_SOCKS5_AUTHDONE;                  c->flags |= SSH_SOCKS5_AUTHDONE;
                 debug2("channel %d: socks5 auth done", c->self);                  debug2("channel %d: socks5 auth done", c->self);
                 return 0;                               /* need more */                  return 0;                               /* need more */
Line 1447 
Line 1434 
                 need++;                  need++;
         if (have < need)          if (have < need)
                 return 0;                  return 0;
         if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0) {          if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0)
                 fatal("%s: channel %d: consume: %s", __func__,                  fatal_fr(r, "channel %d: consume", c->self);
                     c->self, ssh_err(r));  
         }  
         if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {          if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
                 /* host string length */                  /* host string length */
                 if ((r = sshbuf_consume(input, 1)) != 0) {                  if ((r = sshbuf_consume(input, 1)) != 0)
                         fatal("%s: channel %d: consume: %s", __func__,                          fatal_fr(r, "channel %d: consume", c->self);
                             c->self, ssh_err(r));  
                 }  
         }          }
         if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||          if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||
             (r = sshbuf_get(input, &dest_port, 2)) != 0) {              (r = sshbuf_get(input, &dest_port, 2)) != 0) {
                 debug("channel %d: parse addr/port: %s", c->self, ssh_err(r));                  debug_r(r, "channel %d: parse addr/port", c->self);
                 return -1;                  return -1;
         }          }
         dest_addr[addrlen] = '\0';          dest_addr[addrlen] = '\0';
Line 1492 
Line 1475 
         if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||          if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||
             (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||              (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||
             (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)              (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)
                 fatal("%s: channel %d: append reply: %s", __func__,                  fatal_fr(r, "channel %d: append reply", c->self);
                     c->self, ssh_err(r));  
         return 1;          return 1;
 }  }
   
Line 1503 
Line 1485 
 {  {
         Channel *c;          Channel *c;
   
         debug("%s %s:%d", __func__, host_to_connect, port_to_connect);          debug_f("%s:%d", host_to_connect, port_to_connect);
   
         c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,          c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,
             -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,              -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
Line 1592 
Line 1574 
         /* sshbuf_dump(c->output, stderr); */          /* sshbuf_dump(c->output, stderr); */
         /* EOF received */          /* EOF received */
         if (c->flags & CHAN_EOF_RCVD) {          if (c->flags & CHAN_EOF_RCVD) {
                 if ((r = sshbuf_consume(c->output, have)) != 0) {                  if ((r = sshbuf_consume(c->output, have)) != 0)
                         fatal("%s: channel %d: consume: %s",                          fatal_fr(r, "channel %d: consume", c->self);
                             __func__, c->self, ssh_err(r));  
                 }  
                 rdynamic_close(ssh, c);                  rdynamic_close(ssh, c);
                 return;                  return;
         }          }
Line 1627 
Line 1607 
                             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||                              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
                             (r = sshpkt_put_stringb(ssh, c->input)) != 0 ||                              (r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
                             (r = sshpkt_send(ssh)) != 0) {                              (r = sshpkt_send(ssh)) != 0) {
                                 fatal("%s: channel %i: rdynamic: %s", __func__,                                  fatal_fr(r, "channel %i: rdynamic", c->self);
                                     c->self, ssh_err(r));  
                         }                          }
                         if ((r = sshbuf_consume(c->input, len)) != 0) {                          if ((r = sshbuf_consume(c->input, len)) != 0)
                                 fatal("%s: channel %d: consume: %s",                                  fatal_fr(r, "channel %d: consume", c->self);
                                     __func__, c->self, ssh_err(r));  
                         }  
                         c->remote_window -= len;                          c->remote_window -= len;
                 }                  }
         } else if (rdynamic_connect_finish(ssh, c) < 0) {          } else if (rdynamic_connect_finish(ssh, c) < 0) {
Line 1686 
Line 1663 
         open_preamble(ssh, __func__, nc, "x11");          open_preamble(ssh, __func__, nc, "x11");
         if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||          if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
             (r = sshpkt_put_u32(ssh, remote_port)) != 0) {              (r = sshpkt_put_u32(ssh, remote_port)) != 0) {
                 fatal("%s: channel %i: reply %s", __func__,                  fatal_fr(r, "channel %i: reply", c->self);
                     c->self, ssh_err(r));  
         }          }
         if ((r = sshpkt_send(ssh)) != 0)          if ((r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i: send", c->self);
         free(remote_ipaddr);          free(remote_ipaddr);
 }  }
   
Line 1721 
Line 1697 
         if (strcmp(rtype, "direct-tcpip") == 0) {          if (strcmp(rtype, "direct-tcpip") == 0) {
                 /* target host, port */                  /* target host, port */
                 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||                  if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
                     (r = sshpkt_put_u32(ssh, c->host_port)) != 0) {                      (r = sshpkt_put_u32(ssh, c->host_port)) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {          } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
                 /* target path */                  /* target path */
                 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {                  if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {          } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
                 /* listen path */                  /* listen path */
                 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {                  if ((r = sshpkt_put_cstring(ssh, c->path)) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         } else {          } else {
                 /* listen address, port */                  /* listen address, port */
                 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||                  if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
                     (r = sshpkt_put_u32(ssh, local_port)) != 0) {                      (r = sshpkt_put_u32(ssh, local_port)) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         }          }
         if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {          if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
                 /* reserved for future owner/mode info */                  /* reserved for future owner/mode info */
                 if ((r = sshpkt_put_cstring(ssh, "")) != 0) {                  if ((r = sshpkt_put_cstring(ssh, "")) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         } else {          } else {
                 /* originator host and port */                  /* originator host and port */
                 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||                  if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
                     (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0) {                      (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0)
                         fatal("%s: channel %i: reply %s", __func__,                          fatal_fr(r, "channel %i: reply", c->self);
                             c->self, ssh_err(r));  
                 }  
         }          }
         if ((r = sshpkt_send(ssh)) != 0)          if ((r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i: send", c->self);
         free(remote_ipaddr);          free(remote_ipaddr);
         free(local_ipaddr);          free(local_ipaddr);
 }  }
Line 1860 
Line 1824 
             0, "accepted auth socket", 1);              0, "accepted auth socket", 1);
         open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");          open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");
         if ((r = sshpkt_send(ssh)) != 0)          if ((r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));                  fatal_fr(r, "channel %i", c->self);
 }  }
   
 static void  static void
Line 1873 
Line 1837 
         if (!FD_ISSET(c->sock, writeset))          if (!FD_ISSET(c->sock, writeset))
                 return;                  return;
         if (!c->have_remote_id)          if (!c->have_remote_id)
                 fatal(":%s: channel %d: no remote id", __func__, c->self);                  fatal_f("channel %d: no remote id", c->self);
         /* for rdynamic the OPEN_CONFIRMATION has been sent already */          /* for rdynamic the OPEN_CONFIRMATION has been sent already */
         isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);          isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);
         if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) {          if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) == -1) {
Line 1893 
Line 1857 
                             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||                              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
                             (r = sshpkt_put_u32(ssh, c->self)) != 0 ||                              (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
                             (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||                              (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
                             (r = sshpkt_put_u32(ssh, c->local_maxpacket))                              (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
                             != 0)                              (r = sshpkt_send(ssh)) != 0)
                                 fatal("%s: channel %i: confirm: %s", __func__,                                  fatal_fr(r, "channel %i open confirm", c->self);
                                     c->self, ssh_err(r));  
                         if ((r = sshpkt_send(ssh)) != 0)  
                                 fatal("%s: channel %i: %s", __func__, c->self,  
                                     ssh_err(r));  
                 }                  }
         } else {          } else {
                 debug("channel %d: connection failed: %s",                  debug("channel %d: connection failed: %s",
Line 1924 
Line 1884 
                             (r = sshpkt_put_u32(ssh,                              (r = sshpkt_put_u32(ssh,
                             SSH2_OPEN_CONNECT_FAILED)) != 0 ||                              SSH2_OPEN_CONNECT_FAILED)) != 0 ||
                             (r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||                              (r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
                             (r = sshpkt_put_cstring(ssh, "")) != 0) {                              (r = sshpkt_put_cstring(ssh, "")) != 0 ||
                                 fatal("%s: channel %i: failure: %s", __func__,                              (r = sshpkt_send(ssh)) != 0)
                                     c->self, ssh_err(r));                                  fatal_fr(r, "channel %i: failure", c->self);
                         }  
                         if ((r = sshpkt_send(ssh)) != 0)  
                                 fatal("%s: channel %i: %s", __func__, c->self,  
                                     ssh_err(r));  
                         chan_mark_dead(ssh, c);                          chan_mark_dead(ssh, c);
                 }                  }
         }          }
Line 1969 
Line 1925 
                 }                  }
         } else if (c->datagram) {          } else if (c->datagram) {
                 if ((r = sshbuf_put_string(c->input, buf, len)) != 0)                  if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
                         fatal("%s: channel %d: put datagram: %s", __func__,                          fatal_fr(r, "channel %i: put datagram", c->self);
                             c->self, ssh_err(r));          } else if ((r = sshbuf_put(c->input, buf, len)) != 0)
         } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {                  fatal_fr(r, "channel %i: put data", c->self);
                 fatal("%s: channel %d: put data: %s", __func__,  
                     c->self, ssh_err(r));  
         }  
         return 1;          return 1;
 }  }
   
Line 2004 
Line 1957 
                 }                  }
         } else if (c->datagram) {          } else if (c->datagram) {
                 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)                  if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
                         fatal("%s: channel %d: get datagram: %s", __func__,                          fatal_fr(r, "channel %i: get datagram", c->self);
                             c->self, ssh_err(r));  
                 buf = data;                  buf = data;
         } else {          } else {
                 buf = data = sshbuf_mutable_ptr(c->output);                  buf = data = sshbuf_mutable_ptr(c->output);
Line 2048 
Line 2000 
                          */                           */
                         if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||                          if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
                             (r = sshpkt_send(ssh)) != 0)                              (r = sshpkt_send(ssh)) != 0)
                                 fatal("%s: channel %d: ignore: %s",                                  fatal_fr(r, "channel %i: ignore", c->self);
                                     __func__, c->self, ssh_err(r));  
                 }                  }
         }          }
         if ((r = sshbuf_consume(c->output, len)) != 0) {          if ((r = sshbuf_consume(c->output, len)) != 0)
                 fatal("%s: channel %d: consume: %s",                  fatal_fr(r, "channel %i: consume", c->self);
                     __func__, c->self, ssh_err(r));  
         }  
  out:   out:
         c->local_consumed += olen - sshbuf_len(c->output);          c->local_consumed += olen - sshbuf_len(c->output);
   
Line 2081 
Line 2030 
                 debug2("channel %d: closing write-efd %d", c->self, c->efd);                  debug2("channel %d: closing write-efd %d", c->self, c->efd);
                 channel_close_fd(ssh, &c->efd);                  channel_close_fd(ssh, &c->efd);
         } else {          } else {
                 if ((r = sshbuf_consume(c->extended, len)) != 0) {                  if ((r = sshbuf_consume(c->extended, len)) != 0)
                         fatal("%s: channel %d: consume: %s",                          fatal_fr(r, "channel %i: consume", c->self);
                             __func__, c->self, ssh_err(r));  
                 }  
                 c->local_consumed += len;                  c->local_consumed += len;
         }          }
         return 1;          return 1;
Line 2106 
Line 2053 
         if (len == -1 && (errno == EINTR || errno == EAGAIN))          if (len == -1 && (errno == EINTR || errno == EAGAIN))
                 return 1;                  return 1;
         if (len <= 0) {          if (len <= 0) {
                 debug2("channel %d: closing read-efd %d",                  debug2("channel %d: closing read-efd %d", c->self, c->efd);
                     c->self, c->efd);  
                 channel_close_fd(ssh, &c->efd);                  channel_close_fd(ssh, &c->efd);
         } else {          } else if (c->extended_usage == CHAN_EXTENDED_IGNORE)
                 if (c->extended_usage == CHAN_EXTENDED_IGNORE) {                  debug3("channel %d: discard efd", c->self);
                         debug3("channel %d: discard efd",          else if ((r = sshbuf_put(c->extended, buf, len)) != 0)
                             c->self);                  fatal_fr(r, "channel %i: append", c->self);
                 } else if ((r = sshbuf_put(c->extended, buf, len)) != 0) {  
                         fatal("%s: channel %d: append: %s",  
                             __func__, c->self, ssh_err(r));  
                 }  
         }  
         return 1;          return 1;
 }  }
   
Line 2151 
Line 2092 
             c->local_window < c->local_window_max/2) &&              c->local_window < c->local_window_max/2) &&
             c->local_consumed > 0) {              c->local_consumed > 0) {
                 if (!c->have_remote_id)                  if (!c->have_remote_id)
                         fatal(":%s: channel %d: no remote id",                          fatal_f("channel %d: no remote id", c->self);
                             __func__, c->self);  
                 if ((r = sshpkt_start(ssh,                  if ((r = sshpkt_start(ssh,
                     SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||                      SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
                     (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||                      (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
                     (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||                      (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0) {                      (r = sshpkt_send(ssh)) != 0) {
                         fatal("%s: channel %i: %s", __func__,                          fatal_fr(r, "channel %i", c->self);
                             c->self, ssh_err(r));  
                 }                  }
                 debug2("channel %d: window %d sent adjust %d",                  debug2("channel %d: window %d sent adjust %d", c->self,
                     c->self, c->local_window,                      c->local_window, c->local_consumed);
                     c->local_consumed);  
                 c->local_window += c->local_consumed;                  c->local_window += c->local_consumed;
                 c->local_consumed = 0;                  c->local_consumed = 0;
         }          }
Line 2198 
Line 2136 
                             c->self, c->rfd, len);                              c->self, c->rfd, len);
                         chan_read_failed(ssh, c);                          chan_read_failed(ssh, c);
                         return 0;                          return 0;
                 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {                  } else if ((r = sshbuf_put(c->input, buf, len)) != 0)
                         fatal("%s: channel %d: append: %s",                          fatal_fr(r, "channel %i: append", c->self);
                             __func__, c->self, ssh_err(r));  
                 }  
         }          }
         return sshbuf_len(c->input);          return sshbuf_len(c->input);
 }  }
Line 2262 
Line 2198 
                 return;                  return;
         }          }
         if ((r = sshbuf_consume(c->output, len)) != 0)          if ((r = sshbuf_consume(c->output, len)) != 0)
                 fatal("%s: channel %d: consume: %s", __func__,                  fatal_fr(r, "channel %i: consume", c->self);
                     c->self, ssh_err(r));  
 }  }
   
 static void  static void
Line 2297 
Line 2232 
         addrlen = sizeof(addr);          addrlen = sizeof(addr);
         if ((newsock = accept(c->sock, (struct sockaddr*)&addr,          if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
             &addrlen)) == -1) {              &addrlen)) == -1) {
                 error("%s accept: %s", __func__, strerror(errno));                  error_f("accept: %s", strerror(errno));
                 if (errno == EMFILE || errno == ENFILE)                  if (errno == EMFILE || errno == ENFILE)
                         c->notbefore = monotime() + 1;                          c->notbefore = monotime() + 1;
                 return;                  return;
         }          }
   
         if (getpeereid(newsock, &euid, &egid) == -1) {          if (getpeereid(newsock, &euid, &egid) == -1) {
                 error("%s getpeereid failed: %s", __func__,                  error_f("getpeereid failed: %s", strerror(errno));
                     strerror(errno));  
                 close(newsock);                  close(newsock);
                 return;                  return;
         }          }
Line 2319 
Line 2253 
             newsock, newsock, -1, c->local_window_max,              newsock, newsock, -1, c->local_window_max,
             c->local_maxpacket, 0, "mux-control", 1);              c->local_maxpacket, 0, "mux-control", 1);
         nc->mux_rcb = c->mux_rcb;          nc->mux_rcb = c->mux_rcb;
         debug3("%s: new mux channel %d fd %d", __func__, nc->self, nc->sock);          debug3_f("new mux channel %d fd %d", nc->self, nc->sock);
         /* establish state */          /* establish state */
         nc->mux_rcb(ssh, nc);          nc->mux_rcb(ssh, nc);
         /* mux state transitions must not elicit protocol messages */          /* mux state transitions must not elicit protocol messages */
Line 2333 
Line 2267 
   
         if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||          if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||
            (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)             (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
                 fatal("%s: allocation failed", __func__);                  fatal_f("allocation failed");
   
         pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open;          pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open;
         pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;          pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
Line 2425 
Line 2359 
                                  * Collect the time that the earliest                                   * Collect the time that the earliest
                                  * channel comes off pause.                                   * channel comes off pause.
                                  */                                   */
                                 debug3("%s: chan %d: skip for %d more seconds",                                  debug3_f("chan %d: skip for %d more "
                                     __func__, c->self,                                      "seconds", c->self,
                                     (int)(c->notbefore - now));                                      (int)(c->notbefore - now));
                                 if (*unpause_secs == 0 ||                                  if (*unpause_secs == 0 ||
                                     (c->notbefore - now) < *unpause_secs)                                      (c->notbefore - now) < *unpause_secs)
Line 2436 
Line 2370 
                 channel_garbage_collect(ssh, c);                  channel_garbage_collect(ssh, c);
         }          }
         if (unpause_secs != NULL && *unpause_secs != 0)          if (unpause_secs != NULL && *unpause_secs != 0)
                 debug3("%s: first channel unpauses in %d seconds",                  debug3_f("first channel unpauses in %d seconds",
                     __func__, (int)*unpause_secs);                      (int)*unpause_secs);
 }  }
   
 /*  /*
Line 2536 
Line 2470 
         }          }
   
         if (!c->have_remote_id)          if (!c->have_remote_id)
                 fatal(":%s: channel %d: no remote id", __func__, c->self);                  fatal_f("channel %d: no remote id", c->self);
   
         if (c->datagram) {          if (c->datagram) {
                 /* Check datagram will fit; drop if not */                  /* Check datagram will fit; drop if not */
                 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)                  if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)
                         fatal("%s: channel %d: get datagram: %s", __func__,                          fatal_fr(r, "channel %i: get datagram", c->self);
                             c->self, ssh_err(r));  
                 /*                  /*
                  * XXX this does tail-drop on the datagram queue which is                   * XXX this does tail-drop on the datagram queue which is
                  * usually suboptimal compared to head-drop. Better to have                   * usually suboptimal compared to head-drop. Better to have
Line 2556 
Line 2489 
                 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||                  if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
                     (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||                      (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
                     (r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||                      (r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0) {                      (r = sshpkt_send(ssh)) != 0)
                         fatal("%s: channel %i: datagram: %s", __func__,                          fatal_fr(r, "channel %i: send datagram", c->self);
                             c->self, ssh_err(r));  
                 }  
                 c->remote_window -= plen;                  c->remote_window -= plen;
                 return;                  return;
         }          }
Line 2574 
Line 2505 
         if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
             (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||              (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
             (r = sshpkt_send(ssh)) != 0) {              (r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: data: %s", __func__,                  fatal_fr(r, "channel %i: send data", c->self);
                     c->self, ssh_err(r));  
         }  
         if ((r = sshbuf_consume(c->input, len)) != 0)          if ((r = sshbuf_consume(c->input, len)) != 0)
                 fatal("%s: channel %i: consume: %s", __func__,                  fatal_fr(r, "channel %i: consume", c->self);
                     c->self, ssh_err(r));  
         c->remote_window -= len;          c->remote_window -= len;
 }  }
   
Line 2605 
Line 2533 
         if (len == 0)          if (len == 0)
                 return;                  return;
         if (!c->have_remote_id)          if (!c->have_remote_id)
                 fatal(":%s: channel %d: no remote id", __func__, c->self);                  fatal_f("channel %d: no remote id", c->self);
         if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
             (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||              (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
             (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||              (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||
             (r = sshpkt_send(ssh)) != 0) {              (r = sshpkt_send(ssh)) != 0)
                 fatal("%s: channel %i: data: %s", __func__,                  fatal_fr(r, "channel %i: data", c->self);
                     c->self, ssh_err(r));  
         }  
         if ((r = sshbuf_consume(c->extended, len)) != 0)          if ((r = sshbuf_consume(c->extended, len)) != 0)
                 fatal("%s: channel %i: consume: %s", __func__,                  fatal_fr(r, "channel %i: consume", c->self);
                     c->self, ssh_err(r));  
         c->remote_window -= len;          c->remote_window -= len;
         debug2("channel %d: sent ext data %zu", c->self, len);          debug2("channel %d: sent ext data %zu", c->self, len);
 }  }
Line 2713 
Line 2638 
         /* sshbuf_dump(downstream->input, stderr); */          /* sshbuf_dump(downstream->input, stderr); */
         if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))          if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
             != 0) {              != 0) {
                 error("%s: malformed message: %s", __func__, ssh_err(r));                  error_fr(r, "parse");
                 return -1;                  return -1;
         }          }
         if (have < 2) {          if (have < 2) {
                 error("%s: short message", __func__);                  error_f("short message");
                 return -1;                  return -1;
         }          }
         type = cp[1];          type = cp[1];
Line 2725 
Line 2650 
         cp += 2;          cp += 2;
         have -= 2;          have -= 2;
         if (ssh_packet_log_type(type))          if (ssh_packet_log_type(type))
                 debug3("%s: channel %u: down->up: type %u", __func__,                  debug3_f("channel %u: down->up: type %u",
                     downstream->self, type);                      downstream->self, type);
   
         switch (type) {          switch (type) {
         case SSH2_MSG_CHANNEL_OPEN:          case SSH2_MSG_CHANNEL_OPEN:
                 if ((original = sshbuf_from(cp, have)) == NULL ||                  if ((original = sshbuf_from(cp, have)) == NULL ||
                     (modified = sshbuf_new()) == NULL) {                      (modified = sshbuf_new()) == NULL) {
                         error("%s: alloc", __func__);                          error_f("alloc");
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||                  if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
                     (r = sshbuf_get_u32(original, &id)) != 0) {                      (r = sshbuf_get_u32(original, &id)) != 0) {
                         error("%s: parse error %s", __func__, ssh_err(r));                          error_fr(r, "parse");
                         goto out;                          goto out;
                 }                  }
                 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,                  c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
Line 2747 
Line 2672 
                 if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||                  if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||
                     (r = sshbuf_put_u32(modified, c->self)) != 0 ||                      (r = sshbuf_put_u32(modified, c->self)) != 0 ||
                     (r = sshbuf_putb(modified, original)) != 0) {                      (r = sshbuf_putb(modified, original)) != 0) {
                         error("%s: compose error %s", __func__, ssh_err(r));                          error_fr(r, "compose");
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         goto out;                          goto out;
                 }                  }
Line 2759 
Line 2684 
                  */                   */
                 if ((original = sshbuf_from(cp, have)) == NULL ||                  if ((original = sshbuf_from(cp, have)) == NULL ||
                     (modified = sshbuf_new()) == NULL) {                      (modified = sshbuf_new()) == NULL) {
                         error("%s: alloc", __func__);                          error_f("alloc");
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||                  if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
                     (r = sshbuf_get_u32(original, &id)) != 0) {                      (r = sshbuf_get_u32(original, &id)) != 0) {
                         error("%s: parse error %s", __func__, ssh_err(r));                          error_fr(r, "parse");
                         goto out;                          goto out;
                 }                  }
                 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,                  c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
Line 2776 
Line 2701 
                 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||                  if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
                     (r = sshbuf_put_u32(modified, c->self)) != 0 ||                      (r = sshbuf_put_u32(modified, c->self)) != 0 ||
                     (r = sshbuf_putb(modified, original)) != 0) {                      (r = sshbuf_putb(modified, original)) != 0) {
                         error("%s: compose error %s", __func__, ssh_err(r));                          error_fr(r, "compose");
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         goto out;                          goto out;
                 }                  }
                 break;                  break;
         case SSH2_MSG_GLOBAL_REQUEST:          case SSH2_MSG_GLOBAL_REQUEST:
                 if ((original = sshbuf_from(cp, have)) == NULL) {                  if ((original = sshbuf_from(cp, have)) == NULL) {
                         error("%s: alloc", __func__);                          error_f("alloc");
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {                  if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
                         error("%s: parse error %s", __func__, ssh_err(r));                          error_fr(r, "parse");
                         goto out;                          goto out;
                 }                  }
                 if (strcmp(ctype, "tcpip-forward") != 0) {                  if (strcmp(ctype, "tcpip-forward") != 0) {
                         error("%s: unsupported request %s", __func__, ctype);                          error_f("unsupported request %s", ctype);
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_u8(original, NULL)) != 0 ||                  if ((r = sshbuf_get_u8(original, NULL)) != 0 ||
                     (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||                      (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||
                     (r = sshbuf_get_u32(original, &listen_port)) != 0) {                      (r = sshbuf_get_u32(original, &listen_port)) != 0) {
                         error("%s: parse error %s", __func__, ssh_err(r));                          error_fr(r, "parse");
                         goto out;                          goto out;
                 }                  }
                 if (listen_port > 65535) {                  if (listen_port > 65535) {
                         error("%s: tcpip-forward for %s: bad port %u",                          error_f("tcpip-forward for %s: bad port %u",
                             __func__, listen_host, listen_port);                              listen_host, listen_port);
                         goto out;                          goto out;
                 }                  }
                 /* Record that connection to this host/port is permitted. */                  /* Record that connection to this host/port is permitted. */
Line 2826 
Line 2751 
                 if ((r = sshpkt_start(ssh, type)) != 0 ||                  if ((r = sshpkt_start(ssh, type)) != 0 ||
                     (r = sshpkt_putb(ssh, modified)) != 0 ||                      (r = sshpkt_putb(ssh, modified)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0) {                      (r = sshpkt_send(ssh)) != 0) {
                         error("%s: send %s", __func__, ssh_err(r));                          error_fr(r, "send");
                         goto out;                          goto out;
                 }                  }
         } else {          } else {
                 if ((r = sshpkt_start(ssh, type)) != 0 ||                  if ((r = sshpkt_start(ssh, type)) != 0 ||
                     (r = sshpkt_put(ssh, cp, have)) != 0 ||                      (r = sshpkt_put(ssh, cp, have)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0) {                      (r = sshpkt_send(ssh)) != 0) {
                         error("%s: send %s", __func__, ssh_err(r));                          error_fr(r, "send");
                         goto out;                          goto out;
                 }                  }
         }          }
Line 2884 
Line 2809 
         case SSH2_MSG_CHANNEL_REQUEST:          case SSH2_MSG_CHANNEL_REQUEST:
                 break;                  break;
         default:          default:
                 debug2("%s: channel %u: unsupported type %u", __func__,                  debug2_f("channel %u: unsupported type %u", c->self, type);
                     c->self, type);  
                 return 0;                  return 0;
         }          }
         if ((b = sshbuf_new()) == NULL) {          if ((b = sshbuf_new()) == NULL) {
                 error("%s: alloc reply", __func__);                  error_f("alloc reply");
                 goto out;                  goto out;
         }          }
         /* get remaining payload (after id) */          /* get remaining payload (after id) */
         cp = sshpkt_ptr(ssh, &len);          cp = sshpkt_ptr(ssh, &len);
         if (cp == NULL) {          if (cp == NULL) {
                 error("%s: no packet", __func__);                  error_f("no packet");
                 goto out;                  goto out;
         }          }
         /* translate id and send to muxclient */          /* translate id and send to muxclient */
Line 2904 
Line 2828 
             (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||              (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
             (r = sshbuf_put(b, cp, len)) != 0 ||              (r = sshbuf_put(b, cp, len)) != 0 ||
             (r = sshbuf_put_stringb(downstream->output, b)) != 0) {              (r = sshbuf_put_stringb(downstream->output, b)) != 0) {
                 error("%s: compose for muxclient %s", __func__, ssh_err(r));                  error_fr(r, "compose muxclient");
                 goto out;                  goto out;
         }          }
         /* sshbuf_dump(b, stderr); */          /* sshbuf_dump(b, stderr); */
         if (ssh_packet_log_type(type))          if (ssh_packet_log_type(type))
                 debug3("%s: channel %u: up->down: type %u", __func__, c->self,                  debug3_f("channel %u: up->down: type %u", c->self, type);
                     type);  
  out:   out:
         /* update state */          /* update state */
         switch (type) {          switch (type) {
Line 2942 
Line 2865 
         int r;          int r;
   
         if ((r = sshpkt_get_u32(ssh, &id)) != 0) {          if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
                 error("%s: parse id: %s", where, ssh_err(r));                  error_r(r, "%s: parse id", where);
                 ssh_packet_disconnect(ssh, "Invalid %s message", what);                  ssh_packet_disconnect(ssh, "Invalid %s message", what);
         }          }
         if (id > INT_MAX) {          if (id > INT_MAX) {
                 error("%s: bad channel id %u: %s", where, id, ssh_err(r));                  error_r(r, "%s: bad channel id %u", where, id);
                 ssh_packet_disconnect(ssh, "Invalid %s channel id", what);                  ssh_packet_disconnect(ssh, "Invalid %s channel id", what);
         }          }
         return (int)id;          return (int)id;
Line 2987 
Line 2910 
         /* Get the data. */          /* Get the data. */
         if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||          if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
             (r = sshpkt_get_end(ssh)) != 0)              (r = sshpkt_get_end(ssh)) != 0)
                 fatal("%s: channel %d: get data: %s", __func__,                  fatal_fr(r, "channel %i: get data", c->self);
                     c->self, ssh_err(r));  
   
         win_len = data_len;          win_len = data_len;
         if (c->datagram)          if (c->datagram)
Line 3019 
Line 2941 
   
         if (c->datagram) {          if (c->datagram) {
                 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)                  if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
                         fatal("%s: channel %d: append datagram: %s",                          fatal_fr(r, "channel %i: append datagram", c->self);
                             __func__, c->self, ssh_err(r));  
         } else if ((r = sshbuf_put(c->output, data, data_len)) != 0)          } else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
                 fatal("%s: channel %d: append data: %s",                  fatal_fr(r, "channel %i: append data", c->self);
                     __func__, c->self, ssh_err(r));  
   
         return 0;          return 0;
 }  }
Line 3053 
Line 2973 
         }          }
   
         if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {          if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
                 error("%s: parse tcode: %s", __func__, ssh_err(r));                  error_fr(r, "parse tcode");
                 ssh_packet_disconnect(ssh, "Invalid extended_data message");                  ssh_packet_disconnect(ssh, "Invalid extended_data message");
         }          }
         if (c->efd == -1 ||          if (c->efd == -1 ||
Line 3064 
Line 2984 
         }          }
         if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||          if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
             (r = sshpkt_get_end(ssh)) != 0) {              (r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: parse data: %s", __func__, ssh_err(r));                  error_fr(r, "parse data");
                 ssh_packet_disconnect(ssh, "Invalid extended_data message");                  ssh_packet_disconnect(ssh, "Invalid extended_data message");
         }          }
   
Line 3076 
Line 2996 
         debug2("channel %d: rcvd ext data %zu", c->self, data_len);          debug2("channel %d: rcvd ext data %zu", c->self, data_len);
         /* XXX sshpkt_getb? */          /* XXX sshpkt_getb? */
         if ((r = sshbuf_put(c->extended, data, data_len)) != 0)          if ((r = sshbuf_put(c->extended, data, data_len)) != 0)
                 error("%s: append: %s", __func__, ssh_err(r));                  error_fr(r, "append");
         c->local_window -= data_len;          c->local_window -= data_len;
         return 0;          return 0;
 }  }
Line 3088 
Line 3008 
         int r;          int r;
   
         if ((r = sshpkt_get_end(ssh)) != 0) {          if ((r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: parse data: %s", __func__, ssh_err(r));                  error_fr(r, "parse data");
                 ssh_packet_disconnect(ssh, "Invalid ieof message");                  ssh_packet_disconnect(ssh, "Invalid ieof message");
         }          }
   
Line 3115 
Line 3035 
         if (channel_proxy_upstream(c, type, seq, ssh))          if (channel_proxy_upstream(c, type, seq, ssh))
                 return 0;                  return 0;
         if ((r = sshpkt_get_end(ssh)) != 0) {          if ((r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: parse data: %s", __func__, ssh_err(r));                  error_fr(r, "parse data");
                 ssh_packet_disconnect(ssh, "Invalid oclose message");                  ssh_packet_disconnect(ssh, "Invalid oclose message");
         }          }
         chan_rcvd_oclose(ssh, c);          chan_rcvd_oclose(ssh, c);
Line 3142 
Line 3062 
             (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||              (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
             (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||              (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||
             (r = sshpkt_get_end(ssh)) != 0) {              (r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: window/maxpacket: %s", __func__, ssh_err(r));                  error_fr(r, "window/maxpacket");
                 ssh_packet_disconnect(ssh, "Invalid open confirmation message");                  ssh_packet_disconnect(ssh, "Invalid open confirmation message");
         }          }
   
Line 3151 
Line 3071 
         c->remote_maxpacket = remote_maxpacket;          c->remote_maxpacket = remote_maxpacket;
         c->type = SSH_CHANNEL_OPEN;          c->type = SSH_CHANNEL_OPEN;
         if (c->open_confirm) {          if (c->open_confirm) {
                 debug2("%s: channel %d: callback start", __func__, c->self);                  debug2_f("channel %d: callback start", c->self);
                 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);                  c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
                 debug2("%s: channel %d: callback done", __func__, c->self);                  debug2_f("channel %d: callback done", c->self);
         }          }
         debug2("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);
Line 3190 
Line 3110 
                 ssh_packet_disconnect(ssh, "Received open failure for "                  ssh_packet_disconnect(ssh, "Received open failure for "
                     "non-opening channel %d.", c->self);                      "non-opening channel %d.", c->self);
         if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {          if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
                 error("%s: reason: %s", __func__, ssh_err(r));                  error_fr(r, "parse reason");
                 ssh_packet_disconnect(ssh, "Invalid open failure message");                  ssh_packet_disconnect(ssh, "Invalid open failure message");
         }          }
         /* skip language */          /* skip language */
         if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||          if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
             (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||              (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||
             (r = sshpkt_get_end(ssh)) != 0) {              (r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: message/lang: %s", __func__, ssh_err(r));                  error_fr(r, "parse msg/lang");
                 ssh_packet_disconnect(ssh, "Invalid open failure message");                  ssh_packet_disconnect(ssh, "Invalid open failure message");
         }          }
         logit("channel %d: open failed: %s%s%s", c->self,          logit("channel %d: open failed: %s%s%s", c->self,
             reason2txt(reason), msg ? ": ": "", msg ? msg : "");              reason2txt(reason), msg ? ": ": "", msg ? msg : "");
         free(msg);          free(msg);
         if (c->open_confirm) {          if (c->open_confirm) {
                 debug2("%s: channel %d: callback start", __func__, c->self);                  debug2_f("channel %d: callback start", c->self);
                 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);                  c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);
                 debug2("%s: channel %d: callback done", __func__, c->self);                  debug2_f("channel %d: callback done", c->self);
         }          }
         /* Schedule the channel for cleanup/deletion. */          /* Schedule the channel for cleanup/deletion. */
         chan_mark_dead(ssh, c);          chan_mark_dead(ssh, c);
Line 3231 
Line 3151 
                 return 0;                  return 0;
         if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||          if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||
             (r = sshpkt_get_end(ssh)) != 0) {              (r = sshpkt_get_end(ssh)) != 0) {
                 error("%s: adjust: %s", __func__, ssh_err(r));                  error_fr(r, "parse adjust");
                 ssh_packet_disconnect(ssh, "Invalid window adjust message");                  ssh_packet_disconnect(ssh, "Invalid window adjust message");
         }          }
         debug2("channel %d: rcvd adjust %u", c->self, adjust);          debug2("channel %d: rcvd adjust %u", c->self, adjust);
Line 3253 
Line 3173 
         /* Reset keepalive timeout */          /* Reset keepalive timeout */
         ssh_packet_set_alive_timeouts(ssh, 0);          ssh_packet_set_alive_timeouts(ssh, 0);
   
         debug2("%s: type %d id %d", __func__, type, id);          debug2_f("type %d id %d", type, id);
   
         if ((c = channel_lookup(ssh, id)) == NULL) {          if ((c = channel_lookup(ssh, id)) == NULL) {
                 logit("%s: %d: unknown", __func__, id);                  logit_f("%d: unknown", id);
                 return 0;                  return 0;
         }          }
         if (channel_proxy_upstream(c, type, seq, ssh))          if (channel_proxy_upstream(c, type, seq, ssh))
Line 3381 
Line 3301 
         /* Determine the bind address, cf. channel_fwd_bind_addr() comment */          /* Determine the bind address, cf. channel_fwd_bind_addr() comment */
         addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard,          addr = channel_fwd_bind_addr(ssh, fwd->listen_host, &wildcard,
             is_client, fwd_opts);              is_client, fwd_opts);
         debug3("%s: type %d wildcard %d addr %s", __func__,          debug3_f("type %d wildcard %d addr %s", type, wildcard,
             type, wildcard, (addr == NULL) ? "NULL" : addr);              (addr == NULL) ? "NULL" : addr);
   
         /*          /*
          * getaddrinfo returns a loopback address if the hostname is           * getaddrinfo returns a loopback address if the hostname is
Line 3399 
Line 3319 
                         ssh_packet_disconnect(ssh, "getaddrinfo: fatal error: %s",                          ssh_packet_disconnect(ssh, "getaddrinfo: fatal error: %s",
                             ssh_gai_strerror(r));                              ssh_gai_strerror(r));
                 } else {                  } else {
                         error("%s: getaddrinfo(%.64s): %s", __func__, addr,                          error_f("getaddrinfo(%.64s): %s", addr,
                             ssh_gai_strerror(r));                              ssh_gai_strerror(r));
                 }                  }
                 return 0;                  return 0;
Line 3431 
Line 3351 
                 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),                  if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
                     strport, sizeof(strport),                      strport, sizeof(strport),
                     NI_NUMERICHOST|NI_NUMERICSERV) != 0) {                      NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
                         error("%s: getnameinfo failed", __func__);                          error_f("getnameinfo failed");
                         continue;                          continue;
                 }                  }
                 /* Create a port to listen for the host. */                  /* Create a port to listen for the host. */
Line 3495 
Line 3415 
                 success = 1;                  success = 1;
         }          }
         if (success == 0)          if (success == 0)
                 error("%s: cannot listen to port: %d", __func__,                  error_f("cannot listen to port: %d", fwd->listen_port);
                     fwd->listen_port);  
         freeaddrinfo(aitop);          freeaddrinfo(aitop);
         return success;          return success;
 }  }
Line 3539 
Line 3458 
                 port = PORT_STREAMLOCAL;                  port = PORT_STREAMLOCAL;
                 break;                  break;
         default:          default:
                 error("%s: unexpected channel type %d", __func__, type);                  error_f("unexpected channel type %d", type);
                 return 0;                  return 0;
         }          }
   
Line 3552 
Line 3471 
                 return 0;                  return 0;
         }          }
   
         debug3("%s: type %d path %s", __func__, type, fwd->listen_path);          debug3_f("type %d path %s", type, fwd->listen_path);
   
         /* Start a Unix domain listener. */          /* Start a Unix domain listener. */
         omask = umask(fwd_opts->streamlocal_bind_mask);          omask = umask(fwd_opts->streamlocal_bind_mask);
Line 3587 
Line 3506 
                 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)                  if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
                         continue;                          continue;
                 if (strcmp(c->path, host) == 0 && c->listening_port == port) {                  if (strcmp(c->path, host) == 0 && c->listening_port == port) {
                         debug2("%s: close channel %d", __func__, i);                          debug2_f("close channel %d", i);
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         found = 1;                          found = 1;
                 }                  }
Line 3609 
Line 3528 
                 if (c->path == NULL)                  if (c->path == NULL)
                         continue;                          continue;
                 if (strcmp(c->path, path) == 0) {                  if (strcmp(c->path, path) == 0) {
                         debug2("%s: close channel %d", __func__, i);                          debug2_f("close channel %d", i);
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         found = 1;                          found = 1;
                 }                  }
Line 3657 
Line 3576 
                     (c->listening_addr != NULL && addr == NULL))                      (c->listening_addr != NULL && addr == NULL))
                         continue;                          continue;
                 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {                  if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
                         debug2("%s: close channel %d", __func__, i);                          debug2_f("close channel %d", i);
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         found = 1;                          found = 1;
                 }                  }
Line 3673 
Line 3592 
         int found = 0;          int found = 0;
   
         if (path == NULL) {          if (path == NULL) {
                 error("%s: no path specified.", __func__);                  error_f("no path specified.");
                 return 0;                  return 0;
         }          }
   
Line 3684 
Line 3603 
                 if (c->listening_addr == NULL)                  if (c->listening_addr == NULL)
                         continue;                          continue;
                 if (strcmp(c->listening_addr, path) == 0) {                  if (strcmp(c->listening_addr, path) == 0) {
                         debug2("%s: close channel %d", __func__, i);                          debug2_f("close channel %d", i);
                         channel_free(ssh, c);                          channel_free(ssh, c);
                         found = 1;                          found = 1;
                 }                  }
Line 3856 
Line 3775 
                     (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||                      (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0 ||                      (r = sshpkt_send(ssh)) != 0 ||
                     (r = ssh_packet_write_wait(ssh)) != 0)                      (r = ssh_packet_write_wait(ssh)) != 0)
                         fatal("%s: request streamlocal: %s",                          fatal_fr(r, "request streamlocal");
                             __func__, ssh_err(r));  
         } else {          } else {
                 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||                  if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
                     (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||                      (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
Line 3867 
Line 3785 
                     (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||                      (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0 ||                      (r = sshpkt_send(ssh)) != 0 ||
                     (r = ssh_packet_write_wait(ssh)) != 0)                      (r = ssh_packet_write_wait(ssh)) != 0)
                         fatal("%s: request tcpip-forward: %s",                          fatal_fr(r, "request tcpip-forward");
                             __func__, ssh_err(r));  
         }          }
         /* Assume that server accepts the request */          /* Assume that server accepts the request */
         success = 1;          success = 1;
Line 3976 
Line 3893 
                 perm = NULL;                  perm = NULL;
         }          }
         if (perm == NULL) {          if (perm == NULL) {
                 debug("%s: requested forward not found", __func__);                  debug_f("requested forward not found");
                 return -1;                  return -1;
         }          }
         if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
Line 3985 
Line 3902 
             (r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||              (r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
             (r = sshpkt_put_u32(ssh, port)) != 0 ||              (r = sshpkt_put_u32(ssh, port)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0)
                 fatal("%s: send cancel: %s", __func__, ssh_err(r));                  fatal_fr(r, "send cancel");
   
         fwd_perm_clear(perm); /* unregister */          fwd_perm_clear(perm); /* unregister */
   
Line 4012 
Line 3929 
                 perm = NULL;                  perm = NULL;
         }          }
         if (perm == NULL) {          if (perm == NULL) {
                 debug("%s: requested forward not found", __func__);                  debug_f("requested forward not found");
                 return -1;                  return -1;
         }          }
         if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
Line 4021 
Line 3938 
             (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */              (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
             (r = sshpkt_put_cstring(ssh, path)) != 0 ||              (r = sshpkt_put_cstring(ssh, path)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0)
                 fatal("%s: send cancel: %s", __func__, ssh_err(r));                  fatal_fr(r, "send cancel");
   
         fwd_perm_clear(perm); /* unregister */          fwd_perm_clear(perm); /* unregister */
   
Line 4116 
Line 4033 
         struct permission_set *pset = &ssh->chanctxt->local_perms;          struct permission_set *pset = &ssh->chanctxt->local_perms;
   
         if (idx < 0 || (u_int)idx >= pset->num_permitted_user) {          if (idx < 0 || (u_int)idx >= pset->num_permitted_user) {
                 debug("%s: index out of range: %d num_permitted_user %d",                  debug_f("index out of range: %d num_permitted_user %d",
                     __func__, idx, pset->num_permitted_user);                      idx, pset->num_permitted_user);
                 return;                  return;
         }          }
         debug("%s allowed port %d for forwarding to host %s port %d",          debug("%s allowed port %d for forwarding to host %s port %d",
Line 4184 
Line 4101 
                         continue;                          continue;
                 }                  }
                 if (set_nonblock(sock) == -1)                  if (set_nonblock(sock) == -1)
                         fatal("%s: set_nonblock(%d)", __func__, sock);                          fatal_f("set_nonblock(%d)", sock);
                 if (connect(sock, cctx->ai->ai_addr,                  if (connect(sock, cctx->ai->ai_addr,
                     cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {                      cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
                         debug("connect_next: host %.100s ([%.100s]:%s): "                          debug("connect_next: host %.100s ([%.100s]:%s): "
Line 4487 
Line 4404 
                     (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||                      (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
                     (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||                      (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
                     (r = sshpkt_send(ssh)) != 0)                      (r = sshpkt_send(ssh)) != 0)
                         fatal("%s: channel %u: send window-change: %s",                          fatal_fr(r, "channel %u; send window-change", i);
                             __func__, i, ssh_err(r));  
         }          }
 }  }
   
Line 4512 
Line 4428 
             (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||              (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->self)) != 0 ||              (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||              (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
             (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {              (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0)
                 fatal("%s: channel %i: confirm: %s", __func__,                  fatal_fr(r, "channel %i; confirm", c->self);
                     c->self, ssh_err(r));  
         }  
         return c;          return c;
 }  }
   
Line 4589 
Line 4503 
                         }                          }
                         set_reuseaddr(sock);                          set_reuseaddr(sock);
                         if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {                          if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
                                 debug2("%s: bind port %d: %.100s", __func__,                                  debug2_f("bind port %d: %.100s", port,
                                     port, strerror(errno));                                      strerror(errno));
                                 close(sock);                                  close(sock);
                                 for (n = 0; n < num_socks; n++)                                  for (n = 0; n < num_socks; n++)
                                         close(socks[n]);                                          close(socks[n]);
Line 4795 
Line 4709 
                 /* Extract real authentication data. */                  /* Extract real authentication data. */
                 sc->x11_saved_data = xmalloc(data_len);                  sc->x11_saved_data = xmalloc(data_len);
                 for (i = 0; i < data_len; i++) {                  for (i = 0; i < data_len; i++) {
                         if (sscanf(data + 2 * i, "%2x", &value) != 1)                          if (sscanf(data + 2 * i, "%2x", &value) != 1) {
                                 fatal("x11_request_forwarding: bad "                                  fatal("x11_request_forwarding: bad "
                                     "authentication data: %.100s", data);                                      "authentication data: %.100s", data);
                           }
                         sc->x11_saved_data[i] = value;                          sc->x11_saved_data[i] = value;
                 }                  }
                 sc->x11_saved_data_len = data_len;                  sc->x11_saved_data_len = data_len;
Line 4819 
Line 4734 
             (r = sshpkt_put_u32(ssh, screen_number)) != 0 ||              (r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
             (r = sshpkt_send(ssh)) != 0 ||              (r = sshpkt_send(ssh)) != 0 ||
             (r = ssh_packet_write_wait(ssh)) != 0)              (r = ssh_packet_write_wait(ssh)) != 0)
                 fatal("%s: send x11-req: %s", __func__, ssh_err(r));                  fatal_fr(r, "send x11-req");
         free(new_data);          free(new_data);
 }  }

Legend:
Removed from v.1.402  
changed lines
  Added in v.1.403