[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.308 and 1.309

version 1.308, 2018/11/18 22:43:29 version 1.309, 2018/12/27 03:25:25
Line 27 
Line 27 
 #include <fcntl.h>  #include <fcntl.h>
 #include <netdb.h>  #include <netdb.h>
 #include <paths.h>  #include <paths.h>
 #include <poll.h>  
 #include <signal.h>  #include <signal.h>
 #include <pwd.h>  #include <pwd.h>
 #include <stdio.h>  #include <stdio.h>
Line 55 
Line 54 
 #include "authfile.h"  #include "authfile.h"
 #include "ssherr.h"  #include "ssherr.h"
 #include "authfd.h"  #include "authfd.h"
   #include "kex.h"
   
 char *client_version_string = NULL;  
 char *server_version_string = NULL;  
 struct sshkey *previous_host_key = NULL;  struct sshkey *previous_host_key = NULL;
   
 static int matching_host_key_dns = 0;  static int matching_host_key_dns = 0;
Line 422 
Line 420 
 }  }
   
 /*  /*
  * Wait up to *timeoutp milliseconds for fd to be readable. Updates  
  * *timeoutp with time remaining.  
  * Returns 0 if fd ready or -1 on timeout or error (see errno).  
  */  
 static int  
 waitrfd(int fd, int *timeoutp)  
 {  
         struct pollfd pfd;  
         struct timeval t_start;  
         int oerrno, r;  
   
         monotime_tv(&t_start);  
         pfd.fd = fd;  
         pfd.events = POLLIN;  
         for (; *timeoutp >= 0;) {  
                 r = poll(&pfd, 1, *timeoutp);  
                 oerrno = errno;  
                 ms_subtract_diff(&t_start, timeoutp);  
                 errno = oerrno;  
                 if (r > 0)  
                         return 0;  
                 else if (r == -1 && errno != EAGAIN)  
                         return -1;  
                 else if (r == 0)  
                         break;  
         }  
         /* timeout */  
         errno = ETIMEDOUT;  
         return -1;  
 }  
   
 static int  
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,  
     socklen_t addrlen, int *timeoutp)  
 {  
         int optval = 0;  
         socklen_t optlen = sizeof(optval);  
   
         /* No timeout: just do a blocking connect() */  
         if (*timeoutp <= 0)  
                 return connect(sockfd, serv_addr, addrlen);  
   
         set_nonblock(sockfd);  
         if (connect(sockfd, serv_addr, addrlen) == 0) {  
                 /* Succeeded already? */  
                 unset_nonblock(sockfd);  
                 return 0;  
         } else if (errno != EINPROGRESS)  
                 return -1;  
   
         if (waitrfd(sockfd, timeoutp) == -1)  
                 return -1;  
   
         /* Completed or failed */  
         if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {  
                 debug("getsockopt: %s", strerror(errno));  
                 return -1;  
         }  
         if (optval != 0) {  
                 errno = optval;  
                 return -1;  
         }  
         unset_nonblock(sockfd);  
         return 0;  
 }  
   
 /*  
  * Opens a TCP/IP connection to the remote server on the given host.   * Opens a TCP/IP connection to the remote server on the given host.
  * The address of the remote host will be returned in hostaddr.   * The address of the remote host will be returned in hostaddr.
  * If port is 0, the default port will be used.   * If port is 0, the default port will be used.
Line 606 
Line 537 
         return ssh_proxy_connect(ssh, host, port, options.proxy_command);          return ssh_proxy_connect(ssh, host, port, options.proxy_command);
 }  }
   
 static void  
 send_client_banner(int connection_out, int minor1)  
 {  
         /* Send our own protocol version identification. */  
         xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",  
             PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);  
         if (atomicio(vwrite, connection_out, client_version_string,  
             strlen(client_version_string)) != strlen(client_version_string))  
                 fatal("write: %.100s", strerror(errno));  
         chop(client_version_string);  
         debug("Local version string %.100s", client_version_string);  
 }  
   
 /*  
  * Waits for the server identification string, and sends our own  
  * identification string.  
  */  
 void  
 ssh_exchange_identification(int timeout_ms)  
 {  
         char buf[256], remote_version[256];     /* must be same size! */  
         int remote_major, remote_minor, mismatch;  
         int connection_in = packet_get_connection_in();  
         int connection_out = packet_get_connection_out();  
         u_int i, n;  
         size_t len;  
         int rc;  
   
         send_client_banner(connection_out, 0);  
   
         /* Read other side's version identification. */  
         for (n = 0;;) {  
                 for (i = 0; i < sizeof(buf) - 1; i++) {  
                         if (timeout_ms > 0) {  
                                 rc = waitrfd(connection_in, &timeout_ms);  
                                 if (rc == -1 && errno == ETIMEDOUT) {  
                                         fatal("Connection timed out during "  
                                             "banner exchange");  
                                 } else if (rc == -1) {  
                                         fatal("%s: %s",  
                                             __func__, strerror(errno));  
                                 }  
                         }  
   
                         len = atomicio(read, connection_in, &buf[i], 1);  
                         if (len != 1 && errno == EPIPE)  
                                 fatal("ssh_exchange_identification: "  
                                     "Connection closed by remote host");  
                         else if (len != 1)  
                                 fatal("ssh_exchange_identification: "  
                                     "read: %.100s", strerror(errno));  
                         if (buf[i] == '\r') {  
                                 buf[i] = '\n';  
                                 buf[i + 1] = 0;  
                                 continue;               /**XXX wait for \n */  
                         }  
                         if (buf[i] == '\n') {  
                                 buf[i + 1] = 0;  
                                 break;  
                         }  
                         if (++n > 65536)  
                                 fatal("ssh_exchange_identification: "  
                                     "No banner received");  
                 }  
                 buf[sizeof(buf) - 1] = 0;  
                 if (strncmp(buf, "SSH-", 4) == 0)  
                         break;  
                 debug("ssh_exchange_identification: %s", buf);  
         }  
         server_version_string = xstrdup(buf);  
   
         /*  
          * Check that the versions match.  In future this might accept  
          * several versions and set appropriate flags to handle them.  
          */  
         if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",  
             &remote_major, &remote_minor, remote_version) != 3)  
                 fatal("Bad remote protocol version identification: '%.100s'", buf);  
         debug("Remote protocol version %d.%d, remote software version %.100s",  
             remote_major, remote_minor, remote_version);  
   
         active_state->compat = compat_datafellows(remote_version);  
         mismatch = 0;  
   
         switch (remote_major) {  
         case 2:  
                 break;  
         case 1:  
                 if (remote_minor != 99)  
                         mismatch = 1;  
                 break;  
         default:  
                 mismatch = 1;  
                 break;  
         }  
         if (mismatch)  
                 fatal("Protocol major versions differ: %d vs. %d",  
                     PROTOCOL_MAJOR_2, remote_major);  
         if ((datafellows & SSH_BUG_RSASIGMD5) != 0)  
                 logit("Server version \"%.100s\" uses unsafe RSA signature "  
                     "scheme; disabling use of RSA keys", remote_version);  
         chop(server_version_string);  
 }  
   
 /* defaults to 'no' */  /* defaults to 'no' */
 static int  static int
 confirm(const char *prompt)  confirm(const char *prompt)
Line 1387 
Line 1214 
  * This function does not require super-user privileges.   * This function does not require super-user privileges.
  */   */
 void  void
 ssh_login(Sensitive *sensitive, const char *orighost,  ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
     struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)      struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)
 {  {
         char *host;          char *host;
Line 1401 
Line 1228 
         lowercase(host);          lowercase(host);
   
         /* Exchange protocol version identification strings with the server. */          /* Exchange protocol version identification strings with the server. */
         ssh_exchange_identification(timeout_ms);          if (kex_exchange_identification(ssh, timeout_ms, NULL) != 0)
                   cleanup_exit(255); /* error already logged */
   
         /* Put the connection into non-blocking mode. */          /* Put the connection into non-blocking mode. */
         packet_set_nonblocking();          ssh_packet_set_nonblocking(ssh);
   
         /* key exchange */          /* key exchange */
         /* authenticate user */          /* authenticate user */
         debug("Authenticating to %s:%d as '%s'", host, port, server_user);          debug("Authenticating to %s:%d as '%s'", host, port, server_user);
         ssh_kex2(host, hostaddr, port);          ssh_kex2(ssh, host, hostaddr, port);
         ssh_userauth2(local_user, server_user, host, sensitive);          ssh_userauth2(ssh, local_user, server_user, host, sensitive);
         free(local_user);          free(local_user);
 }  }
   

Legend:
Removed from v.1.308  
changed lines
  Added in v.1.309