[BACK]Return to sshconnect.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/sshconnect.c between version 1.201 and 1.202

version 1.201, 2007/08/23 03:23:26 version 1.202, 2007/09/04 11:15:55
Line 64 
Line 64 
 static int show_other_keys(const char *, Key *);  static int show_other_keys(const char *, Key *);
 static void warn_changed_key(Key *);  static void warn_changed_key(Key *);
   
   static void
   ms_subtract_diff(struct timeval *start, int *ms)
   {
           struct timeval diff, finish;
   
           gettimeofday(&finish, NULL);
           timersub(&finish, start, &diff);
           *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
   }
   
   static void
   ms_to_timeval(struct timeval *tv, int ms)
   {
           tv->tv_sec = ms / 1000;
           tv->tv_usec = (ms % 1000) * 1000;
   }
   
 /*  /*
  * Connect to the given ssh server using a proxy command.   * Connect to the given ssh server using a proxy command.
  */   */
Line 210 
Line 227 
   
 static int  static int
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,  timeout_connect(int sockfd, const struct sockaddr *serv_addr,
     socklen_t addrlen, int timeout)      socklen_t addrlen, int *timeoutp)
 {  {
         fd_set *fdset;          fd_set *fdset;
         struct timeval tv;          struct timeval tv, t_start;
         socklen_t optlen;          socklen_t optlen;
         int optval, rc, result = -1;          int optval, rc, result = -1;
   
         if (timeout <= 0)          gettimeofday(&t_start, NULL);
                 return (connect(sockfd, serv_addr, addrlen));  
   
           if (*timeoutp <= 0) {
                   result = connect(sockfd, serv_addr, addrlen);
                   goto done;
           }
   
         set_nonblock(sockfd);          set_nonblock(sockfd);
         rc = connect(sockfd, serv_addr, addrlen);          rc = connect(sockfd, serv_addr, addrlen);
         if (rc == 0) {          if (rc == 0) {
                 unset_nonblock(sockfd);                  unset_nonblock(sockfd);
                 return (0);                  result = 0;
                   goto done;
         }          }
         if (errno != EINPROGRESS)          if (errno != EINPROGRESS) {
                 return (-1);                  result = -1;
                   goto done;
           }
   
         fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),          fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
             sizeof(fd_mask));              sizeof(fd_mask));
         FD_SET(sockfd, fdset);          FD_SET(sockfd, fdset);
         tv.tv_sec = timeout;          ms_to_timeval(&tv, *timeoutp);
         tv.tv_usec = 0;  
   
         for (;;) {          for (;;) {
                 rc = select(sockfd + 1, NULL, fdset, NULL, &tv);                  rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
Line 272 
Line 295 
         }          }
   
         xfree(fdset);          xfree(fdset);
   
    done:
           if (result == 0 && *timeoutp > 0) {
                   ms_subtract_diff(&t_start, timeoutp);
                   if (*timeoutp <= 0) {
                           errno = ETIMEDOUT;
                           result = -1;
                   }
           }
   
         return (result);          return (result);
 }  }
   
Line 288 
Line 321 
  */   */
 int  int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,  ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
     u_short port, int family, int connection_attempts,      u_short port, int family, int connection_attempts, int *timeout_ms,
     int needpriv, const char *proxy_command)      int want_keepalive, int needpriv, const char *proxy_command)
 {  {
         int gaierr;          int gaierr;
         int on = 1;          int on = 1;
Line 342 
Line 375 
                                 continue;                                  continue;
   
                         if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,                          if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
                             options.connection_timeout) >= 0) {                              timeout_ms) >= 0) {
                                 /* Successful connection. */                                  /* Successful connection. */
                                 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);                                  memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
                                 break;                                  break;
Line 369 
Line 402 
         debug("Connection established.");          debug("Connection established.");
   
         /* Set SO_KEEPALIVE if requested. */          /* Set SO_KEEPALIVE if requested. */
         if (options.tcp_keep_alive &&          if (want_keepalive &&
             setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,              setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
             sizeof(on)) < 0)              sizeof(on)) < 0)
                 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));                  error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
Line 385 
Line 418 
  * identification string.   * identification string.
  */   */
 static void  static void
 ssh_exchange_identification(void)  ssh_exchange_identification(int timeout_ms)
 {  {
         char buf[256], remote_version[256];     /* must be same size! */          char buf[256], remote_version[256];     /* must be same size! */
         int remote_major, remote_minor, mismatch;          int remote_major, remote_minor, mismatch;
Line 393 
Line 426 
         int connection_out = packet_get_connection_out();          int connection_out = packet_get_connection_out();
         int minor1 = PROTOCOL_MINOR_1;          int minor1 = PROTOCOL_MINOR_1;
         u_int i, n;          u_int i, n;
           size_t len;
           int fdsetsz, remaining, rc;
           struct timeval t_start, t_remaining;
           fd_set *fdset;
   
           fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
           fdset = xcalloc(1, fdsetsz);
   
         /* Read other side's version identification. */          /* Read other side's version identification. */
           remaining = timeout_ms;
         for (n = 0;;) {          for (n = 0;;) {
                 for (i = 0; i < sizeof(buf) - 1; i++) {                  for (i = 0; i < sizeof(buf) - 1; i++) {
                         size_t len = atomicio(read, connection_in, &buf[i], 1);                          if (timeout_ms > 0) {
                                   gettimeofday(&t_start, NULL);
                                   ms_to_timeval(&t_remaining, remaining);
                                   FD_SET(connection_in, fdset);
                                   rc = select(connection_in + 1, fdset, NULL,
                                       fdset, &t_remaining);
                                   ms_subtract_diff(&t_start, &remaining);
                                   if (rc == 0 || remaining <= 0)
                                           fatal("Connection timed out during "
                                               "banner exchange");
                                   if (rc == -1) {
                                           if (errno == EINTR)
                                                   continue;
                                           fatal("ssh_exchange_identification: "
                                               "select: %s", strerror(errno));
                                   }
                           }
   
                           len = atomicio(read, connection_in, &buf[i], 1);
   
                         if (len != 1 && errno == EPIPE)                          if (len != 1 && errno == EPIPE)
                                 fatal("ssh_exchange_identification: Connection closed by remote host");                                  fatal("ssh_exchange_identification: "
                                       "Connection closed by remote host");
                         else if (len != 1)                          else if (len != 1)
                                 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));                                  fatal("ssh_exchange_identification: "
                                       "read: %.100s", strerror(errno));
                         if (buf[i] == '\r') {                          if (buf[i] == '\r') {
                                 buf[i] = '\n';                                  buf[i] = '\n';
                                 buf[i + 1] = 0;                                  buf[i + 1] = 0;
Line 413 
Line 474 
                                 break;                                  break;
                         }                          }
                         if (++n > 65536)                          if (++n > 65536)
                                 fatal("ssh_exchange_identification: No banner received");                                  fatal("ssh_exchange_identification: "
                                       "No banner received");
                 }                  }
                 buf[sizeof(buf) - 1] = 0;                  buf[sizeof(buf) - 1] = 0;
                 if (strncmp(buf, "SSH-", 4) == 0)                  if (strncmp(buf, "SSH-", 4) == 0)
Line 421 
Line 483 
                 debug("ssh_exchange_identification: %s", buf);                  debug("ssh_exchange_identification: %s", buf);
         }          }
         server_version_string = xstrdup(buf);          server_version_string = xstrdup(buf);
           xfree(fdset);
   
         /*          /*
          * Check that the versions match.  In future this might accept           * Check that the versions match.  In future this might accept
Line 929 
Line 992 
  */   */
 void  void
 ssh_login(Sensitive *sensitive, const char *orighost,  ssh_login(Sensitive *sensitive, const char *orighost,
     struct sockaddr *hostaddr, struct passwd *pw)      struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms)
 {  {
         char *host, *cp;          char *host, *cp;
         char *server_user, *local_user;          char *server_user, *local_user;
Line 944 
Line 1007 
                         *cp = (char)tolower(*cp);                          *cp = (char)tolower(*cp);
   
         /* Exchange protocol version identification strings with the server. */          /* Exchange protocol version identification strings with the server. */
         ssh_exchange_identification();          ssh_exchange_identification(timeout_ms);
   
         /* Put the connection into non-blocking mode. */          /* Put the connection into non-blocking mode. */
         packet_set_nonblocking();          packet_set_nonblocking();

Legend:
Removed from v.1.201  
changed lines
  Added in v.1.202