vishalmishra434 / rpms / openssh

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