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

Diff for /src/usr.bin/ssh/ssh.c between version 1.226.2.3 and 1.227

version 1.226.2.3, 2005/09/02 03:45:01 version 1.227, 2004/09/15 00:46:01
Line 144 
Line 144 
 /* fd to control socket */  /* fd to control socket */
 int control_fd = -1;  int control_fd = -1;
   
 /* Multiplexing control command */  
 static u_int mux_command = 0;  
   
 /* Only used in control client mode */  /* Only used in control client mode */
 volatile sig_atomic_t control_client_terminate = 0;  volatile sig_atomic_t control_client_terminate = 0;
 u_int control_server_pid = 0;  u_int control_server_pid = 0;
Line 157 
Line 154 
 usage(void)  usage(void)
 {  {
         fprintf(stderr,          fprintf(stderr,
 "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"  "usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
 "           [-D port] [-e escape_char] [-F configfile]\n"  "           [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n"
 "           [-i identity_file] [-L [bind_address:]port:host:hostport]\n"  "           [-L port:host:hostport] [-l login_name] [-m mac_spec] [-o option]\n"
 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"  "           [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\n"
 "           [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"  
 "           [user@]hostname [command]\n"  
         );          );
         exit(1);          exit(1);
 }  }
Line 179 
Line 174 
 main(int ac, char **av)  main(int ac, char **av)
 {  {
         int i, opt, exit_status;          int i, opt, exit_status;
           u_short fwd_port, fwd_host_port;
           char sfwd_port[6], sfwd_host_port[6];
         char *p, *cp, *line, buf[256];          char *p, *cp, *line, buf[256];
         struct stat st;          struct stat st;
         struct passwd *pw;          struct passwd *pw;
         int dummy;          int dummy;
         extern int optind, optreset;          extern int optind, optreset;
         extern char *optarg;          extern char *optarg;
         struct servent *sp;  
         Forward fwd;  
   
         /*          /*
          * Save the original real uid.  It will be needed later (uid-swapping           * Save the original real uid.  It will be needed later (uid-swapping
Line 236 
Line 231 
   
 again:  again:
         while ((opt = getopt(ac, av,          while ((opt = getopt(ac, av,
             "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) {              "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) {
                 switch (opt) {                  switch (opt) {
                 case '1':                  case '1':
                         options.protocol = SSH_PROTO_1;                          options.protocol = SSH_PROTO_1;
Line 270 
Line 265 
                 case 'g':                  case 'g':
                         options.gateway_ports = 1;                          options.gateway_ports = 1;
                         break;                          break;
                 case 'O':  
                         if (strcmp(optarg, "check") == 0)  
                                 mux_command = SSHMUX_COMMAND_ALIVE_CHECK;  
                         else if (strcmp(optarg, "exit") == 0)  
                                 mux_command = SSHMUX_COMMAND_TERMINATE;  
                         else  
                                 fatal("Invalid multiplex command.");  
                         break;  
                 case 'P':       /* deprecated */                  case 'P':       /* deprecated */
                         options.use_privileged_port = 0;                          options.use_privileged_port = 0;
                         break;                          break;
Line 293 
Line 280 
                 case 'i':                  case 'i':
                         if (stat(optarg, &st) < 0) {                          if (stat(optarg, &st) < 0) {
                                 fprintf(stderr, "Warning: Identity file %s "                                  fprintf(stderr, "Warning: Identity file %s "
                                     "not accessible: %s.\n", optarg,                                      "does not exist.\n", optarg);
                                     strerror(errno));  
                                 break;                                  break;
                         }                          }
                         if (options.num_identity_files >=                          if (options.num_identity_files >=
Line 382 
Line 368 
                         }                          }
                         break;                          break;
                 case 'M':                  case 'M':
                         if (options.control_master == SSHCTL_MASTER_YES)                          options.control_master =
                                 options.control_master = SSHCTL_MASTER_ASK;                              (options.control_master >= 1) ? 2 : 1;
                         else  
                                 options.control_master = SSHCTL_MASTER_YES;  
                         break;                          break;
                 case 'p':                  case 'p':
                         options.port = a2port(optarg);                          options.port = a2port(optarg);
Line 399 
Line 383 
                         break;                          break;
   
                 case 'L':                  case 'L':
                         if (parse_forward(&fwd, optarg))                  case 'R':
                                 add_local_forward(&options, &fwd);                          if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]",
                         else {                              sfwd_port, buf, sfwd_host_port) != 3 &&
                               sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]",
                               sfwd_port, buf, sfwd_host_port) != 3) {
                                 fprintf(stderr,                                  fprintf(stderr,
                                     "Bad local forwarding specification '%s'\n",                                      "Bad forwarding specification '%s'\n",
                                     optarg);                                      optarg);
                                 exit(1);                                  usage();
                                   /* NOTREACHED */
                         }                          }
                         break;                          if ((fwd_port = a2port(sfwd_port)) == 0 ||
                               (fwd_host_port = a2port(sfwd_host_port)) == 0) {
                 case 'R':  
                         if (parse_forward(&fwd, optarg)) {  
                                 add_remote_forward(&options, &fwd);  
                         } else {  
                                 fprintf(stderr,                                  fprintf(stderr,
                                     "Bad remote forwarding specification "                                      "Bad forwarding port(s) '%s'\n", optarg);
                                     "'%s'\n", optarg);  
                                 exit(1);                                  exit(1);
                         }                          }
                           if (opt == 'L')
                                   add_local_forward(&options, fwd_port, buf,
                                       fwd_host_port);
                           else if (opt == 'R')
                                   add_remote_forward(&options, fwd_port, buf,
                                       fwd_host_port);
                         break;                          break;
   
                 case 'D':                  case 'D':
                         cp = p = xstrdup(optarg);                          fwd_port = a2port(optarg);
                         memset(&fwd, '\0', sizeof(fwd));                          if (fwd_port == 0) {
                         fwd.connect_host = "socks";  
                         if ((fwd.listen_host = hpdelim(&cp)) == NULL) {  
                                 fprintf(stderr, "Bad dynamic forwarding "  
                                     "specification '%.100s'\n", optarg);  
                                 exit(1);  
                         }  
                         if (cp != NULL) {  
                                 fwd.listen_port = a2port(cp);  
                                 fwd.listen_host = cleanhostname(fwd.listen_host);  
                         } else {  
                                 fwd.listen_port = a2port(fwd.listen_host);  
                                 fwd.listen_host = NULL;  
                         }  
   
                         if (fwd.listen_port == 0) {  
                                 fprintf(stderr, "Bad dynamic port '%s'\n",                                  fprintf(stderr, "Bad dynamic port '%s'\n",
                                     optarg);                                      optarg);
                                 exit(1);                                  exit(1);
                         }                          }
                         add_local_forward(&options, &fwd);                          add_local_forward(&options, fwd_port, "socks", 0);
                         xfree(p);  
                         break;                          break;
   
                 case 'C':                  case 'C':
Line 548 
Line 520 
         if (no_tty_flag)          if (no_tty_flag)
                 tty_flag = 0;                  tty_flag = 0;
         /* Do not allocate a tty if stdin is not a tty. */          /* Do not allocate a tty if stdin is not a tty. */
         if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {          if (!isatty(fileno(stdin)) && !force_tty_flag) {
                 if (tty_flag)                  if (tty_flag)
                         logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");                          logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
                 tty_flag = 0;                  tty_flag = 0;
Line 600 
Line 572 
                                 *p = tolower(*p);                                  *p = tolower(*p);
         }          }
   
         /* Get default port if port has not been set. */  
         if (options.port == 0) {  
                 sp = getservbyname(SSH_SERVICE_NAME, "tcp");  
                 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;  
         }  
   
         if (options.proxy_command != NULL &&          if (options.proxy_command != NULL &&
             strcmp(options.proxy_command, "none") == 0)              strcmp(options.proxy_command, "none") == 0)
                 options.proxy_command = NULL;                  options.proxy_command = NULL;
         if (options.control_path != NULL &&  
             strcmp(options.control_path, "none") == 0)  
                 options.control_path = NULL;  
   
         if (options.control_path != NULL) {          if (options.control_path != NULL) {
                 snprintf(buf, sizeof(buf), "%d", options.port);                  options.control_path = tilde_expand_filename(
                 cp = tilde_expand_filename(options.control_path,                     options.control_path, original_real_uid);
                     original_real_uid);  
                 options.control_path = percent_expand(cp, "p", buf, "h", host,  
                     "r", options.user, (char *)NULL);  
                 xfree(cp);  
         }          }
         if (mux_command != 0 && options.control_path == NULL)          if (options.control_path != NULL && options.control_master == 0)
                 fatal("No ControlPath specified for \"-O\" command");                  control_client(options.control_path); /* This doesn't return */
         if (options.control_path != NULL)  
                 control_client(options.control_path);  
   
         /* Open a connection to the remote host. */          /* Open a connection to the remote host. */
         if (ssh_connect(host, &hostaddr, options.port,          if (ssh_connect(host, &hostaddr, options.port,
Line 749 
Line 706 
         return exit_status;          return exit_status;
 }  }
   
   #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
   
 static void  static void
   x11_get_proto(char **_proto, char **_data)
   {
           char cmd[1024];
           char line[512];
           char xdisplay[512];
           static char proto[512], data[512];
           FILE *f;
           int got_data = 0, generated = 0, do_unlink = 0, i;
           char *display, *xauthdir, *xauthfile;
           struct stat st;
   
           xauthdir = xauthfile = NULL;
           *_proto = proto;
           *_data = data;
           proto[0] = data[0] = '\0';
   
           if (!options.xauth_location ||
               (stat(options.xauth_location, &st) == -1)) {
                   debug("No xauth program.");
           } else {
                   if ((display = getenv("DISPLAY")) == NULL) {
                           debug("x11_get_proto: DISPLAY not set");
                           return;
                   }
                   /*
                    * Handle FamilyLocal case where $DISPLAY does
                    * not match an authorization entry.  For this we
                    * just try "xauth list unix:displaynum.screennum".
                    * XXX: "localhost" match to determine FamilyLocal
                    *      is not perfect.
                    */
                   if (strncmp(display, "localhost:", 10) == 0) {
                           snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
                               display + 10);
                           display = xdisplay;
                   }
                   if (options.forward_x11_trusted == 0) {
                           xauthdir = xmalloc(MAXPATHLEN);
                           xauthfile = xmalloc(MAXPATHLEN);
                           strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
                           if (mkdtemp(xauthdir) != NULL) {
                                   do_unlink = 1;
                                   snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
                                       xauthdir);
                                   snprintf(cmd, sizeof(cmd),
                                       "%s -f %s generate %s " SSH_X11_PROTO
                                       " untrusted timeout 1200 2>" _PATH_DEVNULL,
                                       options.xauth_location, xauthfile, display);
                                   debug2("x11_get_proto: %s", cmd);
                                   if (system(cmd) == 0)
                                           generated = 1;
                           }
                   }
                   snprintf(cmd, sizeof(cmd),
                       "%s %s%s list %s . 2>" _PATH_DEVNULL,
                       options.xauth_location,
                       generated ? "-f " : "" ,
                       generated ? xauthfile : "",
                       display);
                   debug2("x11_get_proto: %s", cmd);
                   f = popen(cmd, "r");
                   if (f && fgets(line, sizeof(line), f) &&
                       sscanf(line, "%*s %511s %511s", proto, data) == 2)
                           got_data = 1;
                   if (f)
                           pclose(f);
           }
   
           if (do_unlink) {
                   unlink(xauthfile);
                   rmdir(xauthdir);
           }
           if (xauthdir)
                   xfree(xauthdir);
           if (xauthfile)
                   xfree(xauthfile);
   
           /*
            * If we didn't get authentication data, just make up some
            * data.  The forwarding code will check the validity of the
            * response anyway, and substitute this data.  The X11
            * server, however, will ignore this fake data and use
            * whatever authentication mechanisms it was using otherwise
            * for the local connection.
            */
           if (!got_data) {
                   u_int32_t rnd = 0;
   
                   logit("Warning: No xauth data; "
                       "using fake authentication data for X11 forwarding.");
                   strlcpy(proto, SSH_X11_PROTO, sizeof proto);
                   for (i = 0; i < 16; i++) {
                           if (i % 4 == 0)
                                   rnd = arc4random();
                           snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
                               rnd & 0xff);
                           rnd >>= 8;
                   }
           }
   }
   
   static void
 ssh_init_forwarding(void)  ssh_init_forwarding(void)
 {  {
         int success = 0;          int success = 0;
Line 757 
Line 818 
   
         /* Initiate local TCP/IP port forwardings. */          /* Initiate local TCP/IP port forwardings. */
         for (i = 0; i < options.num_local_forwards; i++) {          for (i = 0; i < options.num_local_forwards; i++) {
                 debug("Local connections to %.200s:%d forwarded to remote "                  debug("Connections to local port %d forwarded to remote address %.200s:%d",
                     "address %.200s:%d",                      options.local_forwards[i].port,
                     (options.local_forwards[i].listen_host == NULL) ?                      options.local_forwards[i].host,
                     (options.gateway_ports ? "*" : "LOCALHOST") :                      options.local_forwards[i].host_port);
                     options.local_forwards[i].listen_host,  
                     options.local_forwards[i].listen_port,  
                     options.local_forwards[i].connect_host,  
                     options.local_forwards[i].connect_port);  
                 success += channel_setup_local_fwd_listener(                  success += channel_setup_local_fwd_listener(
                     options.local_forwards[i].listen_host,                      options.local_forwards[i].port,
                     options.local_forwards[i].listen_port,                      options.local_forwards[i].host,
                     options.local_forwards[i].connect_host,                      options.local_forwards[i].host_port,
                     options.local_forwards[i].connect_port,  
                     options.gateway_ports);                      options.gateway_ports);
         }          }
         if (i > 0 && success == 0)          if (i > 0 && success == 0)
Line 777 
Line 833 
   
         /* Initiate remote TCP/IP port forwardings. */          /* Initiate remote TCP/IP port forwardings. */
         for (i = 0; i < options.num_remote_forwards; i++) {          for (i = 0; i < options.num_remote_forwards; i++) {
                 debug("Remote connections from %.200s:%d forwarded to "                  debug("Connections to remote port %d forwarded to local address %.200s:%d",
                     "local address %.200s:%d",                      options.remote_forwards[i].port,
                     (options.remote_forwards[i].listen_host == NULL) ?                      options.remote_forwards[i].host,
                     (options.gateway_ports ? "*" : "LOCALHOST") :                      options.remote_forwards[i].host_port);
                     options.remote_forwards[i].listen_host,  
                     options.remote_forwards[i].listen_port,  
                     options.remote_forwards[i].connect_host,  
                     options.remote_forwards[i].connect_port);  
                 channel_request_remote_forwarding(                  channel_request_remote_forwarding(
                     options.remote_forwards[i].listen_host,                      options.remote_forwards[i].port,
                     options.remote_forwards[i].listen_port,                      options.remote_forwards[i].host,
                     options.remote_forwards[i].connect_host,                      options.remote_forwards[i].host_port);
                     options.remote_forwards[i].connect_port);  
         }          }
 }  }
   
Line 811 
Line 862 
         int have_tty = 0;          int have_tty = 0;
         struct winsize ws;          struct winsize ws;
         char *cp;          char *cp;
         const char *display;  
   
         /* Enable compression if requested. */          /* Enable compression if requested. */
         if (options.compression) {          if (options.compression) {
Line 873 
Line 923 
                         packet_disconnect("Protocol error waiting for pty request response.");                          packet_disconnect("Protocol error waiting for pty request response.");
         }          }
         /* Request X11 forwarding if enabled and DISPLAY is set. */          /* Request X11 forwarding if enabled and DISPLAY is set. */
         display = getenv("DISPLAY");          if (options.forward_x11 && getenv("DISPLAY") != NULL) {
         if (options.forward_x11 && display != NULL) {  
                 char *proto, *data;                  char *proto, *data;
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 client_x11_get_proto(display, options.xauth_location,                  x11_get_proto(&proto, &data);
                     options.forward_x11_trusted, &proto, &data);  
                 /* Request forwarding with authentication spoofing. */                  /* Request forwarding with authentication spoofing. */
                 debug("Requesting X11 forwarding with authentication spoofing.");                  debug("Requesting X11 forwarding with authentication spoofing.");
                 x11_request_forwarding_with_spoofing(0, display, proto, data);                  x11_request_forwarding_with_spoofing(0, proto, data);
   
                 /* Read response from the server. */                  /* Read response from the server. */
                 type = packet_read();                  type = packet_read();
Line 968 
Line 1016 
                 return;                  return;
         debug("remote forward %s for: listen %d, connect %s:%d",          debug("remote forward %s for: listen %d, connect %s:%d",
             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",              type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
             options.remote_forwards[i].listen_port,              options.remote_forwards[i].port,
             options.remote_forwards[i].connect_host,              options.remote_forwards[i].host,
             options.remote_forwards[i].connect_port);              options.remote_forwards[i].host_port);
         if (type == SSH2_MSG_REQUEST_FAILURE)          if (type == SSH2_MSG_REQUEST_FAILURE)
                 logit("Warning: remote port forwarding failed for listen "                  logit("Warning: remote port forwarding failed for listen port %d",
                     "port %d", options.remote_forwards[i].listen_port);                      options.remote_forwards[i].port);
 }  }
   
 static void  static void
Line 982 
Line 1030 
         struct sockaddr_un addr;          struct sockaddr_un addr;
         mode_t old_umask;          mode_t old_umask;
   
         if (options.control_path == NULL ||          if (options.control_path == NULL || options.control_master <= 0)
             options.control_master == SSHCTL_MASTER_NO)  
                 return;                  return;
   
         debug("setting up multiplex master socket");  
   
         memset(&addr, '\0', sizeof(addr));          memset(&addr, '\0', sizeof(addr));
         addr.sun_family = AF_UNIX;          addr.sun_family = AF_UNIX;
         addr.sun_len = offsetof(struct sockaddr_un, sun_path) +          addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
Line 1003 
Line 1048 
         old_umask = umask(0177);          old_umask = umask(0177);
         if (bind(control_fd, (struct sockaddr*)&addr, addr.sun_len) == -1) {          if (bind(control_fd, (struct sockaddr*)&addr, addr.sun_len) == -1) {
                 control_fd = -1;                  control_fd = -1;
                 if (errno == EINVAL || errno == EADDRINUSE)                  if (errno == EINVAL)
                         fatal("ControlSocket %s already exists",                          fatal("ControlSocket %s already exists",
                             options.control_path);                              options.control_path);
                 else                  else
Line 1022 
Line 1067 
 ssh_session2_setup(int id, void *arg)  ssh_session2_setup(int id, void *arg)
 {  {
         extern char **environ;          extern char **environ;
         const char *display;  
         int interactive = tty_flag;  
   
         display = getenv("DISPLAY");          int interactive = tty_flag;
         if (options.forward_x11 && display != NULL) {          if (options.forward_x11 && getenv("DISPLAY") != NULL) {
                 char *proto, *data;                  char *proto, *data;
                 /* Get reasonable local authentication information. */                  /* Get reasonable local authentication information. */
                 client_x11_get_proto(display, options.xauth_location,                  x11_get_proto(&proto, &data);
                     options.forward_x11_trusted, &proto, &data);  
                 /* Request forwarding with authentication spoofing. */                  /* Request forwarding with authentication spoofing. */
                 debug("Requesting X11 forwarding with authentication spoofing.");                  debug("Requesting X11 forwarding with authentication spoofing.");
                 x11_request_forwarding_with_spoofing(id, display, proto, data);                  x11_request_forwarding_with_spoofing(id, proto, data);
                 interactive = 1;                  interactive = 1;
                 /* XXX wait for reply */                  /* XXX wait for reply */
         }          }
Line 1195 
Line 1237 
 control_client(const char *path)  control_client(const char *path)
 {  {
         struct sockaddr_un addr;          struct sockaddr_un addr;
         int i, r, fd, sock, exitval, num_env;          int i, r, sock, exitval, num_env;
         Buffer m;          Buffer m;
         char *term;          char *cp;
         extern char **environ;          extern char **environ;
         u_int  flags;  
   
         if (mux_command == 0)  
                 mux_command = SSHMUX_COMMAND_OPEN;  
   
         switch (options.control_master) {  
         case SSHCTL_MASTER_AUTO:  
         case SSHCTL_MASTER_AUTO_ASK:  
                 debug("auto-mux: Trying existing master");  
                 /* FALLTHROUGH */  
         case SSHCTL_MASTER_NO:  
                 break;  
         default:  
                 return;  
         }  
   
         memset(&addr, '\0', sizeof(addr));          memset(&addr, '\0', sizeof(addr));
         addr.sun_family = AF_UNIX;          addr.sun_family = AF_UNIX;
         addr.sun_len = offsetof(struct sockaddr_un, sun_path) +          addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
Line 1227 
Line 1254 
         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)          if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
                 fatal("%s socket(): %s", __func__, strerror(errno));                  fatal("%s socket(): %s", __func__, strerror(errno));
   
         if (connect(sock, (struct sockaddr*)&addr, addr.sun_len) == -1) {          if (connect(sock, (struct sockaddr*)&addr, addr.sun_len) == -1)
                 if (mux_command != SSHMUX_COMMAND_OPEN) {                  fatal("Couldn't connect to %s: %s", path, strerror(errno));
                         fatal("Control socket connect(%.100s): %s", path,  
                             strerror(errno));  
                 }  
                 if (errno == ENOENT)  
                         debug("Control socket \"%.100s\" does not exist", path);  
                 else {  
                         error("Control socket connect(%.100s): %s", path,  
                             strerror(errno));  
                 }  
                 close(sock);  
                 return;  
         }  
   
         if (stdin_null_flag) {          if ((cp = getenv("TERM")) == NULL)
                 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)                  cp = "";
                         fatal("open(/dev/null): %s", strerror(errno));  
                 if (dup2(fd, STDIN_FILENO) == -1)  
                         fatal("dup2: %s", strerror(errno));  
                 if (fd > STDERR_FILENO)  
                         close(fd);  
         }  
   
         term = getenv("TERM");  
   
         flags = 0;  
         if (tty_flag)  
                 flags |= SSHMUX_FLAG_TTY;  
         if (subsystem_flag)  
                 flags |= SSHMUX_FLAG_SUBSYS;  
         if (options.forward_x11)  
                 flags |= SSHMUX_FLAG_X11_FWD;  
         if (options.forward_agent)  
                 flags |= SSHMUX_FLAG_AGENT_FWD;  
   
         buffer_init(&m);          buffer_init(&m);
   
         /* Send our command to server */          /* Get PID of controlee */
         buffer_put_int(&m, mux_command);  
         buffer_put_int(&m, flags);  
         if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)  
                 fatal("%s: msg_send", __func__);  
         buffer_clear(&m);  
   
         /* Get authorisation status and PID of controlee */  
         if (ssh_msg_recv(sock, &m) == -1)          if (ssh_msg_recv(sock, &m) == -1)
                 fatal("%s: msg_recv", __func__);                  fatal("%s: msg_recv", __func__);
         if (buffer_get_char(&m) != SSHMUX_VER)          if (buffer_get_char(&m) != 0)
                 fatal("%s: wrong version", __func__);                  fatal("%s: wrong version", __func__);
           /* Connection allowed? */
         if (buffer_get_int(&m) != 1)          if (buffer_get_int(&m) != 1)
                 fatal("Connection to master denied");                  fatal("Connection to master denied");
         control_server_pid = buffer_get_int(&m);          control_server_pid = buffer_get_int(&m);
   
         buffer_clear(&m);          buffer_clear(&m);
           buffer_put_int(&m, tty_flag);
           buffer_put_int(&m, subsystem_flag);
           buffer_put_cstring(&m, cp);
   
         switch (mux_command) {  
         case SSHMUX_COMMAND_ALIVE_CHECK:  
                 fprintf(stderr, "Master running (pid=%d)\r\n",  
                     control_server_pid);  
                 exit(0);  
         case SSHMUX_COMMAND_TERMINATE:  
                 fprintf(stderr, "Exit request sent.\r\n");  
                 exit(0);  
         case SSHMUX_COMMAND_OPEN:  
                 /* continue below */  
                 break;  
         default:  
                 fatal("silly mux_command %d", mux_command);  
         }  
   
         /* SSHMUX_COMMAND_OPEN */  
         buffer_put_cstring(&m, term ? term : "");  
         buffer_append(&command, "\0", 1);          buffer_append(&command, "\0", 1);
         buffer_put_cstring(&m, buffer_ptr(&command));          buffer_put_cstring(&m, buffer_ptr(&command));
   
Line 1321 
Line 1298 
                         }                          }
         }          }
   
         if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)          if (ssh_msg_send(sock, /* version */0, &m) == -1)
                 fatal("%s: msg_send", __func__);                  fatal("%s: msg_send", __func__);
   
         mm_send_fd(sock, STDIN_FILENO);          mm_send_fd(sock, STDIN_FILENO);
Line 1332 
Line 1309 
         buffer_clear(&m);          buffer_clear(&m);
         if (ssh_msg_recv(sock, &m) == -1)          if (ssh_msg_recv(sock, &m) == -1)
                 fatal("%s: msg_recv", __func__);                  fatal("%s: msg_recv", __func__);
         if (buffer_get_char(&m) != SSHMUX_VER)          if (buffer_get_char(&m) != 0)
                 fatal("%s: wrong version", __func__);                  fatal("%s: master returned error", __func__);
         buffer_free(&m);          buffer_free(&m);
   
         signal(SIGHUP, control_client_sighandler);          signal(SIGHUP, control_client_sighandler);

Legend:
Removed from v.1.226.2.3  
changed lines
  Added in v.1.227