changeset 3946:0cc6f51aa203

PSARC 2007/034 ssh/sshd resync with OpenSSH 6480090 ConnectTimeout functionality desired for SUNWssh
author jp161948
date Mon, 02 Apr 2007 05:33:26 -0700
parents 84f23e74ca15
children ed1a1295c374
files usr/src/cmd/ssh/include/readconf.h usr/src/cmd/ssh/include/xmalloc.h usr/src/cmd/ssh/libssh/common/misc.c usr/src/cmd/ssh/libssh/common/readconf.c usr/src/cmd/ssh/libssh/common/xmalloc.c usr/src/cmd/ssh/ssh/sshconnect.c
diffstat 6 files changed, 121 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ssh/include/readconf.h	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/include/readconf.h	Mon Apr 02 05:33:26 2007 -0700
@@ -23,7 +23,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -89,6 +89,8 @@
 	int     port;		/* Port to connect. */
 	int     connection_attempts;	/* Max attempts (seconds) before
 					 * giving up */
+	int     connection_timeout;	/* Max time (seconds) before
+					 * aborting connection attempt */
 	int     number_of_password_prompts;	/* Max number of password
 						 * prompts. */
 	int     cipher;		/* Cipher to use. */
--- a/usr/src/cmd/ssh/include/xmalloc.h	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/include/xmalloc.h	Mon Apr 02 05:33:26 2007 -0700
@@ -27,6 +27,7 @@
  */
 
 void	*xmalloc(size_t);
+void	*xcalloc(size_t, size_t);
 void	*xrealloc(void *, size_t);
 void     xfree(void *);
 char	*xstrdup(const char *);
--- a/usr/src/cmd/ssh/libssh/common/misc.c	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/libssh/common/misc.c	Mon Apr 02 05:33:26 2007 -0700
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -119,7 +119,15 @@
 /* Characters considered whitespace in strsep calls. */
 #define WHITESPACE " \t\r\n"
 
-/* return next token in configuration line */
+/*
+ * Function returns a pointer to the 1st token on the line. Such a token can
+ * be an empty string in the case of '*s' equal to " value". It changes the
+ * first whitespace token or '=' character after the 1st token to '\0'. Upon
+ * return it changes '*s' to point to the first character of the next token.
+ * That token may be an empty string if the 1st token was followed only by
+ * whitespace or it could be a NULL pointer if the line contained one token
+ * only.
+ */
 char *
 strdelim(char **s)
 {
--- a/usr/src/cmd/ssh/libssh/common/readconf.c	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/libssh/common/readconf.c	Mon Apr 02 05:33:26 2007 -0700
@@ -11,7 +11,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -126,7 +126,7 @@
 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-	oFallBackToRsh, oUseRsh,
+	oFallBackToRsh, oUseRsh, oConnectTimeout,
 	oDeprecated
 } OpCodes;
 
@@ -212,6 +212,7 @@
 	{ "smartcarddevice", oSmartcardDevice },
 	{ "clearallforwardings", oClearAllForwardings },
 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+	{ "connecttimeout", oConnectTimeout },
 	{ NULL, oBadOption }
 };
 
@@ -319,6 +320,20 @@
 		/* don't panic, but count bad options */
 		return -1;
 		/* NOTREACHED */
+	case oConnectTimeout:
+		intptr = &options->connection_timeout;
+parse_time:
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: missing time value.",
+			    filename, linenum);
+		if ((value = convtime(arg)) == -1)
+			fatal("%s line %d: invalid time value.",
+			    filename, linenum);
+		if (*intptr == -1)
+			*intptr = value;
+		break;
+
 	case oForwardAgent:
 		intptr = &options->forward_agent;
 parse_flag:
@@ -833,6 +848,7 @@
 	options->compression_level = -1;
 	options->port = -1;
 	options->connection_attempts = -1;
+	options->connection_timeout = -1;
 	options->number_of_password_prompts = -1;
 	options->cipher = -1;
 	options->ciphers = NULL;
--- a/usr/src/cmd/ssh/libssh/common/xmalloc.c	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/libssh/common/xmalloc.c	Mon Apr 02 05:33:26 2007 -0700
@@ -34,6 +34,22 @@
 }
 
 void *
+xcalloc(size_t nmemb, size_t size)
+{
+	void *ptr;
+
+	if (size == 0 || nmemb == 0)
+		fatal("xcalloc: zero size");
+	if (SIZE_T_MAX / nmemb < size)
+		fatal("xcalloc: nmemb * size > SIZE_T_MAX");
+	ptr = calloc(nmemb, size);
+	if (ptr == NULL)
+		fatal("xcalloc: out of memory (allocating %lu bytes)",
+		    (u_long)(size * nmemb));
+	return ptr;
+}
+
+void *
 xrealloc(void *ptr, size_t new_size)
 {
 	void *new_ptr;
--- a/usr/src/cmd/ssh/ssh/sshconnect.c	Mon Apr 02 02:03:22 2007 -0700
+++ b/usr/src/cmd/ssh/ssh/sshconnect.c	Mon Apr 02 05:33:26 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -227,6 +227,76 @@
 }
 
 /*
+ * Connect with timeout. Implements ConnectTimeout option.
+ */
+static int
+timeout_connect(int sockfd, const struct sockaddr *serv_addr,
+    socklen_t addrlen, int timeout)
+{
+	fd_set *fdset;
+	struct timeval tv;
+	socklen_t optlen;
+	int optval, rc, result = -1;
+
+	if (timeout <= 0)
+		return (connect(sockfd, serv_addr, addrlen));
+
+	set_nonblock(sockfd);
+	rc = connect(sockfd, serv_addr, addrlen);
+	if (rc == 0) {
+		unset_nonblock(sockfd);
+		return (0);
+	}
+	if (errno != EINPROGRESS)
+		return (-1);
+
+	fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
+	    sizeof(fd_mask));
+	FD_SET(sockfd, fdset);
+	tv.tv_sec = timeout;
+	tv.tv_usec = 0;
+
+	for (;;) {
+		rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
+		if (rc != -1 || errno != EINTR)
+			break;
+	}
+
+	switch (rc) {
+	case 0:
+		/* Timed out */
+		errno = ETIMEDOUT;
+		break;
+	case -1:
+		/* Select error */
+		debug("select: %s", strerror(errno));
+		break;
+	case 1:
+		/* Completed or failed */
+		optval = 0;
+		optlen = sizeof(optval);
+		if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
+		    &optlen) == -1) {
+			debug("getsockopt: %s", strerror(errno));
+			break;
+		}
+		if (optval != 0) {
+			errno = optval;
+			break;
+		}
+		result = 0;
+		unset_nonblock(sockfd);
+		break;
+	default:
+		/* Should not occur */
+		fatal("Bogus return (%d) from select()", rc);
+	}
+
+	xfree(fdset);
+	return (result);
+}
+
+/*
  * Opens a TCP/IP connection to the remote server on the given host.
  * The address of the remote host will be returned in hostaddr.
  * If port is 0, the default port will be used.  If needpriv is true,
@@ -314,7 +384,8 @@
 				/* Any error is already output */
 				continue;
 
-			if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
+			if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
+			    options.connection_timeout) >= 0) {
 				/* Successful connection. */
 				memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
 				break;