changeset 10515:95e125dab827

6868716 dangling sshd authentication thread after timeout exit of monitor 6875551 remove the "authenticated" label from sshd.c
author Jan Pechanec <Jan.Pechanec@Sun.COM>
date Mon, 14 Sep 2009 08:35:38 -0700
parents 90bafd4ae0b0
children 73cc1414bac0
files usr/src/cmd/ssh/Makefile.ssh-common usr/src/cmd/ssh/libssh/common/compat.c usr/src/cmd/ssh/libssh/common/packet.c usr/src/cmd/ssh/sshd/altprivsep.c usr/src/cmd/ssh/sshd/sshd.c
diffstat 5 files changed, 42 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ssh/Makefile.ssh-common	Mon Sep 14 05:55:29 2009 -0700
+++ b/usr/src/cmd/ssh/Makefile.ssh-common	Mon Sep 14 08:35:38 2009 -0700
@@ -30,7 +30,7 @@
 CFLAGS += $(CCVERBOSE)
 LDFLAGS += $(MAPFILE.NGB:%=-M%)
 
-SSH_VERSION=\"Sun_SSH_1.4\"
+SSH_VERSION=\"Sun_SSH_1.5\"
 
 C99MODE= $(C99_ENABLE)
 
--- a/usr/src/cmd/ssh/libssh/common/compat.c	Mon Sep 14 05:55:29 2009 -0700
+++ b/usr/src/cmd/ssh/libssh/common/compat.c	Mon Sep 14 08:35:38 2009 -0700
@@ -111,6 +111,7 @@
 		{ "Sun_SSH_1.2*",	SSH_BUG_STRING_ENCODING},
 		{ "Sun_SSH_1.3*",	SSH_BUG_STRING_ENCODING},
 		{ "Sun_SSH_1.4*",	0 },
+		{ "Sun_SSH_1.5*",	0 },
 		{ "Sun_SSH_*",		0 },
 		{ "*MindTerm*",		0 },
 		{ "2.1.0*",		SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
--- a/usr/src/cmd/ssh/libssh/common/packet.c	Mon Sep 14 05:55:29 2009 -0700
+++ b/usr/src/cmd/ssh/libssh/common/packet.c	Mon Sep 14 08:35:38 2009 -0700
@@ -933,8 +933,11 @@
  * Waits until a packet has been received, and returns its type.  Note that
  * no other data is processed until this returns, so this function should not
  * be used during the interactive session.
+ *
+ * The function is also used in the monitor to read the authentication context
+ * in aps_read_auth_context() via packet_read_seqnr(), before the monitor enters
+ * aps_monitor_loop() and starts using the process_input() function.
  */
-
 int
 packet_read_seqnr(u_int32_t *seqnr_p)
 {
@@ -980,11 +983,22 @@
 		/* Read data from the socket. */
 		len = read(connection_in, buf, sizeof(buf));
 		if (len == 0) {
-			log("Connection closed by %.200s", get_remote_ipaddr());
+			if (packet_connection_is_on_socket())
+				log("Connection closed by %.200s",
+				    get_remote_ipaddr());
+			else
+				debug("child closed the communication pipe "
+				    "before user auth was finished");
 			fatal_cleanup();
 		}
-		if (len < 0)
-			fatal("Read from socket failed: %.100s", strerror(errno));
+		if (len < 0) {
+			if (packet_connection_is_on_socket())
+				fatal("Read from socket failed: %.100s",
+				    strerror(errno));
+			else
+				fatal("Read from communication pipe failed: "
+				    "%.100s", strerror(errno));
+		}
 		/* Append it to the buffer. */
 		packet_process_incoming(buf, len);
 	}
--- a/usr/src/cmd/ssh/sshd/altprivsep.c	Mon Sep 14 05:55:29 2009 -0700
+++ b/usr/src/cmd/ssh/sshd/altprivsep.c	Mon Sep 14 08:35:38 2009 -0700
@@ -1040,6 +1040,10 @@
 	return (buffer_get_string(&from_monitor, length_ptr));
 }
 
+/*
+ * Start and execute the code for the monitor which never returns from this
+ * function. The child will return and continue in the caller.
+ */
 void
 altprivsep_start_and_do_monitor(int use_engine, int inetd, int newsock,
 	int statup_pipe)
@@ -1072,12 +1076,6 @@
 		 *  - PAM cleanup
 		 */
 
-		/*
-		 * Alarm signal handler is for our child only since that's the
-		 * one that does the authentication.
-		 */
-		(void) alarm(0);
-		(void) signal(SIGALRM, SIG_DFL);
 		/* this is for MaxStartups and the child takes care of that */
 		(void) close(statup_pipe);
 		(void) pkcs11_engine_load(use_engine);
--- a/usr/src/cmd/ssh/sshd/sshd.c	Mon Sep 14 05:55:29 2009 -0700
+++ b/usr/src/cmd/ssh/sshd/sshd.c	Mon Sep 14 08:35:38 2009 -0700
@@ -318,15 +318,15 @@
 }
 
 /*
- * Signal handler for the alarm after the login grace period has expired.
+ * Signal handler for the alarm after the login grace period has expired. This
+ * is for the (soon-to-be) unprivileged child only. The monitor gets an event on
+ * the communication pipe and exits as well.
  */
 static void
 grace_alarm_handler(int sig)
 {
-	/* XXX no idea how fix this signal handler */
-
 	/* Log error and exit. */
-	fatal("Timeout before authentication for %s", get_remote_ipaddr());
+	fatal("Timeout before authentication for %.200s", get_remote_ipaddr());
 }
 
 #ifdef HAVE_SOLARIS_CONTRACTS
@@ -1512,18 +1512,6 @@
 	/* Log the connection. */
 	verbose("Connection from %.500s port %d", remote_ip, remote_port);
 
-	/*
-	 * We don\'t want to listen forever unless the other side
-	 * successfully authenticates itself.  So we set up an alarm which is
-	 * cleared after successful authentication.  A limit of zero
-	 * indicates no limit. Note that we don\'t set the alarm in debugging
-	 * mode; it is just annoying to have the server exit just when you
-	 * are about to discover the bug.
-	 */
-	(void) signal(SIGALRM, grace_alarm_handler);
-	if (!debug_flag)
-		(void) alarm(options.login_grace_time);
-
 	sshd_exchange_identification(sock_in, sock_out);
 	/*
 	 * Check that the connection comes from a privileged port.
@@ -1561,11 +1549,25 @@
 	 * PKCS#11 sessions. See the PKCS#11 standard for more information on
 	 * fork safety and packet.c for information about forking with the
 	 * engine.
+	 *
+	 * Note that the monitor stays in the function while the child is the
+	 * only one that returns.
 	 */
 	altprivsep_start_and_do_monitor(options.use_openssl_engine,
 	    inetd_flag, newsock, startup_pipe);
 
 	/*
+	 * We don't want to listen forever unless the other side successfully
+	 * authenticates itself. So we set up an alarm which is cleared after
+	 * successful authentication. A limit of zero indicates no limit. Note
+	 * that we don't set the alarm in debugging mode; it is just annoying to
+	 * have the server exit just when you are about to discover the bug.
+	 */
+	(void) signal(SIGALRM, grace_alarm_handler);
+	if (!debug_flag)
+		(void) alarm(options.login_grace_time);
+
+	/*
 	 * The child is about to start the first key exchange while the monitor
 	 * stays in altprivsep_start_and_do_monitor() function.
 	 */
@@ -1581,7 +1583,6 @@
 		authctxt = do_authentication();
 	}
 
-authenticated:
 	/* Authentication complete */
 	(void) alarm(0);
 	/* we no longer need an alarm handler */