openssh/openssh-4.7p1-master-race.p...

86 lines
2.5 KiB
Diff

--- openssh-4.7p1/ssh.c.masterrace 2008-03-06 13:55:11.000000000 +0000
+++ openssh-4.7p1/ssh.c 2008-03-06 13:55:19.000000000 +0000
@@ -1065,7 +1065,7 @@ client_global_request_reply_fwd(int type
}
}
-static void
+static int
ssh_control_listener(void)
{
struct sockaddr_un addr;
@@ -1073,10 +1073,11 @@ ssh_control_listener(void)
int addr_len;
if (options.control_path == NULL ||
- options.control_master == SSHCTL_MASTER_NO)
- return;
+ options.control_master == SSHCTL_MASTER_NO ||
+ control_fd != -1)
+ return 1;
- debug("setting up multiplex master socket");
+ debug("trying to set up multiplex master socket");
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
@@ -1093,11 +1094,9 @@ ssh_control_listener(void)
old_umask = umask(0177);
if (bind(control_fd, (struct sockaddr *)&addr, addr_len) == -1) {
control_fd = -1;
- if (errno == EINVAL || errno == EADDRINUSE)
- fatal("ControlSocket %s already exists",
- options.control_path);
- else
+ if (errno != EINVAL && errno != EADDRINUSE)
fatal("%s bind(): %s", __func__, strerror(errno));
+ return 0;
}
umask(old_umask);
@@ -1105,6 +1104,9 @@ ssh_control_listener(void)
fatal("%s listen(): %s", __func__, strerror(errno));
set_nonblock(control_fd);
+
+ debug("control master listening on %s", options.control_path);
+ return 1;
}
/* request pty/x11/agent/tcpfwd/shell for channel */
@@ -1196,7 +1198,9 @@ ssh_session2(void)
ssh_init_forwarding();
/* Start listening for multiplex clients */
- ssh_control_listener();
+ if (!ssh_control_listener())
+ fatal("control master socket %s already exists",
+ options.control_path);
/*
* If we are the control master, and if control_persist is set,
@@ -1375,7 +1379,13 @@ control_client(const char *path)
switch (options.control_master) {
case SSHCTL_MASTER_AUTO:
case SSHCTL_MASTER_AUTO_ASK:
- debug("auto-mux: Trying existing master");
+ /* see if we can create a control master socket
+ to avoid a race between two auto clients */
+ if (mux_command == SSHMUX_COMMAND_OPEN &&
+ ssh_control_listener())
+ return;
+ debug("trying to connect to control master socket %s",
+ options.control_path);
/* FALLTHROUGH */
case SSHCTL_MASTER_NO:
break;
@@ -1522,6 +1532,8 @@ control_client(const char *path)
signal(SIGTERM, control_client_sighandler);
signal(SIGWINCH, control_client_sigrelay);
+ debug("connected to control master; waiting for exit");
+
if (tty_flag)
enter_raw_mode();