summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2003-09-01 00:51:03 +0000
committerColin Watson <cjwatson@debian.org>2003-09-01 00:51:03 +0000
commit79cf0b3654d7b597de323153eb57015cdfbd90a4 (patch)
tree274e78bc3369e218e59aa1fcc9b7e90697f424f1 /sshconnect.c
parentd984a3c6658e950881edcfb2aae464add93f68d4 (diff)
Debian release 3.4p1-1.
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/sshconnect.c b/sshconnect.c
index b89321fb8..8eb5fda7d 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -46,6 +46,8 @@ extern uid_t original_effective_uid;
46#define INET6_ADDRSTRLEN 46 46#define INET6_ADDRSTRLEN 46
47#endif 47#endif
48 48
49static sig_atomic_t banner_timedout;
50
49static const char * 51static const char *
50sockaddr_ntop(struct sockaddr *sa, socklen_t salen) 52sockaddr_ntop(struct sockaddr *sa, socklen_t salen)
51{ 53{
@@ -57,6 +59,11 @@ sockaddr_ntop(struct sockaddr *sa, socklen_t salen)
57 return addrbuf; 59 return addrbuf;
58} 60}
59 61
62static void banner_alarm_catch (int signum)
63{
64 banner_timedout = 1;
65}
66
60/* 67/*
61 * Connect to the given ssh server using a proxy command. 68 * Connect to the given ssh server using a proxy command.
62 */ 69 */
@@ -152,7 +159,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
152 buffer_free(&command); 159 buffer_free(&command);
153 160
154 /* Set the connection file descriptors. */ 161 /* Set the connection file descriptors. */
155 packet_set_connection(pout[0], pin[1]); 162 packet_set_connection(pout[0], pin[1], options.setuptimeout);
156 163
157 /* Indicate OK return */ 164 /* Indicate OK return */
158 return 0; 165 return 0;
@@ -353,7 +360,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
353 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 360 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
354 361
355 /* Set the connection. */ 362 /* Set the connection. */
356 packet_set_connection(sock, sock); 363 packet_set_connection(sock, sock, options.setuptimeout);
357 364
358 return 0; 365 return 0;
359} 366}
@@ -370,24 +377,41 @@ ssh_exchange_identification(void)
370 int connection_in = packet_get_connection_in(); 377 int connection_in = packet_get_connection_in();
371 int connection_out = packet_get_connection_out(); 378 int connection_out = packet_get_connection_out();
372 int minor1 = PROTOCOL_MINOR_1; 379 int minor1 = PROTOCOL_MINOR_1;
380 struct sigaction sa, osa;
373 381
374 /* Read other side\'s version identification. */ 382 /* Read other side's version identification.
383 * If SetupTimeOut has been set, give up after
384 * the specified amount of time
385 */
386 if(options.setuptimeout > 0){
387 memset(&sa, 0, sizeof(sa));
388 sa.sa_handler = banner_alarm_catch;
389 /*throw away any pending alarms, since we'd block otherwise*/
390 alarm(0);
391 sigaction(SIGALRM, &sa, &osa);
392 alarm(options.setuptimeout);
393 }
375 for (;;) { 394 for (;;) {
376 for (i = 0; i < sizeof(buf) - 1; i++) { 395 for (i = 0; i < sizeof(buf) - 1; ) {
377 int len = atomicio(read, connection_in, &buf[i], 1); 396 int len = read(connection_in, &buf[i], 1);
378 if (len < 0) 397 if (banner_timedout)
398 fatal("ssh_exchange_identification: Timeout waiting for version information.");
399 if (len < 0) {
400 if (errno == EINTR)
401 continue;
379 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 402 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
403 }
380 if (len != 1) 404 if (len != 1)
381 fatal("ssh_exchange_identification: Connection closed by remote host"); 405 fatal("ssh_exchange_identification: Connection closed by remote host");
382 if (buf[i] == '\r') {
383 buf[i] = '\n';
384 buf[i + 1] = 0;
385 continue; /**XXX wait for \n */
386 }
387 if (buf[i] == '\n') { 406 if (buf[i] == '\n') {
388 buf[i + 1] = 0; 407 buf[i + 1] = 0;
389 break; 408 break;
390 } 409 }
410 if (buf[i] == '\r') {
411 buf[i] = '\n';
412 buf[i + 1] = 0; /**XXX wait for \n */
413 }
414 i++;
391 } 415 }
392 buf[sizeof(buf) - 1] = 0; 416 buf[sizeof(buf) - 1] = 0;
393 if (strncmp(buf, "SSH-", 4) == 0) 417 if (strncmp(buf, "SSH-", 4) == 0)
@@ -396,6 +420,14 @@ ssh_exchange_identification(void)
396 } 420 }
397 server_version_string = xstrdup(buf); 421 server_version_string = xstrdup(buf);
398 422
423 /* If SetupTimeOut has been set, unset the alarm now, and
424 * put the correct handler for SIGALRM back.
425 */
426 if (options.setuptimeout > 0) {
427 alarm(0);
428 sigaction(SIGALRM,&osa,NULL);
429 }
430
399 /* 431 /*
400 * Check that the versions match. In future this might accept 432 * Check that the versions match. In future this might accept
401 * several versions and set appropriate flags to handle them. 433 * several versions and set appropriate flags to handle them.