PSARC 2007/034 ssh/sshd resync with OpenSSH
6480090 ConnectTimeout functionality desired for SUNWssh
--- 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;