[BACK]Return to mux.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/mux.c between version 1.84 and 1.85

version 1.84, 2020/10/03 09:22:26 version 1.85, 2020/10/18 11:32:01
Line 181 
Line 181 
 {  {
         Channel *cc, *c = channel_by_id(ssh, cid);          Channel *cc, *c = channel_by_id(ssh, cid);
   
         debug3("%s: entering for channel %d", __func__, cid);          debug3_f("entering for channel %d", cid);
         if (c == NULL)          if (c == NULL)
                 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);                  fatal_f("channel_by_id(%i) == NULL", cid);
         if (c->ctl_chan != -1) {          if (c->ctl_chan != -1) {
                 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)                  if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
                         fatal("%s: channel %d missing control channel %d",                          fatal_f("channel %d missing control channel %d",
                             __func__, c->self, c->ctl_chan);                              c->self, c->ctl_chan);
                 c->ctl_chan = -1;                  c->ctl_chan = -1;
                 cc->remote_id = 0;                  cc->remote_id = 0;
                 cc->have_remote_id = 0;                  cc->have_remote_id = 0;
Line 203 
Line 203 
 {  {
         Channel *sc, *c = channel_by_id(ssh, cid);          Channel *sc, *c = channel_by_id(ssh, cid);
   
         debug3("%s: entering for channel %d", __func__, cid);          debug3_f("entering for channel %d", cid);
         if (c == NULL)          if (c == NULL)
                 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);                  fatal_f("channel_by_id(%i) == NULL", cid);
         if (c->have_remote_id) {          if (c->have_remote_id) {
                 if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)                  if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
                         fatal("%s: channel %d missing session channel %u",                          fatal_f("channel %d missing session channel %u",
                             __func__, c->self, c->remote_id);                              c->self, c->remote_id);
                 c->remote_id = 0;                  c->remote_id = 0;
                 c->have_remote_id = 0;                  c->have_remote_id = 0;
                 sc->ctl_chan = -1;                  sc->ctl_chan = -1;
                 if (sc->type != SSH_CHANNEL_OPEN &&                  if (sc->type != SSH_CHANNEL_OPEN &&
                     sc->type != SSH_CHANNEL_OPENING) {                      sc->type != SSH_CHANNEL_OPENING) {
                         debug2("%s: channel %d: not open", __func__, sc->self);                          debug2_f("channel %d: not open", sc->self);
                         chan_mark_dead(ssh, sc);                          chan_mark_dead(ssh, sc);
                 } else {                  } else {
                         if (sc->istate == CHAN_INPUT_OPEN)                          if (sc->istate == CHAN_INPUT_OPEN)
Line 238 
Line 238 
                 return 0;                  return 0;
         ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);          ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
         if (ret <= 0 || (size_t)ret >= sizeof(name)) {          if (ret <= 0 || (size_t)ret >= sizeof(name)) {
                 error("%s: name '%.100s...' too long", __func__, env);                  error_f("name '%.100s...' too long", env);
                 return 0;                  return 0;
         }          }
   
Line 260 
Line 260 
         int r;          int r;
   
         if (state == NULL)          if (state == NULL)
                 fatal("%s: channel %d: c->mux_ctx == NULL", __func__, c->self);                  fatal_f("channel %d: c->mux_ctx == NULL", c->self);
         if (state->hello_rcvd) {          if (state->hello_rcvd) {
                 error("%s: HELLO received twice", __func__);                  error_f("HELLO received twice");
                 return -1;                  return -1;
         }          }
         if ((r = sshbuf_get_u32(m, &ver)) != 0) {          if ((r = sshbuf_get_u32(m, &ver)) != 0) {
                 error("%s: malformed message: %s", __func__, ssh_err(r));                  error_fr(r, "parse");
                 return -1;                  return -1;
         }          }
         if (ver != SSHMUX_VER) {          if (ver != SSHMUX_VER) {
                 error("%s: unsupported multiplexing protocol version %u "                  error_f("unsupported multiplexing protocol version %u "
                     "(expected %u)", __func__, ver, SSHMUX_VER);                      "(expected %u)", ver, SSHMUX_VER);
                 return -1;                  return -1;
         }          }
         debug2("%s: channel %d client version %u", __func__, c->self, ver);          debug2_f("channel %d client version %u", c->self, ver);
   
         /* No extensions are presently defined */          /* No extensions are presently defined */
         while (sshbuf_len(m) > 0) {          while (sshbuf_len(m) > 0) {
Line 283 
Line 283 
   
                 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||                  if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
                     (r = sshbuf_get_string_direct(m, NULL, &value_len)) != 0) {                      (r = sshbuf_get_string_direct(m, NULL, &value_len)) != 0) {
                         error("%s: malformed extension: %s",                          error_fr(r, "parse extension");
                             __func__, ssh_err(r));  
                         return -1;                          return -1;
                 }                  }
                 debug2("%s: Unrecognised extension \"%s\" length %zu",                  debug2_f("Unrecognised extension \"%s\" length %zu",
                     __func__, name, value_len);                      name, value_len);
                 free(name);                  free(name);
         }          }
         state->hello_rcvd = 1;          state->hello_rcvd = 1;
Line 303 
Line 302 
   
         if ((r = sshbuf_put_u32(reply, MUX_S_OK)) != 0 ||          if ((r = sshbuf_put_u32(reply, MUX_S_OK)) != 0 ||
             (r = sshbuf_put_u32(reply, rid)) != 0)              (r = sshbuf_put_u32(reply, rid)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
 }  }
   
 /* Enqueue an error response to the reply buffer */  /* Enqueue an error response to the reply buffer */
Line 315 
Line 314 
         if ((r = sshbuf_put_u32(reply, type)) != 0 ||          if ((r = sshbuf_put_u32(reply, type)) != 0 ||
             (r = sshbuf_put_u32(reply, rid)) != 0 ||              (r = sshbuf_put_u32(reply, rid)) != 0 ||
             (r = sshbuf_put_cstring(reply, msg)) != 0)              (r = sshbuf_put_cstring(reply, msg)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
 }  }
   
 static int  static int
Line 350 
Line 349 
                 free(cctx->env);                  free(cctx->env);
                 free(cctx->term);                  free(cctx->term);
                 free(cctx);                  free(cctx);
                 error("%s: malformed message", __func__);                  error_f("malformed message");
                 return -1;                  return -1;
         }          }
   
Line 367 
Line 366 
                 cctx->env[env_len++] = cp;                  cctx->env[env_len++] = cp;
                 cctx->env[env_len] = NULL;                  cctx->env[env_len] = NULL;
                 if (env_len > MUX_MAX_ENV_VARS) {                  if (env_len > MUX_MAX_ENV_VARS) {
                         error("%s: >%d environment variables received, "                          error_f(">%d environment variables received, "
                             "ignoring additional", __func__, MUX_MAX_ENV_VARS);                              "ignoring additional", MUX_MAX_ENV_VARS);
                         break;                          break;
                 }                  }
         }          }
   
         debug2("%s: channel %d: request tty %d, X %d, agent %d, subsys %d, "          debug2_f("channel %d: request tty %d, X %d, agent %d, subsys %d, "
             "term \"%s\", cmd \"%s\", env %u", __func__, c->self,              "term \"%s\", cmd \"%s\", env %u", c->self,
             cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,              cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,
             cctx->want_subsys, cctx->term, cmd, env_len);              cctx->want_subsys, cctx->term, cmd, env_len);
   
         if ((cctx->cmd = sshbuf_new()) == NULL)          if ((cctx->cmd = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put(cctx->cmd, cmd, strlen(cmd))) != 0)          if ((r = sshbuf_put(cctx->cmd, cmd, strlen(cmd))) != 0)
                 fatal("%s: sshbuf_put: %s", __func__, ssh_err(r));                  fatal_fr(r, "sshbuf_put");
         free(cmd);          free(cmd);
         cmd = NULL;          cmd = NULL;
   
         /* Gather fds from client */          /* Gather fds from client */
         for(i = 0; i < 3; i++) {          for(i = 0; i < 3; i++) {
                 if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {                  if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
                         error("%s: failed to receive fd %d from client",                          error_f("failed to receive fd %d from client", i);
                             __func__, i);  
                         for (j = 0; j < i; j++)                          for (j = 0; j < i; j++)
                                 close(new_fd[j]);                                  close(new_fd[j]);
                         for (j = 0; j < env_len; j++)                          for (j = 0; j < env_len; j++)
Line 404 
Line 402 
                 }                  }
         }          }
   
         debug3("%s: got fds stdin %d, stdout %d, stderr %d", __func__,          debug3_f("got fds stdin %d, stdout %d, stderr %d",
             new_fd[0], new_fd[1], new_fd[2]);              new_fd[0], new_fd[1], new_fd[2]);
   
         /* XXX support multiple child sessions in future */          /* XXX support multiple child sessions in future */
         if (c->have_remote_id) {          if (c->have_remote_id) {
                 debug2("%s: session already open", __func__);                  debug2_f("session already open");
                 reply_error(reply, MUX_S_FAILURE, rid,                  reply_error(reply, MUX_S_FAILURE, rid,
                     "Multiple sessions not supported");                      "Multiple sessions not supported");
  cleanup:   cleanup:
Line 430 
Line 428 
         if (options.control_master == SSHCTL_MASTER_ASK ||          if (options.control_master == SSHCTL_MASTER_ASK ||
             options.control_master == SSHCTL_MASTER_AUTO_ASK) {              options.control_master == SSHCTL_MASTER_AUTO_ASK) {
                 if (!ask_permission("Allow shared connection to %s? ", host)) {                  if (!ask_permission("Allow shared connection to %s? ", host)) {
                         debug2("%s: session refused by user", __func__);                          debug2_f("session refused by user");
                         reply_error(reply, MUX_S_PERMISSION_DENIED, rid,                          reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
                             "Permission denied");                              "Permission denied");
                         goto cleanup;                          goto cleanup;
Line 439 
Line 437 
   
         /* Try to pick up ttymodes from client before it goes raw */          /* Try to pick up ttymodes from client before it goes raw */
         if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)          if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
                 error("%s: tcgetattr: %s", __func__, strerror(errno));                  error_f("tcgetattr: %s", strerror(errno));
   
         /* enable nonblocking unless tty */          /* enable nonblocking unless tty */
         if (!isatty(new_fd[0]))          if (!isatty(new_fd[0]))
Line 471 
Line 469 
                     client_new_escape_filter_ctx((int)escape_char));                      client_new_escape_filter_ctx((int)escape_char));
         }          }
   
         debug2("%s: channel_new: %d linked to control channel %d",          debug2_f("channel_new: %d linked to control channel %d",
             __func__, nc->self, nc->ctl_chan);              nc->self, nc->ctl_chan);
   
         channel_send_open(ssh, nc->self);          channel_send_open(ssh, nc->self);
         channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);          channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);
Line 490 
Line 488 
 {  {
         int r;          int r;
   
         debug2("%s: channel %d: alive check", __func__, c->self);          debug2_f("channel %d: alive check", c->self);
   
         /* prepare reply */          /* prepare reply */
         if ((r = sshbuf_put_u32(reply, MUX_S_ALIVE)) != 0 ||          if ((r = sshbuf_put_u32(reply, MUX_S_ALIVE)) != 0 ||
             (r = sshbuf_put_u32(reply, rid)) != 0 ||              (r = sshbuf_put_u32(reply, rid)) != 0 ||
             (r = sshbuf_put_u32(reply, (u_int)getpid())) != 0)              (r = sshbuf_put_u32(reply, (u_int)getpid())) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
   
         return 0;          return 0;
 }  }
Line 505 
Line 503 
 mux_master_process_terminate(struct ssh *ssh, u_int rid,  mux_master_process_terminate(struct ssh *ssh, u_int rid,
     Channel *c, struct sshbuf *m, struct sshbuf *reply)      Channel *c, struct sshbuf *m, struct sshbuf *reply)
 {  {
         debug2("%s: channel %d: terminate request", __func__, c->self);          debug2_f("channel %d: terminate request", c->self);
   
         if (options.control_master == SSHCTL_MASTER_ASK ||          if (options.control_master == SSHCTL_MASTER_ASK ||
             options.control_master == SSHCTL_MASTER_AUTO_ASK) {              options.control_master == SSHCTL_MASTER_AUTO_ASK) {
                 if (!ask_permission("Terminate shared connection to %s? ",                  if (!ask_permission("Terminate shared connection to %s? ",
                     host)) {                      host)) {
                         debug2("%s: termination refused by user", __func__);                          debug2_f("termination refused by user");
                         reply_error(reply, MUX_S_PERMISSION_DENIED, rid,                          reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
                             "Permission denied");                              "Permission denied");
                         return 0;                          return 0;
Line 555 
Line 553 
                     fwd->connect_host, fwd->connect_port);                      fwd->connect_host, fwd->connect_port);
                 break;                  break;
         default:          default:
                 fatal("%s: unknown forward type %u", __func__, ftype);                  fatal_f("unknown forward type %u", ftype);
         }          }
         return ret;          return ret;
 }  }
Line 602 
Line 600 
   
         if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {          if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
                 /* no channel for reply */                  /* no channel for reply */
                 error("%s: unknown channel", __func__);                  error_f("unknown channel");
                 return;                  return;
         }          }
         if ((out = sshbuf_new()) == NULL)          if ((out = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if (fctx->fid >= options.num_remote_forwards ||          if (fctx->fid >= options.num_remote_forwards ||
             (options.remote_forwards[fctx->fid].connect_path == NULL &&              (options.remote_forwards[fctx->fid].connect_path == NULL &&
             options.remote_forwards[fctx->fid].connect_host == NULL)) {              options.remote_forwards[fctx->fid].connect_host == NULL)) {
Line 614 
Line 612 
                 goto fail;                  goto fail;
         }          }
         rfwd = &options.remote_forwards[fctx->fid];          rfwd = &options.remote_forwards[fctx->fid];
         debug("%s: %s for: listen %d, connect %s:%d", __func__,          debug_f("%s for: listen %d, connect %s:%d",
             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",              type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
             rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :              rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
             rfwd->connect_host, rfwd->connect_port);              rfwd->connect_host, rfwd->connect_port);
         if (type == SSH2_MSG_REQUEST_SUCCESS) {          if (type == SSH2_MSG_REQUEST_SUCCESS) {
                 if (rfwd->listen_port == 0) {                  if (rfwd->listen_port == 0) {
                         if ((r = sshpkt_get_u32(ssh, &port)) != 0)                          if ((r = sshpkt_get_u32(ssh, &port)) != 0)
                                 fatal("%s: packet error: %s",                                  fatal_fr(r, "parse port");
                                     __func__, ssh_err(r));  
                         if (port > 65535) {                          if (port > 65535) {
                                 fatal("Invalid allocated port %u for "                                  fatal("Invalid allocated port %u for "
                                     "mux remote forward to %s:%d", port,                                      "mux remote forward to %s:%d", port,
Line 637 
Line 634 
                             (r = sshbuf_put_u32(out, fctx->rid)) != 0 ||                              (r = sshbuf_put_u32(out, fctx->rid)) != 0 ||
                             (r = sshbuf_put_u32(out,                              (r = sshbuf_put_u32(out,
                             rfwd->allocated_port)) != 0)                              rfwd->allocated_port)) != 0)
                                 fatal("%s: reply: %s", __func__, ssh_err(r));                                  fatal_fr(r, "reply");
                         channel_update_permission(ssh, rfwd->handle,                          channel_update_permission(ssh, rfwd->handle,
                            rfwd->allocated_port);                             rfwd->allocated_port);
                 } else {                  } else {
Line 654 
Line 651 
                         xasprintf(&failmsg, "remote port forwarding failed for "                          xasprintf(&failmsg, "remote port forwarding failed for "
                             "listen port %d", rfwd->listen_port);                              "listen port %d", rfwd->listen_port);
   
                 debug2("%s: clearing registered forwarding for listen %d, "                  debug2_f("clearing registered forwarding for listen %d, "
                     "connect %s:%d", __func__, rfwd->listen_port,                      "connect %s:%d", rfwd->listen_port,
                     rfwd->connect_path ? rfwd->connect_path :                      rfwd->connect_path ? rfwd->connect_path :
                     rfwd->connect_host, rfwd->connect_port);                      rfwd->connect_host, rfwd->connect_port);
   
Line 666 
Line 663 
                 memset(rfwd, 0, sizeof(*rfwd));                  memset(rfwd, 0, sizeof(*rfwd));
         }          }
  fail:   fail:
         error("%s: %s", __func__, failmsg);          error_f("%s", failmsg);
         reply_error(out, MUX_S_FAILURE, fctx->rid, failmsg);          reply_error(out, MUX_S_FAILURE, fctx->rid, failmsg);
         free(failmsg);          free(failmsg);
  out:   out:
         if ((r = sshbuf_put_stringb(c->output, out)) != 0)          if ((r = sshbuf_put_stringb(c->output, out)) != 0)
                 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));                  fatal_fr(r, "enqueue");
         sshbuf_free(out);          sshbuf_free(out);
         if (c->mux_pause <= 0)          if (c->mux_pause <= 0)
                 fatal("%s: mux_pause %d", __func__, c->mux_pause);                  fatal_f("mux_pause %d", c->mux_pause);
         c->mux_pause = 0; /* start processing messages again */          c->mux_pause = 0; /* start processing messages again */
 }  }
   
Line 699 
Line 696 
             (r = sshbuf_get_u32(m, &cport)) != 0 ||              (r = sshbuf_get_u32(m, &cport)) != 0 ||
             (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||              (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
             (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {              (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
                 error("%s: malformed message", __func__);                  error_f("malformed message");
                 ret = -1;                  ret = -1;
                 goto out;                  goto out;
         }          }
Line 724 
Line 721 
         else          else
                 fwd.connect_host = connect_addr;                  fwd.connect_host = connect_addr;
   
         debug2("%s: channel %d: request %s", __func__, c->self,          debug2_f("channel %d: request %s", c->self,
             (fwd_desc = format_forward(ftype, &fwd)));              (fwd_desc = format_forward(ftype, &fwd)));
   
         if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&          if (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&
             ftype != MUX_FWD_DYNAMIC) {              ftype != MUX_FWD_DYNAMIC) {
                 logit("%s: invalid forwarding type %u", __func__, ftype);                  logit_f("invalid forwarding type %u", ftype);
  invalid:   invalid:
                 free(listen_addr);                  free(listen_addr);
                 free(connect_addr);                  free(connect_addr);
Line 738 
Line 735 
                 return 0;                  return 0;
         }          }
         if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {          if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
                 logit("%s: streamlocal and dynamic forwards "                  logit_f("streamlocal and dynamic forwards "
                     "are mutually exclusive", __func__);                      "are mutually exclusive");
                 goto invalid;                  goto invalid;
         }          }
         if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {          if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
                 logit("%s: invalid listen port %u", __func__,                  logit_f("invalid listen port %u", fwd.listen_port);
                     fwd.listen_port);  
                 goto invalid;                  goto invalid;
         }          }
         if ((fwd.connect_port != PORT_STREAMLOCAL &&          if ((fwd.connect_port != PORT_STREAMLOCAL &&
             fwd.connect_port >= 65536) ||              fwd.connect_port >= 65536) ||
             (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&              (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&
             fwd.connect_port == 0)) {              fwd.connect_port == 0)) {
                 logit("%s: invalid connect port %u", __func__,                  logit_f("invalid connect port %u",
                     fwd.connect_port);                      fwd.connect_port);
                 goto invalid;                  goto invalid;
         }          }
         if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&          if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
             fwd.connect_path == NULL) {              fwd.connect_path == NULL) {
                 logit("%s: missing connect host", __func__);                  logit_f("missing connect host");
                 goto invalid;                  goto invalid;
         }          }
   
Line 769 
Line 765 
                         if (compare_forward(&fwd,                          if (compare_forward(&fwd,
                             options.local_forwards + i)) {                              options.local_forwards + i)) {
  exists:   exists:
                                 debug2("%s: found existing forwarding",                                  debug2_f("found existing forwarding");
                                     __func__);  
                                 reply_ok(reply, rid);                                  reply_ok(reply, rid);
                                 goto out;                                  goto out;
                         }                          }
Line 782 
Line 777 
                                 continue;                                  continue;
                         if (fwd.listen_port != 0)                          if (fwd.listen_port != 0)
                                 goto exists;                                  goto exists;
                         debug2("%s: found allocated port", __func__);                          debug2_f("found allocated port");
                         if ((r = sshbuf_put_u32(reply,                          if ((r = sshbuf_put_u32(reply,
                             MUX_S_REMOTE_PORT)) != 0 ||                              MUX_S_REMOTE_PORT)) != 0 ||
                             (r = sshbuf_put_u32(reply, rid)) != 0 ||                              (r = sshbuf_put_u32(reply, rid)) != 0 ||
                             (r = sshbuf_put_u32(reply,                              (r = sshbuf_put_u32(reply,
                             options.remote_forwards[i].allocated_port)) != 0)                              options.remote_forwards[i].allocated_port)) != 0)
                                 fatal("%s: reply: %s", __func__, ssh_err(r));                                  fatal_fr(r, "reply FWD_REMOTE");
                         goto out;                          goto out;
                 }                  }
                 break;                  break;
Line 797 
Line 792 
         if (options.control_master == SSHCTL_MASTER_ASK ||          if (options.control_master == SSHCTL_MASTER_ASK ||
             options.control_master == SSHCTL_MASTER_AUTO_ASK) {              options.control_master == SSHCTL_MASTER_AUTO_ASK) {
                 if (!ask_permission("Open %s on %s?", fwd_desc, host)) {                  if (!ask_permission("Open %s on %s?", fwd_desc, host)) {
                         debug2("%s: forwarding refused by user", __func__);                          debug2_f("forwarding refused by user");
                         reply_error(reply, MUX_S_PERMISSION_DENIED, rid,                          reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
                             "Permission denied");                              "Permission denied");
                         goto out;                          goto out;
Line 808 
Line 803 
                 if (!channel_setup_local_fwd_listener(ssh, &fwd,                  if (!channel_setup_local_fwd_listener(ssh, &fwd,
                     &options.fwd_opts)) {                      &options.fwd_opts)) {
  fail:   fail:
                         logit("%s: requested %s failed", __func__, fwd_desc);                          logit_f("requested %s failed", fwd_desc);
                         reply_error(reply, MUX_S_FAILURE, rid,                          reply_error(reply, MUX_S_FAILURE, rid,
                             "Port forwarding failed");                              "Port forwarding failed");
                         goto out;                          goto out;
Line 866 
Line 861 
             (r = sshbuf_get_u32(m, &cport)) != 0 ||              (r = sshbuf_get_u32(m, &cport)) != 0 ||
             (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||              (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
             (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {              (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
                 error("%s: malformed message", __func__);                  error_f("malformed message");
                 ret = -1;                  ret = -1;
                 goto out;                  goto out;
         }          }
Line 892 
Line 887 
         else          else
                 fwd.connect_host = connect_addr;                  fwd.connect_host = connect_addr;
   
         debug2("%s: channel %d: request cancel %s", __func__, c->self,          debug2_f("channel %d: request cancel %s", c->self,
             (fwd_desc = format_forward(ftype, &fwd)));              (fwd_desc = format_forward(ftype, &fwd)));
   
         /* make sure this has been requested */          /* make sure this has been requested */
Line 971 
Line 966 
             (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||              (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||
             (r = sshbuf_get_u32(m, &cport)) != 0) {              (r = sshbuf_get_u32(m, &cport)) != 0) {
                 free(chost);                  free(chost);
                 error("%s: malformed message", __func__);                  error_f("malformed message");
                 return -1;                  return -1;
         }          }
   
         debug2("%s: channel %d: request stdio fwd to %s:%u",          debug2_f("channel %d: stdio fwd to %s:%u", c->self, chost, cport);
             __func__, c->self, chost, cport);  
   
         /* Gather fds from client */          /* Gather fds from client */
         for(i = 0; i < 2; i++) {          for(i = 0; i < 2; i++) {
                 if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {                  if ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {
                         error("%s: failed to receive fd %d from client",                          error_f("failed to receive fd %d from client", i);
                             __func__, i);  
                         for (j = 0; j < i; j++)                          for (j = 0; j < i; j++)
                                 close(new_fd[j]);                                  close(new_fd[j]);
                         free(chost);                          free(chost);
Line 994 
Line 987 
                 }                  }
         }          }
   
         debug3("%s: got fds stdin %d, stdout %d", __func__,          debug3_f("got fds stdin %d, stdout %d", new_fd[0], new_fd[1]);
             new_fd[0], new_fd[1]);  
   
         /* XXX support multiple child sessions in future */          /* XXX support multiple child sessions in future */
         if (c->have_remote_id) {          if (c->have_remote_id) {
                 debug2("%s: session already open", __func__);                  debug2_f("session already open");
                 reply_error(reply, MUX_S_FAILURE, rid,                  reply_error(reply, MUX_S_FAILURE, rid,
                     "Multiple sessions not supported");                      "Multiple sessions not supported");
  cleanup:   cleanup:
Line 1013 
Line 1005 
             options.control_master == SSHCTL_MASTER_AUTO_ASK) {              options.control_master == SSHCTL_MASTER_AUTO_ASK) {
                 if (!ask_permission("Allow forward to %s:%u? ",                  if (!ask_permission("Allow forward to %s:%u? ",
                     chost, cport)) {                      chost, cport)) {
                         debug2("%s: stdio fwd refused by user", __func__);                          debug2_f("stdio fwd refused by user");
                         reply_error(reply, MUX_S_PERMISSION_DENIED, rid,                          reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
                             "Permission denied");                              "Permission denied");
                         goto cleanup;                          goto cleanup;
Line 1033 
Line 1025 
         c->remote_id = nc->self;        /* link control -> session channel */          c->remote_id = nc->self;        /* link control -> session channel */
         c->have_remote_id = 1;          c->have_remote_id = 1;
   
         debug2("%s: channel_new: %d linked to control channel %d",          debug2_f("channel_new: %d control %d", nc->self, nc->ctl_chan);
             __func__, nc->self, nc->ctl_chan);  
   
         channel_register_cleanup(ssh, nc->self,          channel_register_cleanup(ssh, nc->self,
             mux_master_session_cleanup_cb, 1);              mux_master_session_cleanup_cb, 1);
Line 1058 
Line 1049 
         int r;          int r;
   
         if (cctx == NULL)          if (cctx == NULL)
                 fatal("%s: cctx == NULL", __func__);                  fatal_f("cctx == NULL");
         if ((c = channel_by_id(ssh, id)) == NULL)          if ((c = channel_by_id(ssh, id)) == NULL)
                 fatal("%s: no channel for id %d", __func__, id);                  fatal_f("no channel for id %d", id);
         if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)          if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
                 fatal("%s: channel %d lacks control channel %d", __func__,                  fatal_f("channel %d lacks control channel %d",
                     id, c->ctl_chan);                      id, c->ctl_chan);
         if ((reply = sshbuf_new()) == NULL)          if ((reply = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
   
         if (!success) {          if (!success) {
                 debug3("%s: sending failure reply", __func__);                  debug3_f("sending failure reply");
                 reply_error(reply, MUX_S_FAILURE, cctx->rid,                  reply_error(reply, MUX_S_FAILURE, cctx->rid,
                     "Session open refused by peer");                      "Session open refused by peer");
                 /* prepare reply */                  /* prepare reply */
                 goto done;                  goto done;
         }          }
   
         debug3("%s: sending success reply", __func__);          debug3_f("sending success reply");
         /* prepare reply */          /* prepare reply */
         if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||          if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
             (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||              (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
             (r = sshbuf_put_u32(reply, c->self)) != 0)              (r = sshbuf_put_u32(reply, c->self)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
   
  done:   done:
         /* Send reply */          /* Send reply */
         if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)          if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
                 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));                  fatal_fr(r, "enqueue");
         sshbuf_free(reply);          sshbuf_free(reply);
   
         if (cc->mux_pause <= 0)          if (cc->mux_pause <= 0)
                 fatal("%s: mux_pause %d", __func__, cc->mux_pause);                  fatal_f("mux_pause %d", cc->mux_pause);
         cc->mux_pause = 0; /* start processing messages again */          cc->mux_pause = 0; /* start processing messages again */
         c->open_confirm_ctx = NULL;          c->open_confirm_ctx = NULL;
         free(cctx);          free(cctx);
Line 1099 
Line 1090 
 mux_master_process_stop_listening(struct ssh *ssh, u_int rid,  mux_master_process_stop_listening(struct ssh *ssh, u_int rid,
     Channel *c, struct sshbuf *m, struct sshbuf *reply)      Channel *c, struct sshbuf *m, struct sshbuf *reply)
 {  {
         debug("%s: channel %d: stop listening", __func__, c->self);          debug_f("channel %d: stop listening", c->self);
   
         if (options.control_master == SSHCTL_MASTER_ASK ||          if (options.control_master == SSHCTL_MASTER_ASK ||
             options.control_master == SSHCTL_MASTER_AUTO_ASK) {              options.control_master == SSHCTL_MASTER_AUTO_ASK) {
                 if (!ask_permission("Disable further multiplexing on shared "                  if (!ask_permission("Disable further multiplexing on shared "
                     "connection to %s? ", host)) {                      "connection to %s? ", host)) {
                         debug2("%s: stop listen refused by user", __func__);                          debug2_f("stop listen refused by user");
                         reply_error(reply, MUX_S_PERMISSION_DENIED, rid,                          reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
                             "Permission denied");                              "Permission denied");
                         return 0;                          return 0;
Line 1131 
Line 1122 
 {  {
         int r;          int r;
   
         debug("%s: channel %d: proxy request", __func__, c->self);          debug_f("channel %d: proxy request", c->self);
   
         c->mux_rcb = channel_proxy_downstream;          c->mux_rcb = channel_proxy_downstream;
         if ((r = sshbuf_put_u32(reply, MUX_S_PROXY)) != 0 ||          if ((r = sshbuf_put_u32(reply, MUX_S_PROXY)) != 0 ||
             (r = sshbuf_put_u32(reply, rid)) != 0)              (r = sshbuf_put_u32(reply, rid)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
   
         return 0;          return 0;
 }  }
Line 1151 
Line 1142 
         int r, ret = -1;          int r, ret = -1;
   
         if ((out = sshbuf_new()) == NULL)          if ((out = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
   
         /* Setup ctx and  */          /* Setup ctx and  */
         if (c->mux_ctx == NULL) {          if (c->mux_ctx == NULL) {
Line 1163 
Line 1154 
                 /* Send hello */                  /* Send hello */
                 if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 ||                  if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 ||
                     (r = sshbuf_put_u32(out, SSHMUX_VER)) != 0)                      (r = sshbuf_put_u32(out, SSHMUX_VER)) != 0)
                         fatal("%s: reply: %s", __func__, ssh_err(r));                          fatal_fr(r, "reply");
                 /* no extensions */                  /* no extensions */
                 if ((r = sshbuf_put_stringb(c->output, out)) != 0)                  if ((r = sshbuf_put_stringb(c->output, out)) != 0)
                         fatal("%s: sshbuf_put_stringb: %s",                          fatal_fr(r, "enqueue");
                             __func__, ssh_err(r));                  debug3_f("channel %d: hello sent", c->self);
                 debug3("%s: channel %d: hello sent", __func__, c->self);  
                 ret = 0;                  ret = 0;
                 goto out;                  goto out;
         }          }
Line 1176 
Line 1166 
         /* Channel code ensures that we receive whole packets */          /* Channel code ensures that we receive whole packets */
         if ((r = sshbuf_froms(c->input, &in)) != 0) {          if ((r = sshbuf_froms(c->input, &in)) != 0) {
  malf:   malf:
                 error("%s: malformed message", __func__);                  error_f("malformed message");
                 goto out;                  goto out;
         }          }
   
         if ((r = sshbuf_get_u32(in, &type)) != 0)          if ((r = sshbuf_get_u32(in, &type)) != 0)
                 goto malf;                  goto malf;
         debug3("%s: channel %d packet type 0x%08x len %zu",          debug3_f("channel %d packet type 0x%08x len %zu", c->self,
             __func__, c->self, type, sshbuf_len(in));              type, sshbuf_len(in));
   
         if (type == MUX_MSG_HELLO)          if (type == MUX_MSG_HELLO)
                 rid = 0;                  rid = 0;
         else {          else {
                 if (!state->hello_rcvd) {                  if (!state->hello_rcvd) {
                         error("%s: expected MUX_MSG_HELLO(0x%08x), "                          error_f("expected MUX_MSG_HELLO(0x%08x), "
                             "received 0x%08x", __func__, MUX_MSG_HELLO, type);                              "received 0x%08x", MUX_MSG_HELLO, type);
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_u32(in, &rid)) != 0)                  if ((r = sshbuf_get_u32(in, &rid)) != 0)
Line 1205 
Line 1195 
                 }                  }
         }          }
         if (mux_master_handlers[i].handler == NULL) {          if (mux_master_handlers[i].handler == NULL) {
                 error("%s: unsupported mux message 0x%08x", __func__, type);                  error_f("unsupported mux message 0x%08x", type);
                 reply_error(out, MUX_S_FAILURE, rid, "unsupported request");                  reply_error(out, MUX_S_FAILURE, rid, "unsupported request");
                 ret = 0;                  ret = 0;
         }          }
         /* Enqueue reply packet */          /* Enqueue reply packet */
         if (sshbuf_len(out) != 0) {          if (sshbuf_len(out) != 0 &&
                 if ((r = sshbuf_put_stringb(c->output, out)) != 0)              (r = sshbuf_put_stringb(c->output, out)) != 0)
                         fatal("%s: sshbuf_put_stringb: %s",                  fatal_fr(r, "enqueue");
                             __func__, ssh_err(r));  
         }  
  out:   out:
         sshbuf_free(in);          sshbuf_free(in);
         sshbuf_free(out);          sshbuf_free(out);
Line 1228 
Line 1216 
         Channel *mux_chan;          Channel *mux_chan;
         int r;          int r;
   
         debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,          debug3_f("channel %d: exit message, exitval %d", c->self, exitval);
             exitval);  
   
         if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)          if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
                 fatal("%s: channel %d missing mux channel %d",                  fatal_f("channel %d missing mux %d", c->self, c->ctl_chan);
                     __func__, c->self, c->ctl_chan);  
   
         /* Append exit message packet to control socket output queue */          /* Append exit message packet to control socket output queue */
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_S_EXIT_MESSAGE)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_S_EXIT_MESSAGE)) != 0 ||
             (r = sshbuf_put_u32(m, c->self)) != 0 ||              (r = sshbuf_put_u32(m, c->self)) != 0 ||
             (r = sshbuf_put_u32(m, exitval)) != 0 ||              (r = sshbuf_put_u32(m, exitval)) != 0 ||
             (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)              (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
         sshbuf_free(m);          sshbuf_free(m);
 }  }
   
Line 1253 
Line 1239 
         Channel *mux_chan;          Channel *mux_chan;
         int r;          int r;
   
         debug3("%s: channel %d: TTY alloc failed", __func__, c->self);          debug3_f("channel %d: TTY alloc failed", c->self);
   
         if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)          if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
                 fatal("%s: channel %d missing mux channel %d",                  fatal_f("channel %d missing mux %d", c->self, c->ctl_chan);
                     __func__, c->self, c->ctl_chan);  
   
         /* Append exit message packet to control socket output queue */          /* Append exit message packet to control socket output queue */
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_S_TTY_ALLOC_FAIL)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_S_TTY_ALLOC_FAIL)) != 0 ||
             (r = sshbuf_put_u32(m, c->self)) != 0 ||              (r = sshbuf_put_u32(m, c->self)) != 0 ||
             (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)              (r = sshbuf_put_stringb(mux_chan->output, m)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
         sshbuf_free(m);          sshbuf_free(m);
 }  }
   
Line 1300 
Line 1285 
         rbuf[sizeof(rbuf) - 1] = '\0';          rbuf[sizeof(rbuf) - 1] = '\0';
         options.control_path = NULL;          options.control_path = NULL;
         xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);          xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
         debug3("%s: temporary control path %s", __func__, options.control_path);          debug3_f("temporary control path %s", options.control_path);
   
         old_umask = umask(0177);          old_umask = umask(0177);
         muxserver_sock = unix_listener(options.control_path, 64, 0);          muxserver_sock = unix_listener(options.control_path, 64, 0);
Line 1329 
Line 1314 
         /* Now atomically "move" the mux socket into position */          /* Now atomically "move" the mux socket into position */
         if (link(options.control_path, orig_control_path) != 0) {          if (link(options.control_path, orig_control_path) != 0) {
                 if (errno != EEXIST) {                  if (errno != EEXIST) {
                         fatal("%s: link mux listener %s => %s: %s", __func__,                          fatal_f("link mux listener %s => %s: %s",
                             options.control_path, orig_control_path,                              options.control_path, orig_control_path,
                             strerror(errno));                              strerror(errno));
                 }                  }
Line 1349 
Line 1334 
             CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,              CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
             0, options.control_path, 1);              0, options.control_path, 1);
         mux_listener_channel->mux_rcb = mux_master_read_cb;          mux_listener_channel->mux_rcb = mux_master_read_cb;
         debug3("%s: mux listener channel %d fd %d", __func__,          debug3_f("mux listener channel %d fd %d",
             mux_listener_channel->self, mux_listener_channel->sock);              mux_listener_channel->self, mux_listener_channel->sock);
 }  }
   
Line 1364 
Line 1349 
         struct sshbuf *reply;          struct sshbuf *reply;
   
         if (cctx == NULL)          if (cctx == NULL)
                 fatal("%s: cctx == NULL", __func__);                  fatal_f("cctx == NULL");
         if ((c = channel_by_id(ssh, id)) == NULL)          if ((c = channel_by_id(ssh, id)) == NULL)
                 fatal("%s: no channel for id %d", __func__, id);                  fatal_f("no channel for id %d", id);
         if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)          if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
                 fatal("%s: channel %d lacks control channel %d", __func__,                  fatal_f("channel %d lacks control channel %d",
                     id, c->ctl_chan);                      id, c->ctl_chan);
         if ((reply = sshbuf_new()) == NULL)          if ((reply = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
   
         if (!success) {          if (!success) {
                 debug3("%s: sending failure reply", __func__);                  debug3_f("sending failure reply");
                 reply_error(reply, MUX_S_FAILURE, cctx->rid,                  reply_error(reply, MUX_S_FAILURE, cctx->rid,
                     "Session open refused by peer");                      "Session open refused by peer");
                 goto done;                  goto done;
Line 1403 
Line 1388 
                 debug("Requesting authentication agent forwarding.");                  debug("Requesting authentication agent forwarding.");
                 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);                  channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
                 if ((r = sshpkt_send(ssh)) != 0)                  if ((r = sshpkt_send(ssh)) != 0)
                         fatal("%s: packet error: %s", __func__, ssh_err(r));                          fatal_fr(r, "send");
         }          }
   
         client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,          client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
             cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env);              cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env);
   
         debug3("%s: sending success reply", __func__);          debug3_f("sending success reply");
         /* prepare reply */          /* prepare reply */
         if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||          if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 ||
             (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||              (r = sshbuf_put_u32(reply, cctx->rid)) != 0 ||
             (r = sshbuf_put_u32(reply, c->self)) != 0)              (r = sshbuf_put_u32(reply, c->self)) != 0)
                 fatal("%s: reply: %s", __func__, ssh_err(r));                  fatal_fr(r, "reply");
   
  done:   done:
         /* Send reply */          /* Send reply */
         if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)          if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
                 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));                  fatal_fr(r, "enqueue");
         sshbuf_free(reply);          sshbuf_free(reply);
   
         if (cc->mux_pause <= 0)          if (cc->mux_pause <= 0)
                 fatal("%s: mux_pause %d", __func__, cc->mux_pause);                  fatal_f("mux_pause %d", cc->mux_pause);
         cc->mux_pause = 0; /* start processing messages again */          cc->mux_pause = 0; /* start processing messages again */
         c->open_confirm_ctx = NULL;          c->open_confirm_ctx = NULL;
         sshbuf_free(cctx->cmd);          sshbuf_free(cctx->cmd);
Line 1472 
Line 1457 
         pfd.fd = fd;          pfd.fd = fd;
         pfd.events = POLLIN;          pfd.events = POLLIN;
         if ((r = sshbuf_reserve(b, need, &p)) != 0)          if ((r = sshbuf_reserve(b, need, &p)) != 0)
                 fatal("%s: reserve: %s", __func__, ssh_err(r));                  fatal_fr(r, "reserve");
         for (have = 0; have < need; ) {          for (have = 0; have < need; ) {
                 if (muxclient_terminate) {                  if (muxclient_terminate) {
                         errno = EINTR;                          errno = EINTR;
Line 1511 
Line 1496 
         pfd.fd = fd;          pfd.fd = fd;
         pfd.events = POLLOUT;          pfd.events = POLLOUT;
         if ((queue = sshbuf_new()) == NULL)          if ((queue = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_stringb(queue, m)) != 0)          if ((r = sshbuf_put_stringb(queue, m)) != 0)
                 fatal("%s: sshbuf_put_stringb: %s", __func__, ssh_err(r));                  fatal_fr(r, "enqueue");
   
         need = sshbuf_len(queue);          need = sshbuf_len(queue);
         ptr = sshbuf_ptr(queue);          ptr = sshbuf_ptr(queue);
Line 1559 
Line 1544 
         int r, oerrno;          int r, oerrno;
   
         if ((queue = sshbuf_new()) == NULL)          if ((queue = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if (mux_client_read(fd, queue, 4) != 0) {          if (mux_client_read(fd, queue, 4) != 0) {
                 if ((oerrno = errno) == EPIPE)                  if ((oerrno = errno) == EPIPE)
                         debug3("%s: read header failed: %s", __func__,                          debug3_f("read header failed: %s",
                             strerror(errno));                              strerror(errno));
                 sshbuf_free(queue);                  sshbuf_free(queue);
                 errno = oerrno;                  errno = oerrno;
Line 1571 
Line 1556 
         need = PEEK_U32(sshbuf_ptr(queue));          need = PEEK_U32(sshbuf_ptr(queue));
         if (mux_client_read(fd, queue, need) != 0) {          if (mux_client_read(fd, queue, need) != 0) {
                 oerrno = errno;                  oerrno = errno;
                 debug3("%s: read body failed: %s", __func__, strerror(errno));                  debug3_f("read body failed: %s", strerror(errno));
                 sshbuf_free(queue);                  sshbuf_free(queue);
                 errno = oerrno;                  errno = oerrno;
                 return -1;                  return -1;
         }          }
         if ((r = sshbuf_get_string_direct(queue, &ptr, &have)) != 0 ||          if ((r = sshbuf_get_string_direct(queue, &ptr, &have)) != 0 ||
             (r = sshbuf_put(m, ptr, have)) != 0)              (r = sshbuf_put(m, ptr, have)) != 0)
                 fatal("%s: buffer error: %s", __func__, ssh_err(r));                  fatal_fr(r, "dequeue");
         sshbuf_free(queue);          sshbuf_free(queue);
         return 0;          return 0;
 }  }
Line 1591 
Line 1576 
         int r, ret = -1;          int r, ret = -1;
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_MSG_HELLO)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_MSG_HELLO)) != 0 ||
             (r = sshbuf_put_u32(m, SSHMUX_VER)) != 0)              (r = sshbuf_put_u32(m, SSHMUX_VER)) != 0)
                 fatal("%s: hello: %s", __func__, ssh_err(r));                  fatal_fr(r, "assemble hello");
         /* no extensions */          /* no extensions */
   
         if (mux_client_write_packet(fd, m) != 0) {          if (mux_client_write_packet(fd, m) != 0) {
                 debug("%s: write packet: %s", __func__, strerror(errno));                  debug_f("write packet: %s", strerror(errno));
                 goto out;                  goto out;
         }          }
   
Line 1606 
Line 1591 
   
         /* Read their HELLO */          /* Read their HELLO */
         if (mux_client_read_packet(fd, m) != 0) {          if (mux_client_read_packet(fd, m) != 0) {
                 debug("%s: read packet failed", __func__);                  debug_f("read packet failed");
                 goto out;                  goto out;
         }          }
   
         if ((r = sshbuf_get_u32(m, &type)) != 0)          if ((r = sshbuf_get_u32(m, &type)) != 0)
                 fatal("%s: decode type: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse type");
         if (type != MUX_MSG_HELLO) {          if (type != MUX_MSG_HELLO) {
                 error("%s: expected HELLO (%u) received %u",                  error_f("expected HELLO (%u) got %u", MUX_MSG_HELLO, type);
                     __func__, MUX_MSG_HELLO, type);  
                 goto out;                  goto out;
         }          }
         if ((r = sshbuf_get_u32(m, &ver)) != 0)          if ((r = sshbuf_get_u32(m, &ver)) != 0)
                 fatal("%s: decode version: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse version");
         if (ver != SSHMUX_VER) {          if (ver != SSHMUX_VER) {
                 error("Unsupported multiplexing protocol version %d "                  error("Unsupported multiplexing protocol version %d "
                     "(expected %d)", ver, SSHMUX_VER);                      "(expected %d)", ver, SSHMUX_VER);
                 goto out;                  goto out;
         }          }
         debug2("%s: master version %u", __func__, ver);          debug2_f("master version %u", ver);
         /* No extensions are presently defined */          /* No extensions are presently defined */
         while (sshbuf_len(m) > 0) {          while (sshbuf_len(m) > 0) {
                 char *name = NULL;                  char *name = NULL;
   
                 if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||                  if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
                     (r = sshbuf_skip_string(m)) != 0) { /* value */                      (r = sshbuf_skip_string(m)) != 0) { /* value */
                         error("%s: malformed extension: %s",                          error_fr(r, "parse extension");
                             __func__, ssh_err(r));  
                         goto out;                          goto out;
                 }                  }
                 debug2("Unrecognised master extension \"%s\"", name);                  debug2("Unrecognised master extension \"%s\"", name);
Line 1653 
Line 1636 
         u_int pid, type, rid;          u_int pid, type, rid;
         int r;          int r;
   
         debug3("%s: entering", __func__);          debug3_f("entering");
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_ALIVE_CHECK)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_ALIVE_CHECK)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "assemble");
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         sshbuf_reset(m);          sshbuf_reset(m);
   
Line 1673 
Line 1656 
         }          }
   
         if ((r = sshbuf_get_u32(m, &type)) != 0)          if ((r = sshbuf_get_u32(m, &type)) != 0)
                 fatal("%s: decode type: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse type");
         if (type != MUX_S_ALIVE) {          if (type != MUX_S_ALIVE) {
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("%s: master returned error: %s", __func__, e);                  fatal_f("master returned error: %s", e);
         }          }
   
         if ((r = sshbuf_get_u32(m, &rid)) != 0)          if ((r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode remote ID: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse remote ID");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
         if ((r = sshbuf_get_u32(m, &pid)) != 0)          if ((r = sshbuf_get_u32(m, &pid)) != 0)
                 fatal("%s: decode PID: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse PID");
         sshbuf_free(m);          sshbuf_free(m);
   
         debug3("%s: done pid = %u", __func__, pid);          debug3_f("done pid = %u", pid);
   
         muxclient_request_id++;          muxclient_request_id++;
   
Line 1704 
Line 1687 
         u_int type, rid;          u_int type, rid;
         int r;          int r;
   
         debug3("%s: entering", __func__);          debug3_f("entering");
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_TERMINATE)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_TERMINATE)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         sshbuf_reset(m);          sshbuf_reset(m);
   
Line 1724 
Line 1707 
                         sshbuf_free(m);                          sshbuf_free(m);
                         return;                          return;
                 }                  }
                 fatal("%s: read from master failed: %s",                  fatal_f("read from master failed: %s", strerror(errno));
                     __func__, strerror(errno));  
         }          }
   
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
         switch (type) {          switch (type) {
         case MUX_S_OK:          case MUX_S_OK:
                 break;                  break;
         case MUX_S_PERMISSION_DENIED:          case MUX_S_PERMISSION_DENIED:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("Master refused termination request: %s", e);                  fatal("Master refused termination request: %s", e);
         case MUX_S_FAILURE:          case MUX_S_FAILURE:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("%s: termination request failed: %s", __func__, e);                  fatal_f("termination request failed: %s", e);
         default:          default:
                 fatal("%s: unexpected response from master 0x%08x",                  fatal_f("unexpected response from master 0x%08x", type);
                     __func__, type);  
         }          }
         sshbuf_free(m);          sshbuf_free(m);
         muxclient_request_id++;          muxclient_request_id++;
Line 1785 
Line 1766 
                 chost = fwd->connect_host;                  chost = fwd->connect_host;
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, type)) != 0 ||          if ((r = sshbuf_put_u32(m, type)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
             (r = sshbuf_put_u32(m, ftype)) != 0 ||              (r = sshbuf_put_u32(m, ftype)) != 0 ||
Line 1793 
Line 1774 
             (r = sshbuf_put_u32(m, fwd->listen_port)) != 0 ||              (r = sshbuf_put_u32(m, fwd->listen_port)) != 0 ||
             (r = sshbuf_put_cstring(m, chost)) != 0 ||              (r = sshbuf_put_cstring(m, chost)) != 0 ||
             (r = sshbuf_put_u32(m, fwd->connect_port)) != 0)              (r = sshbuf_put_u32(m, fwd->connect_port)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         sshbuf_reset(m);          sshbuf_reset(m);
   
Line 1808 
Line 1789 
   
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
   
         switch (type) {          switch (type) {
         case MUX_S_OK:          case MUX_S_OK:
                 break;                  break;
         case MUX_S_REMOTE_PORT:          case MUX_S_REMOTE_PORT:
                 if (cancel_flag)                  if (cancel_flag)
                         fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);                          fatal_f("got MUX_S_REMOTE_PORT for cancel");
                 if ((r = sshbuf_get_u32(m, &fwd->allocated_port)) != 0)                  if ((r = sshbuf_get_u32(m, &fwd->allocated_port)) != 0)
                         fatal("%s: decode port: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse port");
                 verbose("Allocated port %u for remote forward to %s:%d",                  verbose("Allocated port %u for remote forward to %s:%d",
                     fwd->allocated_port,                      fwd->allocated_port,
                     fwd->connect_host ? fwd->connect_host : "",                      fwd->connect_host ? fwd->connect_host : "",
Line 1830 
Line 1811 
                 break;                  break;
         case MUX_S_PERMISSION_DENIED:          case MUX_S_PERMISSION_DENIED:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 sshbuf_free(m);                  sshbuf_free(m);
                 error("Master refused forwarding request: %s", e);                  error("Master refused forwarding request: %s", e);
                 return -1;                  return -1;
         case MUX_S_FAILURE:          case MUX_S_FAILURE:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 sshbuf_free(m);                  sshbuf_free(m);
                 error("%s: forwarding request failed: %s", __func__, e);                  error_f("forwarding request failed: %s", e);
                 return -1;                  return -1;
         default:          default:
                 fatal("%s: unexpected response from master 0x%08x",                  fatal_f("unexpected response from master 0x%08x", type);
                     __func__, type);  
         }          }
         sshbuf_free(m);          sshbuf_free(m);
   
Line 1855 
Line 1835 
 {  {
         int i, ret = 0;          int i, ret = 0;
   
         debug3("%s: %s forwardings: %d local, %d remote", __func__,          debug3_f("%s forwardings: %d local, %d remote",
             cancel_flag ? "cancel" : "request",              cancel_flag ? "cancel" : "request",
             options.num_local_forwards, options.num_remote_forwards);              options.num_local_forwards, options.num_remote_forwards);
   
Line 1885 
Line 1865 
         extern char **environ;          extern char **environ;
         int r, i, rawmode;          int r, i, rawmode;
   
         debug3("%s: entering", __func__);          debug3_f("entering");
   
         if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {          if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
                 error("%s: master alive request failed", __func__);                  error_f("master alive request failed");
                 return -1;                  return -1;
         }          }
   
         ssh_signal(SIGPIPE, SIG_IGN);          ssh_signal(SIGPIPE, SIG_IGN);
   
         if (stdin_null_flag && stdfd_devnull(1, 0, 0) == -1)          if (stdin_null_flag && stdfd_devnull(1, 0, 0) == -1)
                 fatal("%s: stdfd_devnull failed", __func__);                  fatal_f("stdfd_devnull failed");
   
         if ((term = getenv("TERM")) == NULL)          if ((term = getenv("TERM")) == NULL)
                 term = "";                  term = "";
Line 1904 
Line 1884 
             echar = (u_int)options.escape_char;              echar = (u_int)options.escape_char;
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_NEW_SESSION)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_NEW_SESSION)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
             (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */              (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
Line 1915 
Line 1895 
             (r = sshbuf_put_u32(m, echar)) != 0 ||              (r = sshbuf_put_u32(m, echar)) != 0 ||
             (r = sshbuf_put_cstring(m, term)) != 0 ||              (r = sshbuf_put_cstring(m, term)) != 0 ||
             (r = sshbuf_put_stringb(m, command)) != 0)              (r = sshbuf_put_stringb(m, command)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
   
         /* Pass environment */          /* Pass environment */
         if (options.num_send_env > 0 && environ != NULL) {          if (options.num_send_env > 0 && environ != NULL) {
Line 1923 
Line 1903 
                         if (!env_permitted(environ[i]))                          if (!env_permitted(environ[i]))
                                 continue;                                  continue;
                         if ((r = sshbuf_put_cstring(m, environ[i])) != 0)                          if ((r = sshbuf_put_cstring(m, environ[i])) != 0)
                                 fatal("%s: request: %s", __func__, ssh_err(r));                                  fatal_fr(r, "request sendenv");
                 }                  }
         }          }
         for (i = 0; i < options.num_setenv; i++) {          for (i = 0; i < options.num_setenv; i++) {
                 if ((r = sshbuf_put_cstring(m, options.setenv[i])) != 0)                  if ((r = sshbuf_put_cstring(m, options.setenv[i])) != 0)
                         fatal("%s: request: %s", __func__, ssh_err(r));                          fatal_fr(r, "request setenv");
         }          }
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         /* Send the stdio file descriptors */          /* Send the stdio file descriptors */
         if (mm_send_fd(fd, STDIN_FILENO) == -1 ||          if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
             mm_send_fd(fd, STDOUT_FILENO) == -1 ||              mm_send_fd(fd, STDOUT_FILENO) == -1 ||
             mm_send_fd(fd, STDERR_FILENO) == -1)              mm_send_fd(fd, STDERR_FILENO) == -1)
                 fatal("%s: send fds failed", __func__);                  fatal_f("send fds failed");
   
         debug3("%s: session request sent", __func__);          debug3_f("session request sent");
   
         /* Read their reply */          /* Read their reply */
         sshbuf_reset(m);          sshbuf_reset(m);
         if (mux_client_read_packet(fd, m) != 0) {          if (mux_client_read_packet(fd, m) != 0) {
                 error("%s: read from master failed: %s",                  error_f("read from master failed: %s", strerror(errno));
                     __func__, strerror(errno));  
                 sshbuf_free(m);                  sshbuf_free(m);
                 return -1;                  return -1;
         }          }
   
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
   
         switch (type) {          switch (type) {
         case MUX_S_SESSION_OPENED:          case MUX_S_SESSION_OPENED:
                 if ((r = sshbuf_get_u32(m, &sid)) != 0)                  if ((r = sshbuf_get_u32(m, &sid)) != 0)
                         fatal("%s: decode ID: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse session ID");
                 debug("%s: master session id: %u", __func__, sid);                  debug_f("master session id: %u", sid);
                 break;                  break;
         case MUX_S_PERMISSION_DENIED:          case MUX_S_PERMISSION_DENIED:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 error("Master refused session request: %s", e);                  error("Master refused session request: %s", e);
                 sshbuf_free(m);                  sshbuf_free(m);
                 return -1;                  return -1;
         case MUX_S_FAILURE:          case MUX_S_FAILURE:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 error("%s: session request failed: %s", __func__, e);                  error_f("session request failed: %s", e);
                 sshbuf_free(m);                  sshbuf_free(m);
                 return -1;                  return -1;
         default:          default:
                 sshbuf_free(m);                  sshbuf_free(m);
                 error("%s: unexpected response from master 0x%08x",                  error_f("unexpected response from master 0x%08x", type);
                     __func__, type);  
                 return -1;                  return -1;
         }          }
         muxclient_request_id++;          muxclient_request_id++;
   
         if (pledge("stdio proc tty", NULL) == -1)          if (pledge("stdio proc tty", NULL) == -1)
                 fatal("%s pledge(): %s", __func__, strerror(errno));                  fatal_f("pledge(): %s", strerror(errno));
   
         ssh_signal(SIGHUP, control_client_sighandler);          ssh_signal(SIGHUP, control_client_sighandler);
         ssh_signal(SIGINT, control_client_sighandler);          ssh_signal(SIGINT, control_client_sighandler);
Line 2008 
Line 1986 
                 if (mux_client_read_packet(fd, m) != 0)                  if (mux_client_read_packet(fd, m) != 0)
                         break;                          break;
                 if ((r = sshbuf_get_u32(m, &type)) != 0)                  if ((r = sshbuf_get_u32(m, &type)) != 0)
                         fatal("%s: decode type: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse type");
                 switch (type) {                  switch (type) {
                 case MUX_S_TTY_ALLOC_FAIL:                  case MUX_S_TTY_ALLOC_FAIL:
                         if ((r = sshbuf_get_u32(m, &esid)) != 0)                          if ((r = sshbuf_get_u32(m, &esid)) != 0)
                                 fatal("%s: decode ID: %s",                                  fatal_fr(r, "parse session ID");
                                     __func__, ssh_err(r));  
                         if (esid != sid)                          if (esid != sid)
                                 fatal("%s: tty alloc fail on unknown session: "                                  fatal_f("tty alloc fail on unknown session: "
                                     "my id %u theirs %u",                                      "my id %u theirs %u", sid, esid);
                                     __func__, sid, esid);  
                         leave_raw_mode(options.request_tty ==                          leave_raw_mode(options.request_tty ==
                             REQUEST_TTY_FORCE);                              REQUEST_TTY_FORCE);
                         rawmode = 0;                          rawmode = 0;
                         continue;                          continue;
                 case MUX_S_EXIT_MESSAGE:                  case MUX_S_EXIT_MESSAGE:
                         if ((r = sshbuf_get_u32(m, &esid)) != 0)                          if ((r = sshbuf_get_u32(m, &esid)) != 0)
                                 fatal("%s: decode ID: %s",                                  fatal_fr(r, "parse session ID");
                                     __func__, ssh_err(r));  
                         if (esid != sid)                          if (esid != sid)
                                 fatal("%s: exit on unknown session: "                                  fatal_f("exit on unknown session: "
                                     "my id %u theirs %u",                                      "my id %u theirs %u", sid, esid);
                                     __func__, sid, esid);  
                         if (exitval_seen)                          if (exitval_seen)
                                 fatal("%s: exitval sent twice", __func__);                                  fatal_f("exitval sent twice");
                         if ((r = sshbuf_get_u32(m, &exitval)) != 0)                          if ((r = sshbuf_get_u32(m, &exitval)) != 0)
                                 fatal("%s: decode exit value: %s",                                  fatal_fr(r, "parse exitval");
                                     __func__, ssh_err(r));  
                         exitval_seen = 1;                          exitval_seen = 1;
                         continue;                          continue;
                 default:                  default:
                         if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                          if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                                 fatal("%s: decode error: %s",                                  fatal_fr(r, "parse error message");
                                     __func__, ssh_err(r));                          fatal_f("master returned error: %s", e);
                         fatal("%s: master returned error: %s", __func__, e);  
                 }                  }
         }          }
   
Line 2073 
Line 2045 
         int r;          int r;
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_PROXY)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_PROXY)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         sshbuf_reset(m);          sshbuf_reset(m);
   
Line 2089 
Line 2061 
         }          }
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
         if (type != MUX_S_PROXY) {          if (type != MUX_S_PROXY) {
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("%s: master returned error: %s", __func__, e);                  fatal_f("master returned error: %s", e);
         }          }
         sshbuf_free(m);          sshbuf_free(m);
   
         debug3("%s: done", __func__);          debug3_f("done");
         muxclient_request_id++;          muxclient_request_id++;
         return 0;          return 0;
 }  }
Line 2113 
Line 2085 
         u_int type, rid, sid;          u_int type, rid, sid;
         int r;          int r;
   
         debug3("%s: entering", __func__);          debug3_f("entering");
   
         if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {          if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
                 error("%s: master alive request failed", __func__);                  error_f("master alive request failed");
                 return -1;                  return -1;
         }          }
   
         ssh_signal(SIGPIPE, SIG_IGN);          ssh_signal(SIGPIPE, SIG_IGN);
   
         if (stdin_null_flag && stdfd_devnull(1, 0, 0) == -1)          if (stdin_null_flag && stdfd_devnull(1, 0, 0) == -1)
                 fatal("%s: stdfd_devnull failed", __func__);                  fatal_f("stdfd_devnull failed");
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_NEW_STDIO_FWD)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_NEW_STDIO_FWD)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 ||
             (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */              (r = sshbuf_put_string(m, NULL, 0)) != 0 || /* reserved */
             (r = sshbuf_put_cstring(m, options.stdio_forward_host)) != 0 ||              (r = sshbuf_put_cstring(m, options.stdio_forward_host)) != 0 ||
             (r = sshbuf_put_u32(m, options.stdio_forward_port)) != 0)              (r = sshbuf_put_u32(m, options.stdio_forward_port)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         /* Send the stdio file descriptors */          /* Send the stdio file descriptors */
         if (mm_send_fd(fd, STDIN_FILENO) == -1 ||          if (mm_send_fd(fd, STDIN_FILENO) == -1 ||
             mm_send_fd(fd, STDOUT_FILENO) == -1)              mm_send_fd(fd, STDOUT_FILENO) == -1)
                 fatal("%s: send fds failed", __func__);                  fatal_f("send fds failed");
   
         if (pledge("stdio proc tty", NULL) == -1)          if (pledge("stdio proc tty", NULL) == -1)
                 fatal("%s pledge(): %s", __func__, strerror(errno));                  fatal_f("pledge(): %s", strerror(errno));
   
         debug3("%s: stdio forward request sent", __func__);          debug3_f("stdio forward request sent");
   
         /* Read their reply */          /* Read their reply */
         sshbuf_reset(m);          sshbuf_reset(m);
   
         if (mux_client_read_packet(fd, m) != 0) {          if (mux_client_read_packet(fd, m) != 0) {
                 error("%s: read from master failed: %s",                  error_f("read from master failed: %s", strerror(errno));
                     __func__, strerror(errno));  
                 sshbuf_free(m);                  sshbuf_free(m);
                 return -1;                  return -1;
         }          }
   
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
         switch (type) {          switch (type) {
         case MUX_S_SESSION_OPENED:          case MUX_S_SESSION_OPENED:
                 if ((r = sshbuf_get_u32(m, &sid)) != 0)                  if ((r = sshbuf_get_u32(m, &sid)) != 0)
                         fatal("%s: decode ID: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse session ID");
                 debug("%s: master session id: %u", __func__, sid);                  debug_f("master session id: %u", sid);
                 break;                  break;
         case MUX_S_PERMISSION_DENIED:          case MUX_S_PERMISSION_DENIED:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 sshbuf_free(m);                  sshbuf_free(m);
                 fatal("Master refused stdio forwarding request: %s", e);                  fatal("Master refused stdio forwarding request: %s", e);
         case MUX_S_FAILURE:          case MUX_S_FAILURE:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 sshbuf_free(m);                  sshbuf_free(m);
                 fatal("Stdio forwarding request failed: %s", e);                  fatal("Stdio forwarding request failed: %s", e);
         default:          default:
                 sshbuf_free(m);                  sshbuf_free(m);
                 error("%s: unexpected response from master 0x%08x",                  error_f("unexpected response from master 0x%08x", type);
                     __func__, type);  
                 return -1;                  return -1;
         }          }
         muxclient_request_id++;          muxclient_request_id++;
Line 2200 
Line 2170 
                 if (errno == EPIPE ||                  if (errno == EPIPE ||
                     (errno == EINTR && muxclient_terminate != 0))                      (errno == EINTR && muxclient_terminate != 0))
                         return 0;                          return 0;
                 fatal("%s: mux_client_read_packet: %s",                  fatal_f("mux_client_read_packet: %s", strerror(errno));
                     __func__, strerror(errno));  
         }          }
         fatal("%s: master returned unexpected message %u", __func__, type);          fatal_f("master returned unexpected message %u", type);
 }  }
   
 static void  static void
Line 2214 
Line 2183 
         u_int type, rid;          u_int type, rid;
         int r;          int r;
   
         debug3("%s: entering", __func__);          debug3_f("entering");
   
         if ((m = sshbuf_new()) == NULL)          if ((m = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new", __func__);                  fatal_f("sshbuf_new");
         if ((r = sshbuf_put_u32(m, MUX_C_STOP_LISTENING)) != 0 ||          if ((r = sshbuf_put_u32(m, MUX_C_STOP_LISTENING)) != 0 ||
             (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)              (r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
                 fatal("%s: request: %s", __func__, ssh_err(r));                  fatal_fr(r, "request");
   
         if (mux_client_write_packet(fd, m) != 0)          if (mux_client_write_packet(fd, m) != 0)
                 fatal("%s: write packet: %s", __func__, strerror(errno));                  fatal_f("write packet: %s", strerror(errno));
   
         sshbuf_reset(m);          sshbuf_reset(m);
   
         /* Read their reply */          /* Read their reply */
         if (mux_client_read_packet(fd, m) != 0)          if (mux_client_read_packet(fd, m) != 0)
                 fatal("%s: read from master failed: %s",                  fatal_f("read from master failed: %s", strerror(errno));
                     __func__, strerror(errno));  
   
         if ((r = sshbuf_get_u32(m, &type)) != 0 ||          if ((r = sshbuf_get_u32(m, &type)) != 0 ||
             (r = sshbuf_get_u32(m, &rid)) != 0)              (r = sshbuf_get_u32(m, &rid)) != 0)
                 fatal("%s: decode: %s", __func__, ssh_err(r));                  fatal_fr(r, "parse");
         if (rid != muxclient_request_id)          if (rid != muxclient_request_id)
                 fatal("%s: out of sequence reply: my id %u theirs %u",                  fatal_f("out of sequence reply: my id %u theirs %u",
                     __func__, muxclient_request_id, rid);                      muxclient_request_id, rid);
   
         switch (type) {          switch (type) {
         case MUX_S_OK:          case MUX_S_OK:
                 break;                  break;
         case MUX_S_PERMISSION_DENIED:          case MUX_S_PERMISSION_DENIED:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("Master refused stop listening request: %s", e);                  fatal("Master refused stop listening request: %s", e);
         case MUX_S_FAILURE:          case MUX_S_FAILURE:
                 if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)                  if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
                         fatal("%s: decode error: %s", __func__, ssh_err(r));                          fatal_fr(r, "parse error message");
                 fatal("%s: stop listening request failed: %s", __func__, e);                  fatal_f("stop listening request failed: %s", e);
         default:          default:
                 fatal("%s: unexpected response from master 0x%08x",                  fatal_f("unexpected response from master 0x%08x", type);
                     __func__, type);  
         }          }
         sshbuf_free(m);          sshbuf_free(m);
         muxclient_request_id++;          muxclient_request_id++;
Line 2293 
Line 2260 
                      (unsigned int)sizeof(addr.sun_path));                       (unsigned int)sizeof(addr.sun_path));
   
         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)          if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
                 fatal("%s socket(): %s", __func__, strerror(errno));                  fatal_f("socket(): %s", strerror(errno));
   
         if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {          if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
                 switch (muxclient_command) {                  switch (muxclient_command) {
Line 2320 
Line 2287 
         set_nonblock(sock);          set_nonblock(sock);
   
         if (mux_client_hello_exchange(sock) != 0) {          if (mux_client_hello_exchange(sock) != 0) {
                 error("%s: master hello exchange failed", __func__);                  error_f("master hello exchange failed");
                 close(sock);                  close(sock);
                 return -1;                  return -1;
         }          }
Line 2328 
Line 2295 
         switch (muxclient_command) {          switch (muxclient_command) {
         case SSHMUX_COMMAND_ALIVE_CHECK:          case SSHMUX_COMMAND_ALIVE_CHECK:
                 if ((pid = mux_client_request_alive(sock)) == 0)                  if ((pid = mux_client_request_alive(sock)) == 0)
                         fatal("%s: master alive check failed", __func__);                          fatal_f("master alive check failed");
                 fprintf(stderr, "Master running (pid=%u)\r\n", pid);                  fprintf(stderr, "Master running (pid=%u)\r\n", pid);
                 exit(0);                  exit(0);
         case SSHMUX_COMMAND_TERMINATE:          case SSHMUX_COMMAND_TERMINATE:
Line 2338 
Line 2305 
                 exit(0);                  exit(0);
         case SSHMUX_COMMAND_FORWARD:          case SSHMUX_COMMAND_FORWARD:
                 if (mux_client_forwards(sock, 0) != 0)                  if (mux_client_forwards(sock, 0) != 0)
                         fatal("%s: master forward request failed", __func__);                          fatal_f("master forward request failed");
                 exit(0);                  exit(0);
         case SSHMUX_COMMAND_OPEN:          case SSHMUX_COMMAND_OPEN:
                 if (mux_client_forwards(sock, 0) != 0) {                  if (mux_client_forwards(sock, 0) != 0) {
                         error("%s: master forward request failed", __func__);                          error_f("master forward request failed");
                         return -1;                          return -1;
                 }                  }
                 mux_client_request_session(sock);                  mux_client_request_session(sock);
Line 2357 
Line 2324 
                 exit(0);                  exit(0);
         case SSHMUX_COMMAND_CANCEL_FWD:          case SSHMUX_COMMAND_CANCEL_FWD:
                 if (mux_client_forwards(sock, 1) != 0)                  if (mux_client_forwards(sock, 1) != 0)
                         error("%s: master cancel forward request failed",                          error_f("master cancel forward request failed");
                             __func__);  
                 exit(0);                  exit(0);
         case SSHMUX_COMMAND_PROXY:          case SSHMUX_COMMAND_PROXY:
                 mux_client_proxy(sock);                  mux_client_proxy(sock);

Legend:
Removed from v.1.84  
changed lines
  Added in v.1.85