diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | readconf.c | 20 | ||||
-rw-r--r-- | readconf.h | 4 | ||||
-rw-r--r-- | ssh_config | 3 | ||||
-rw-r--r-- | ssh_config.5 | 7 | ||||
-rw-r--r-- | sshconnect.c | 70 |
6 files changed, 102 insertions, 8 deletions
@@ -10,6 +10,10 @@ | |||
10 | - markus@cvs.openbsd.org 2003/05/15 14:09:21 | 10 | - markus@cvs.openbsd.org 2003/05/15 14:09:21 |
11 | [auth2-krb5.c] | 11 | [auth2-krb5.c] |
12 | fix 64bit issue; report itojun@ | 12 | fix 64bit issue; report itojun@ |
13 | - djm@cvs.openbsd.org 2003/05/15 14:55:25 | ||
14 | [readconf.c readconf.h ssh_config ssh_config.5 sshconnect.c] | ||
15 | add a ConnectTimeout option to ssh, based on patch from | ||
16 | Jean-Charles Longuet (jclonguet at free.fr); portable #207 ok markus@ | ||
13 | 17 | ||
14 | 20030515 | 18 | 20030515 |
15 | - (djm) OpenBSD CVS Sync | 19 | - (djm) OpenBSD CVS Sync |
@@ -1541,4 +1545,4 @@ | |||
1541 | save auth method before monitor_reset_key_state(); bugzilla bug #284; | 1545 | save auth method before monitor_reset_key_state(); bugzilla bug #284; |
1542 | ok provos@ | 1546 | ok provos@ |
1543 | 1547 | ||
1544 | $Id: ChangeLog,v 1.2726 2003/05/16 01:38:46 djm Exp $ | 1548 | $Id: ChangeLog,v 1.2727 2003/05/16 01:39:04 djm Exp $ |
diff --git a/readconf.c b/readconf.c index fee7a8993..a0cf3d687 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: readconf.c,v 1.110 2003/05/15 14:02:47 jakob Exp $"); | 15 | RCSID("$OpenBSD: readconf.c,v 1.111 2003/05/15 14:55:25 djm Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "xmalloc.h" | 18 | #include "xmalloc.h" |
@@ -106,7 +106,7 @@ typedef enum { | |||
106 | oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, | 106 | oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, |
107 | oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, | 107 | oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, |
108 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, | 108 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, |
109 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, | 109 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
110 | oDeprecated, oUnsupported | 110 | oDeprecated, oUnsupported |
111 | } OpCodes; | 111 | } OpCodes; |
112 | 112 | ||
@@ -193,6 +193,7 @@ static struct { | |||
193 | #endif | 193 | #endif |
194 | { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, | 194 | { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, |
195 | { "rekeylimit", oRekeyLimit }, | 195 | { "rekeylimit", oRekeyLimit }, |
196 | { "connecttimeout", oConnectTimeout }, | ||
196 | { NULL, oBadOption } | 197 | { NULL, oBadOption } |
197 | }; | 198 | }; |
198 | 199 | ||
@@ -309,6 +310,20 @@ process_config_line(Options *options, const char *host, | |||
309 | /* don't panic, but count bad options */ | 310 | /* don't panic, but count bad options */ |
310 | return -1; | 311 | return -1; |
311 | /* NOTREACHED */ | 312 | /* NOTREACHED */ |
313 | case oConnectTimeout: | ||
314 | intptr = &options->connection_timeout; | ||
315 | /* parse_time: */ | ||
316 | arg = strdelim(&s); | ||
317 | if (!arg || *arg == '\0') | ||
318 | fatal("%s line %d: missing time value.", | ||
319 | filename, linenum); | ||
320 | if ((value = convtime(arg)) == -1) | ||
321 | fatal("%s line %d: invalid time value.", | ||
322 | filename, linenum); | ||
323 | if (*intptr == -1) | ||
324 | *intptr = value; | ||
325 | break; | ||
326 | |||
312 | case oForwardAgent: | 327 | case oForwardAgent: |
313 | intptr = &options->forward_agent; | 328 | intptr = &options->forward_agent; |
314 | parse_flag: | 329 | parse_flag: |
@@ -808,6 +823,7 @@ initialize_options(Options * options) | |||
808 | options->compression_level = -1; | 823 | options->compression_level = -1; |
809 | options->port = -1; | 824 | options->port = -1; |
810 | options->connection_attempts = -1; | 825 | options->connection_attempts = -1; |
826 | options->connection_timeout = -1; | ||
811 | options->number_of_password_prompts = -1; | 827 | options->number_of_password_prompts = -1; |
812 | options->cipher = -1; | 828 | options->cipher = -1; |
813 | options->ciphers = NULL; | 829 | options->ciphers = NULL; |
diff --git a/readconf.h b/readconf.h index 991e20091..c884de68b 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.49 2003/05/15 01:48:10 jakob Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.50 2003/05/15 14:55:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -60,6 +60,8 @@ typedef struct { | |||
60 | int port; /* Port to connect. */ | 60 | int port; /* Port to connect. */ |
61 | int connection_attempts; /* Max attempts (seconds) before | 61 | int connection_attempts; /* Max attempts (seconds) before |
62 | * giving up */ | 62 | * giving up */ |
63 | int connection_timeout; /* Max time (seconds) before | ||
64 | * aborting connection attempt */ | ||
63 | int number_of_password_prompts; /* Max number of password | 65 | int number_of_password_prompts; /* Max number of password |
64 | * prompts. */ | 66 | * prompts. */ |
65 | int cipher; /* Cipher to use. */ | 67 | int cipher; /* Cipher to use. */ |
diff --git a/ssh_config b/ssh_config index 94cffbf39..8a0acc17f 100644 --- a/ssh_config +++ b/ssh_config | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: ssh_config,v 1.16 2002/07/03 14:21:05 markus Exp $ | 1 | # $OpenBSD: ssh_config,v 1.17 2003/05/15 14:55:25 djm Exp $ |
2 | 2 | ||
3 | # This is the ssh client system-wide configuration file. See | 3 | # This is the ssh client system-wide configuration file. See |
4 | # ssh_config(5) for more information. This file provides defaults for | 4 | # ssh_config(5) for more information. This file provides defaults for |
@@ -25,6 +25,7 @@ | |||
25 | # HostbasedAuthentication no | 25 | # HostbasedAuthentication no |
26 | # BatchMode no | 26 | # BatchMode no |
27 | # CheckHostIP yes | 27 | # CheckHostIP yes |
28 | # ConnectTimeout 0 | ||
28 | # StrictHostKeyChecking ask | 29 | # StrictHostKeyChecking ask |
29 | # IdentityFile ~/.ssh/identity | 30 | # IdentityFile ~/.ssh/identity |
30 | # IdentityFile ~/.ssh/id_rsa | 31 | # IdentityFile ~/.ssh/id_rsa |
diff --git a/ssh_config.5 b/ssh_config.5 index 2f33aa3f3..c5de4a9de 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -34,7 +34,7 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: ssh_config.5,v 1.8 2003/05/14 18:16:20 jakob Exp $ | 37 | .\" $OpenBSD: ssh_config.5,v 1.9 2003/05/15 14:55:25 djm Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH_CONFIG 5 | 39 | .Dt SSH_CONFIG 5 |
40 | .Os | 40 | .Os |
@@ -227,6 +227,11 @@ Specifies the number of tries (one per second) to make before exiting. | |||
227 | The argument must be an integer. | 227 | The argument must be an integer. |
228 | This may be useful in scripts if the connection sometimes fails. | 228 | This may be useful in scripts if the connection sometimes fails. |
229 | The default is 1. | 229 | The default is 1. |
230 | .It Cm ConnectTimeout | ||
231 | Specifies the timeout (in seconds) used when connecting to the ssh | ||
232 | server, instead of using the default system TCP timeout. This value is | ||
233 | used only when the target is down or really unreachable, not when it | ||
234 | refuses the connection. | ||
230 | .It Cm DynamicForward | 235 | .It Cm DynamicForward |
231 | Specifies that a TCP/IP port on the local machine be forwarded | 236 | Specifies that a TCP/IP port on the local machine be forwarded |
232 | over the secure channel, and the application | 237 | over the secure channel, and the application |
diff --git a/sshconnect.c b/sshconnect.c index 32bef7d07..8aac221d3 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.140 2003/05/14 18:16:21 jakob Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.141 2003/05/15 14:55:25 djm Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -218,6 +218,71 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
218 | return sock; | 218 | return sock; |
219 | } | 219 | } |
220 | 220 | ||
221 | static int | ||
222 | timeout_connect(int sockfd, const struct sockaddr *serv_addr, | ||
223 | socklen_t addrlen, int timeout) | ||
224 | { | ||
225 | fd_set *fdset; | ||
226 | struct timeval tv; | ||
227 | socklen_t optlen; | ||
228 | int fdsetsz, optval, rc; | ||
229 | |||
230 | if (timeout <= 0) | ||
231 | return (connect(sockfd, serv_addr, addrlen)); | ||
232 | |||
233 | if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) | ||
234 | return (-1); | ||
235 | |||
236 | rc = connect(sockfd, serv_addr, addrlen); | ||
237 | if (rc == 0) | ||
238 | return (0); | ||
239 | if (errno != EINPROGRESS) | ||
240 | return (-1); | ||
241 | |||
242 | fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask); | ||
243 | fdset = (fd_set *)xmalloc(fdsetsz); | ||
244 | |||
245 | memset(fdset, '\0', fdsetsz); | ||
246 | FD_SET(sockfd, fdset); | ||
247 | tv.tv_sec = timeout; | ||
248 | tv.tv_usec = 0; | ||
249 | |||
250 | for(;;) { | ||
251 | rc = select(sockfd + 1, NULL, fdset, NULL, &tv); | ||
252 | if (rc != -1 || errno != EINTR) | ||
253 | break; | ||
254 | } | ||
255 | |||
256 | switch(rc) { | ||
257 | case 0: | ||
258 | /* Timed out */ | ||
259 | errno = ETIMEDOUT; | ||
260 | return (-1); | ||
261 | case -1: | ||
262 | /* Select error */ | ||
263 | debug("select: %s", strerror(errno)); | ||
264 | return (-1); | ||
265 | case 1: | ||
266 | /* Completed or failed */ | ||
267 | optval = 0; | ||
268 | optlen = sizeof(optval); | ||
269 | if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, | ||
270 | &optlen) == -1) | ||
271 | debug("getsockopt: %s", strerror(errno)); | ||
272 | return (-1); | ||
273 | if (optval != 0) { | ||
274 | errno = optval; | ||
275 | return (-1); | ||
276 | } | ||
277 | break; | ||
278 | default: | ||
279 | /* Should not occur */ | ||
280 | fatal("Bogus return (%d) from select()", rc); | ||
281 | } | ||
282 | |||
283 | return (0); | ||
284 | } | ||
285 | |||
221 | /* | 286 | /* |
222 | * Opens a TCP/IP connection to the remote server on the given host. | 287 | * Opens a TCP/IP connection to the remote server on the given host. |
223 | * The address of the remote host will be returned in hostaddr. | 288 | * The address of the remote host will be returned in hostaddr. |
@@ -306,7 +371,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
306 | /* Any error is already output */ | 371 | /* Any error is already output */ |
307 | continue; | 372 | continue; |
308 | 373 | ||
309 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { | 374 | if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, |
375 | options.connection_timeout) >= 0) { | ||
310 | /* Successful connection. */ | 376 | /* Successful connection. */ |
311 | memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); | 377 | memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
312 | break; | 378 | break; |