diff options
author | jp161948 <none@none> | 2007-04-02 05:33:26 -0700 |
---|---|---|
committer | jp161948 <none@none> | 2007-04-02 05:33:26 -0700 |
commit | 47b374ff8413339e27ddb691c18d22ffe3482515 (patch) | |
tree | 5c4a679e4018638ed40b17ceae5b3478f0ec4f4d /usr/src | |
parent | f763a6cdd6a48d48089e0c8473a138f32345775a (diff) | |
download | illumos-joyent-47b374ff8413339e27ddb691c18d22ffe3482515.tar.gz |
PSARC 2007/034 ssh/sshd resync with OpenSSH
6480090 ConnectTimeout functionality desired for SUNWssh
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ssh/include/readconf.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/ssh/include/xmalloc.h | 1 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/misc.c | 12 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/readconf.c | 20 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/xmalloc.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/ssh/ssh/sshconnect.c | 75 |
6 files changed, 121 insertions, 7 deletions
diff --git a/usr/src/cmd/ssh/include/readconf.h b/usr/src/cmd/ssh/include/readconf.h index e6bdcb5e88..52d2f7100b 100644 --- a/usr/src/cmd/ssh/include/readconf.h +++ b/usr/src/cmd/ssh/include/readconf.h @@ -23,7 +23,7 @@ extern "C" { * 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 @@ typedef struct { 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. */ diff --git a/usr/src/cmd/ssh/include/xmalloc.h b/usr/src/cmd/ssh/include/xmalloc.h index c5aafe6da1..6477737a4e 100644 --- a/usr/src/cmd/ssh/include/xmalloc.h +++ b/usr/src/cmd/ssh/include/xmalloc.h @@ -27,6 +27,7 @@ extern "C" { */ void *xmalloc(size_t); +void *xcalloc(size_t, size_t); void *xrealloc(void *, size_t); void xfree(void *); char *xstrdup(const char *); diff --git a/usr/src/cmd/ssh/libssh/common/misc.c b/usr/src/cmd/ssh/libssh/common/misc.c index 33454826f2..99c0778307 100644 --- a/usr/src/cmd/ssh/libssh/common/misc.c +++ b/usr/src/cmd/ssh/libssh/common/misc.c @@ -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 @@ set_nodelay(int fd) /* 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) { diff --git a/usr/src/cmd/ssh/libssh/common/readconf.c b/usr/src/cmd/ssh/libssh/common/readconf.c index 516cad749e..678632a126 100644 --- a/usr/src/cmd/ssh/libssh/common/readconf.c +++ b/usr/src/cmd/ssh/libssh/common/readconf.c @@ -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 @@ typedef enum { oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, oClearAllForwardings, oNoHostAuthenticationForLocalhost, - oFallBackToRsh, oUseRsh, + oFallBackToRsh, oUseRsh, oConnectTimeout, oDeprecated } OpCodes; @@ -212,6 +212,7 @@ static struct { { "smartcarddevice", oSmartcardDevice }, { "clearallforwardings", oClearAllForwardings }, { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, + { "connecttimeout", oConnectTimeout }, { NULL, oBadOption } }; @@ -319,6 +320,20 @@ process_config_line(Options *options, const char *host, /* 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 @@ initialize_options(Options * options) 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; diff --git a/usr/src/cmd/ssh/libssh/common/xmalloc.c b/usr/src/cmd/ssh/libssh/common/xmalloc.c index ef11fce812..b9ae011d3c 100644 --- a/usr/src/cmd/ssh/libssh/common/xmalloc.c +++ b/usr/src/cmd/ssh/libssh/common/xmalloc.c @@ -34,6 +34,22 @@ xmalloc(size_t size) } 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; diff --git a/usr/src/cmd/ssh/ssh/sshconnect.c b/usr/src/cmd/ssh/ssh/sshconnect.c index a5e138e65b..4a6b1a3b11 100644 --- a/usr/src/cmd/ssh/ssh/sshconnect.c +++ b/usr/src/cmd/ssh/ssh/sshconnect.c @@ -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 @@ ssh_create_socket(int privileged, int family) } /* + * 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 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, /* 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; |