[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.45 and 1.46

version 1.45, 2014/04/28 03:09:18 version 1.46, 2014/07/15 15:54:14
Line 496 
Line 496 
 }  }
   
 static char *  static char *
 format_forward(u_int ftype, Forward *fwd)  format_forward(u_int ftype, struct Forward *fwd)
 {  {
         char *ret;          char *ret;
   
         switch (ftype) {          switch (ftype) {
         case MUX_FWD_LOCAL:          case MUX_FWD_LOCAL:
                 xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",                  xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
                       (fwd->listen_path != NULL) ? fwd->listen_path :
                     (fwd->listen_host == NULL) ?                      (fwd->listen_host == NULL) ?
                     (options.gateway_ports ? "*" : "LOCALHOST") :                      (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
                     fwd->listen_host, fwd->listen_port,                      fwd->listen_host, fwd->listen_port,
                       (fwd->connect_path != NULL) ? fwd->connect_path :
                     fwd->connect_host, fwd->connect_port);                      fwd->connect_host, fwd->connect_port);
                 break;                  break;
         case MUX_FWD_DYNAMIC:          case MUX_FWD_DYNAMIC:
                 xasprintf(&ret, "dynamic forward %.200s:%d -> *",                  xasprintf(&ret, "dynamic forward %.200s:%d -> *",
                     (fwd->listen_host == NULL) ?                      (fwd->listen_host == NULL) ?
                     (options.gateway_ports ? "*" : "LOCALHOST") :                      (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
                      fwd->listen_host, fwd->listen_port);                       fwd->listen_host, fwd->listen_port);
                 break;                  break;
         case MUX_FWD_REMOTE:          case MUX_FWD_REMOTE:
                 xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",                  xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
                       (fwd->listen_path != NULL) ? fwd->listen_path :
                     (fwd->listen_host == NULL) ?                      (fwd->listen_host == NULL) ?
                     "LOCALHOST" : fwd->listen_host,                      "LOCALHOST" : fwd->listen_host,
                     fwd->listen_port,                      fwd->listen_port,
                       (fwd->connect_path != NULL) ? fwd->connect_path :
                     fwd->connect_host, fwd->connect_port);                      fwd->connect_host, fwd->connect_port);
                 break;                  break;
         default:          default:
Line 538 
Line 542 
 }  }
   
 static int  static int
 compare_forward(Forward *a, Forward *b)  compare_forward(struct Forward *a, struct Forward *b)
 {  {
         if (!compare_host(a->listen_host, b->listen_host))          if (!compare_host(a->listen_host, b->listen_host))
                 return 0;                  return 0;
           if (!compare_host(a->listen_path, b->listen_path))
                   return 0;
         if (a->listen_port != b->listen_port)          if (a->listen_port != b->listen_port)
                 return 0;                  return 0;
         if (!compare_host(a->connect_host, b->connect_host))          if (!compare_host(a->connect_host, b->connect_host))
                 return 0;                  return 0;
           if (!compare_host(a->connect_path, b->connect_path))
                   return 0;
         if (a->connect_port != b->connect_port)          if (a->connect_port != b->connect_port)
                 return 0;                  return 0;
   
Line 557 
Line 565 
 {  {
         struct mux_channel_confirm_ctx *fctx = ctxt;          struct mux_channel_confirm_ctx *fctx = ctxt;
         char *failmsg = NULL;          char *failmsg = NULL;
         Forward *rfwd;          struct Forward *rfwd;
         Channel *c;          Channel *c;
         Buffer out;          Buffer out;
   
Line 574 
Line 582 
         rfwd = &options.remote_forwards[fctx->fid];          rfwd = &options.remote_forwards[fctx->fid];
         debug("%s: %s for: listen %d, connect %s:%d", __func__,          debug("%s: %s for: listen %d, connect %s:%d", __func__,
             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",              type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
             rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);              rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
               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) {
                         rfwd->allocated_port = packet_get_int();                          rfwd->allocated_port = packet_get_int();
Line 594 
Line 603 
         } else {          } else {
                 if (rfwd->listen_port == 0)                  if (rfwd->listen_port == 0)
                         channel_update_permitted_opens(rfwd->handle, -1);                          channel_update_permitted_opens(rfwd->handle, -1);
                 xasprintf(&failmsg, "remote port forwarding failed for "                  if (rfwd->listen_path != NULL)
                     "listen port %d", rfwd->listen_port);                          xasprintf(&failmsg, "remote port forwarding failed for "
                               "listen path %s", rfwd->listen_path);
                   else
                           xasprintf(&failmsg, "remote port forwarding failed for "
                               "listen port %d", rfwd->listen_port);
         }          }
  fail:   fail:
         error("%s: %s", __func__, failmsg);          error("%s: %s", __func__, failmsg);
Line 614 
Line 627 
 static int  static int
 process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)  process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 {  {
         Forward fwd;          struct Forward fwd;
         char *fwd_desc = NULL;          char *fwd_desc = NULL;
           char *listen_addr, *connect_addr;
         u_int ftype;          u_int ftype;
         u_int lport, cport;          u_int lport, cport;
         int i, ret = 0, freefwd = 1;          int i, ret = 0, freefwd = 1;
   
         fwd.listen_host = fwd.connect_host = NULL;          /* XXX - lport/cport check redundant */
         if (buffer_get_int_ret(&ftype, m) != 0 ||          if (buffer_get_int_ret(&ftype, m) != 0 ||
             (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||              (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
             buffer_get_int_ret(&lport, m) != 0 ||              buffer_get_int_ret(&lport, m) != 0 ||
             (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||              (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
             buffer_get_int_ret(&cport, m) != 0 ||              buffer_get_int_ret(&cport, m) != 0 ||
             lport > 65535 || cport > 65535) {              (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
               (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
                 error("%s: malformed message", __func__);                  error("%s: malformed message", __func__);
                 ret = -1;                  ret = -1;
                 goto out;                  goto out;
         }          }
         fwd.listen_port = lport;          if (*listen_addr == '\0') {
         fwd.connect_port = cport;                  free(listen_addr);
         if (*fwd.listen_host == '\0') {                  listen_addr = NULL;
                 free(fwd.listen_host);  
                 fwd.listen_host = NULL;  
         }          }
         if (*fwd.connect_host == '\0') {          if (*connect_addr == '\0') {
                 free(fwd.connect_host);                  free(connect_addr);
                 fwd.connect_host = NULL;                  connect_addr = NULL;
         }          }
   
           memset(&fwd, 0, sizeof(fwd));
           fwd.listen_port = lport;
           if (fwd.listen_port == PORT_STREAMLOCAL)
                   fwd.listen_path = listen_addr;
           else
                   fwd.listen_host = listen_addr;
           fwd.connect_port = cport;
           if (fwd.connect_port == PORT_STREAMLOCAL)
                   fwd.connect_path = connect_addr;
           else
                   fwd.connect_host = connect_addr;
   
         debug2("%s: channel %d: request %s", __func__, c->self,          debug2("%s: channel %d: request %s", __func__, c->self,
             (fwd_desc = format_forward(ftype, &fwd)));              (fwd_desc = format_forward(ftype, &fwd)));
   
Line 649 
Line 674 
             ftype != MUX_FWD_DYNAMIC) {              ftype != MUX_FWD_DYNAMIC) {
                 logit("%s: invalid forwarding type %u", __func__, ftype);                  logit("%s: invalid forwarding type %u", __func__, ftype);
  invalid:   invalid:
                 free(fwd.listen_host);                  free(listen_addr);
                 free(fwd.connect_host);                  free(connect_addr);
                 buffer_put_int(r, MUX_S_FAILURE);                  buffer_put_int(r, MUX_S_FAILURE);
                 buffer_put_int(r, rid);                  buffer_put_int(r, rid);
                 buffer_put_cstring(r, "Invalid forwarding request");                  buffer_put_cstring(r, "Invalid forwarding request");
                 return 0;                  return 0;
         }          }
         if (fwd.listen_port >= 65536) {          if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
                   logit("%s: streamlocal and dynamic forwards "
                       "are mutually exclusive", __func__);
                   goto invalid;
           }
           if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
                 logit("%s: invalid listen port %u", __func__,                  logit("%s: invalid listen port %u", __func__,
                     fwd.listen_port);                      fwd.listen_port);
                 goto invalid;                  goto invalid;
         }          }
         if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC &&          if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536)
             ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {              || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
                 logit("%s: invalid connect port %u", __func__,                  logit("%s: invalid connect port %u", __func__,
                     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) {
                 logit("%s: missing connect host", __func__);                  logit("%s: missing connect host", __func__);
                 goto invalid;                  goto invalid;
         }          }
Line 718 
Line 748 
         }          }
   
         if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {          if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
                 if (!channel_setup_local_fwd_listener(fwd.listen_host,                  if (!channel_setup_local_fwd_listener(&fwd,
                     fwd.listen_port, fwd.connect_host, fwd.connect_port,                      &options.fwd_opts)) {
                     options.gateway_ports)) {  
  fail:   fail:
                         logit("slave-requested %s failed", fwd_desc);                          logit("slave-requested %s failed", fwd_desc);
                         buffer_put_int(r, MUX_S_FAILURE);                          buffer_put_int(r, MUX_S_FAILURE);
Line 733 
Line 762 
         } else {          } else {
                 struct mux_channel_confirm_ctx *fctx;                  struct mux_channel_confirm_ctx *fctx;
   
                 fwd.handle = channel_request_remote_forwarding(fwd.listen_host,                  fwd.handle = channel_request_remote_forwarding(&fwd);
                     fwd.listen_port, fwd.connect_host, fwd.connect_port);  
                 if (fwd.handle < 0)                  if (fwd.handle < 0)
                         goto fail;                          goto fail;
                 add_remote_forward(&options, &fwd);                  add_remote_forward(&options, &fwd);
Line 755 
Line 783 
         free(fwd_desc);          free(fwd_desc);
         if (freefwd) {          if (freefwd) {
                 free(fwd.listen_host);                  free(fwd.listen_host);
                   free(fwd.listen_path);
                 free(fwd.connect_host);                  free(fwd.connect_host);
                   free(fwd.connect_path);
         }          }
         return ret;          return ret;
 }  }
Line 763 
Line 793 
 static int  static int
 process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)  process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
 {  {
         Forward fwd, *found_fwd;          struct Forward fwd, *found_fwd;
         char *fwd_desc = NULL;          char *fwd_desc = NULL;
         const char *error_reason = NULL;          const char *error_reason = NULL;
           char *listen_addr = NULL, *connect_addr = NULL;
         u_int ftype;          u_int ftype;
         int i, listen_port, ret = 0;          int i, ret = 0;
         u_int lport, cport;          u_int lport, cport;
   
         fwd.listen_host = fwd.connect_host = NULL;  
         if (buffer_get_int_ret(&ftype, m) != 0 ||          if (buffer_get_int_ret(&ftype, m) != 0 ||
             (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL ||              (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
             buffer_get_int_ret(&lport, m) != 0 ||              buffer_get_int_ret(&lport, m) != 0 ||
             (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL ||              (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
             buffer_get_int_ret(&cport, m) != 0 ||              buffer_get_int_ret(&cport, m) != 0 ||
             lport > 65535 || cport > 65535) {              (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
               (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
                 error("%s: malformed message", __func__);                  error("%s: malformed message", __func__);
                 ret = -1;                  ret = -1;
                 goto out;                  goto out;
         }          }
         fwd.listen_port = lport;  
         fwd.connect_port = cport;  
   
         if (*fwd.listen_host == '\0') {          if (*listen_addr == '\0') {
                 free(fwd.listen_host);                  free(listen_addr);
                 fwd.listen_host = NULL;                  listen_addr = NULL;
         }          }
         if (*fwd.connect_host == '\0') {          if (*connect_addr == '\0') {
                 free(fwd.connect_host);                  free(connect_addr);
                 fwd.connect_host = NULL;                  connect_addr = NULL;
         }          }
   
           memset(&fwd, 0, sizeof(fwd));
           fwd.listen_port = lport;
           if (fwd.listen_port == PORT_STREAMLOCAL)
                   fwd.listen_path = listen_addr;
           else
                   fwd.listen_host = listen_addr;
           fwd.connect_port = cport;
           if (fwd.connect_port == PORT_STREAMLOCAL)
                   fwd.connect_path = connect_addr;
           else
                   fwd.connect_host = connect_addr;
   
         debug2("%s: channel %d: request cancel %s", __func__, c->self,          debug2("%s: channel %d: request cancel %s", __func__, c->self,
             (fwd_desc = format_forward(ftype, &fwd)));              (fwd_desc = format_forward(ftype, &fwd)));
   
Line 827 
Line 868 
                  * This shouldn't fail unless we confused the host/port                   * This shouldn't fail unless we confused the host/port
                  * between options.remote_forwards and permitted_opens.                   * between options.remote_forwards and permitted_opens.
                  * However, for dynamic allocated listen ports we need                   * However, for dynamic allocated listen ports we need
                  * to lookup the actual listen port.                   * to use the actual listen port.
                  */                   */
                 listen_port = (fwd.listen_port == 0) ?                  if (channel_request_rforward_cancel(found_fwd) == -1)
                     found_fwd->allocated_port : fwd.listen_port;  
                 if (channel_request_rforward_cancel(fwd.listen_host,  
                     listen_port) == -1)  
                         error_reason = "port not in permitted opens";                          error_reason = "port not in permitted opens";
         } else {        /* local and dynamic forwards */          } else {        /* local and dynamic forwards */
                 /* Ditto */                  /* Ditto */
                 if (channel_cancel_lport_listener(fwd.listen_host,                  if (channel_cancel_lport_listener(&fwd, fwd.connect_port,
                     fwd.listen_port, fwd.connect_port,                      &options.fwd_opts) == -1)
                     options.gateway_ports) == -1)  
                         error_reason = "port not found";                          error_reason = "port not found";
         }          }
   
Line 847 
Line 884 
                 buffer_put_int(r, rid);                  buffer_put_int(r, rid);
   
                 free(found_fwd->listen_host);                  free(found_fwd->listen_host);
                   free(found_fwd->listen_path);
                 free(found_fwd->connect_host);                  free(found_fwd->connect_host);
                   free(found_fwd->connect_path);
                 found_fwd->listen_host = found_fwd->connect_host = NULL;                  found_fwd->listen_host = found_fwd->connect_host = NULL;
                   found_fwd->listen_path = found_fwd->connect_path = NULL;
                 found_fwd->listen_port = found_fwd->connect_port = 0;                  found_fwd->listen_port = found_fwd->connect_port = 0;
         } else {          } else {
                 buffer_put_int(r, MUX_S_FAILURE);                  buffer_put_int(r, MUX_S_FAILURE);
Line 857 
Line 897 
         }          }
  out:   out:
         free(fwd_desc);          free(fwd_desc);
         free(fwd.listen_host);          free(listen_addr);
         free(fwd.connect_host);          free(connect_addr);
   
         return ret;          return ret;
 }  }
Line 1120 
Line 1160 
 void  void
 muxserver_listen(void)  muxserver_listen(void)
 {  {
         struct sockaddr_un addr;  
         mode_t old_umask;          mode_t old_umask;
         char *orig_control_path = options.control_path;          char *orig_control_path = options.control_path;
         char rbuf[16+1];          char rbuf[16+1];
Line 1149 
Line 1188 
         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("%s: temporary control path %s", __func__, options.control_path);
   
         memset(&addr, '\0', sizeof(addr));  
         addr.sun_family = AF_UNIX;  
         addr.sun_len = offsetof(struct sockaddr_un, sun_path) +  
             strlen(options.control_path) + 1;  
   
         if (strlcpy(addr.sun_path, options.control_path,  
             sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {  
                 error("ControlPath \"%s\" too long for Unix domain socket",  
                     options.control_path);  
                 goto disable_mux_master;  
         }  
   
         if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)  
                 fatal("%s socket(): %s", __func__, strerror(errno));  
   
         old_umask = umask(0177);          old_umask = umask(0177);
         if (bind(muxserver_sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {          muxserver_sock = unix_listener(options.control_path, 64, 0);
           umask(old_umask);
           if (muxserver_sock < 0) {
                 if (errno == EINVAL || errno == EADDRINUSE) {                  if (errno == EINVAL || errno == EADDRINUSE) {
                         error("ControlSocket %s already exists, "                          error("ControlSocket %s already exists, "
                             "disabling multiplexing", options.control_path);                              "disabling multiplexing", options.control_path);
Line 1179 
Line 1205 
                         options.control_path = NULL;                          options.control_path = NULL;
                         options.control_master = SSHCTL_MASTER_NO;                          options.control_master = SSHCTL_MASTER_NO;
                         return;                          return;
                 } else                  } else {
                         fatal("%s bind(): %s", __func__, strerror(errno));                          /* unix_listener() logs the error */
                           cleanup_exit(255);
                   }
         }          }
         umask(old_umask);  
   
         if (listen(muxserver_sock, 64) == -1)  
                 fatal("%s listen(): %s", __func__, strerror(errno));  
   
         /* 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) {
Line 1573 
Line 1597 
 }  }
   
 static int  static int
 mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)  mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
 {  {
         Buffer m;          Buffer m;
         char *e, *fwd_desc;          char *e, *fwd_desc;
Line 1588 
Line 1612 
         buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);          buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
         buffer_put_int(&m, muxclient_request_id);          buffer_put_int(&m, muxclient_request_id);
         buffer_put_int(&m, ftype);          buffer_put_int(&m, ftype);
         buffer_put_cstring(&m,          if (fwd->listen_path != NULL) {
             fwd->listen_host == NULL ? "" : fwd->listen_host);                  buffer_put_cstring(&m, fwd->listen_path);
           } else {
                   buffer_put_cstring(&m,
                       fwd->listen_host == NULL ? "" : fwd->listen_host);
           }
         buffer_put_int(&m, fwd->listen_port);          buffer_put_int(&m, fwd->listen_port);
         buffer_put_cstring(&m,          if (fwd->connect_path != NULL) {
             fwd->connect_host == NULL ? "" : fwd->connect_host);                  buffer_put_cstring(&m, fwd->connect_path);
           } else {
                   buffer_put_cstring(&m,
                       fwd->connect_host == NULL ? "" : fwd->connect_host);
           }
         buffer_put_int(&m, fwd->connect_port);          buffer_put_int(&m, fwd->connect_port);
   
         if (mux_client_write_packet(fd, &m) != 0)          if (mux_client_write_packet(fd, &m) != 0)

Legend:
Removed from v.1.45  
changed lines
  Added in v.1.46