vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Blob Blame History Raw
--- 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();