[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.176 and 1.176.2.2

version 1.176, 2006/02/22 00:04:45 version 1.176.2.2, 2006/11/08 00:17:14
Line 1 
Line 1 
   /* $OpenBSD$ */
 /*  /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>   * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Line 12 
Line 13 
  * called by a name other than "ssh" or "Secure Shell".   * called by a name other than "ssh" or "Secure Shell".
  */   */
   
 #include "includes.h"  
 RCSID("$OpenBSD$");  
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/wait.h>  #include <sys/wait.h>
 #include <sys/stat.h>  #include <sys/stat.h>
   #include <sys/socket.h>
   #include <sys/time.h>
   
   #include <netinet/in.h>
   
 #include <ctype.h>  #include <ctype.h>
   #include <errno.h>
   #include <netdb.h>
 #include <paths.h>  #include <paths.h>
   #include <signal.h>
   #include <pwd.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>
   
 #include "ssh.h"  
 #include "xmalloc.h"  #include "xmalloc.h"
   #include "ssh.h"
 #include "rsa.h"  #include "rsa.h"
 #include "buffer.h"  #include "buffer.h"
 #include "packet.h"  #include "packet.h"
Line 37 
Line 47 
 #include "atomicio.h"  #include "atomicio.h"
 #include "misc.h"  #include "misc.h"
 #include "dns.h"  #include "dns.h"
   #include "version.h"
   
 char *client_version_string = NULL;  char *client_version_string = NULL;
 char *server_version_string = NULL;  char *server_version_string = NULL;
Line 63 
Line 74 
         int pin[2], pout[2];          int pin[2], pout[2];
         pid_t pid;          pid_t pid;
         char strport[NI_MAXSERV];          char strport[NI_MAXSERV];
         size_t len;  
   
         /* Convert the port number into a string. */          /* Convert the port number into a string. */
         snprintf(strport, sizeof strport, "%hu", port);          snprintf(strport, sizeof strport, "%hu", port);
Line 75 
Line 85 
          * Use "exec" to avoid "sh -c" processes on some platforms           * Use "exec" to avoid "sh -c" processes on some platforms
          * (e.g. Solaris)           * (e.g. Solaris)
          */           */
         len = strlen(proxy_command) + 6;          xasprintf(&tmp, "exec %s", proxy_command);
         tmp = xmalloc(len);  
         strlcpy(tmp, "exec ", len);  
         strlcat(tmp, proxy_command, len);  
         command_string = percent_expand(tmp, "h", host,          command_string = percent_expand(tmp, "h", host,
             "p", strport, (char *)NULL);              "p", strport, (char *)NULL);
         xfree(tmp);          xfree(tmp);
Line 95 
Line 102 
                 char *argv[10];                  char *argv[10];
   
                 /* Child.  Permanently give up superuser privileges. */                  /* Child.  Permanently give up superuser privileges. */
                 seteuid(original_real_uid);                  permanently_drop_suid(original_real_uid);
                 setuid(original_real_uid);  
   
                 /* Redirect stdin and stdout. */                  /* Redirect stdin and stdout. */
                 close(pin[1]);                  close(pin[1]);
Line 206 
Line 212 
         fd_set *fdset;          fd_set *fdset;
         struct timeval tv;          struct timeval tv;
         socklen_t optlen;          socklen_t optlen;
         int fdsetsz, optval, rc, result = -1;          int optval, rc, result = -1;
   
         if (timeout <= 0)          if (timeout <= 0)
                 return (connect(sockfd, serv_addr, addrlen));                  return (connect(sockfd, serv_addr, addrlen));
Line 220 
Line 226 
         if (errno != EINPROGRESS)          if (errno != EINPROGRESS)
                 return (-1);                  return (-1);
   
         fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask);          fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
         fdset = (fd_set *)xmalloc(fdsetsz);              sizeof(fd_mask));
   
         memset(fdset, 0, fdsetsz);  
         FD_SET(sockfd, fdset);          FD_SET(sockfd, fdset);
         tv.tv_sec = timeout;          tv.tv_sec = timeout;
         tv.tv_usec = 0;          tv.tv_usec = 0;
Line 306 
Line 310 
                 fatal("%s: %.100s: %s", __progname, host,                  fatal("%s: %.100s: %s", __progname, host,
                     gai_strerror(gaierr));                      gai_strerror(gaierr));
   
         /*          for (attempt = 0; attempt < connection_attempts; attempt++) {
          * Try to connect several times.  On some machines, the first time                  if (attempt > 0) {
          * will sometimes fail.  In general socket code appears to behave                          /* Sleep a moment before retrying. */
          * quite magically on many machines.                          sleep(1);
                  */  
         for (attempt = 0; ;) {  
                 if (attempt > 0)  
                         debug("Trying again...");                          debug("Trying again...");
                   }
                 /* Loop through addresses for this host, and try each one in                  /*
                    sequence until the connection succeeds. */                   * Loop through addresses for this host, and try each one in
                    * sequence until the connection succeeds.
                    */
                 for (ai = aitop; ai; ai = ai->ai_next) {                  for (ai = aitop; ai; ai = ai->ai_next) {
                         if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)                          if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
                                 continue;                                  continue;
Line 343 
Line 346 
                         } else {                          } else {
                                 debug("connect to address %s port %s: %s",                                  debug("connect to address %s port %s: %s",
                                     ntop, strport, strerror(errno));                                      ntop, strport, strerror(errno));
                                 /*  
                                  * Close the failed socket; there appear to  
                                  * be some problems when reusing a socket for  
                                  * which connect() has already returned an  
                                  * error.  
                                  */  
                                 close(sock);                                  close(sock);
                                   sock = -1;
                         }                          }
                 }                  }
                 if (ai)                  if (sock != -1)
                         break;  /* Successful connection. */                          break;  /* Successful connection. */
   
                 attempt++;  
                 if (attempt >= connection_attempts)  
                         break;  
                 /* Sleep a moment before retrying. */  
                 sleep(1);  
         }          }
   
         freeaddrinfo(aitop);          freeaddrinfo(aitop);
   
         /* Return failure if we didn't get a successful connection. */          /* Return failure if we didn't get a successful connection. */
         if (attempt >= connection_attempts) {          if (sock == -1) {
                 error("ssh: connect to host %s port %s: %s",                  error("ssh: connect to host %s port %s: %s",
                     host, strport, strerror(errno));                      host, strport, strerror(errno));
                 return (-1);                  return (-1);
Line 397 
Line 389 
         int connection_in = packet_get_connection_in();          int connection_in = packet_get_connection_in();
         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;          u_int i, n;
   
         /* Read other side's version identification. */          /* Read other side's version identification. */
         for (;;) {          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);                          size_t len = atomicio(read, connection_in, &buf[i], 1);
   
Line 417 
Line 409 
                                 buf[i + 1] = 0;                                  buf[i + 1] = 0;
                                 break;                                  break;
                         }                          }
                           if (++n > 65536)
                                   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 518 
Line 512 
  * check whether the supplied host key is valid, return -1 if the key   * check whether the supplied host key is valid, return -1 if the key
  * is not valid. the user_hostfile will not be updated if 'readonly' is true.   * is not valid. the user_hostfile will not be updated if 'readonly' is true.
  */   */
   #define RDRW    0
   #define RDONLY  1
   #define ROQUIET 2
 static int  static int
 check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,  check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
     int readonly, const char *user_hostfile, const char *system_hostfile)      Key *host_key, int readonly, const char *user_hostfile,
       const char *system_hostfile)
 {  {
         Key *file_key;          Key *file_key;
         const char *type = key_type(host_key);          const char *type = key_type(host_key);
         char *ip = NULL;          char *ip = NULL, *host = NULL;
         char hostline[1000], *hostp, *fp;          char hostline[1000], *hostp, *fp;
         HostStatus host_status;          HostStatus host_status;
         HostStatus ip_status;          HostStatus ip_status;
Line 571 
Line 569 
                 if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop),                  if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop),
                     NULL, 0, NI_NUMERICHOST) != 0)                      NULL, 0, NI_NUMERICHOST) != 0)
                         fatal("check_host_key: getnameinfo failed");                          fatal("check_host_key: getnameinfo failed");
                 ip = xstrdup(ntop);                  ip = put_host_port(ntop, port);
         } else {          } else {
                 ip = xstrdup("<no hostip for proxy command>");                  ip = xstrdup("<no hostip for proxy command>");
         }          }
Line 579 
Line 577 
          * Turn off check_host_ip if the connection is to localhost, via proxy           * Turn off check_host_ip if the connection is to localhost, via proxy
          * command or if we don't have a hostname to compare with           * command or if we don't have a hostname to compare with
          */           */
         if (options.check_host_ip &&          if (options.check_host_ip && (local ||
             (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))              strcmp(hostname, ip) == 0 || options.proxy_command != NULL))
                 options.check_host_ip = 0;                  options.check_host_ip = 0;
   
         /*          /*
          * Allow the user to record the key under a different name. This is           * Allow the user to record the key under a different name or
          * useful for ssh tunneling over forwarded connections or if you run           * differentiate a non-standard port.  This is useful for ssh
          * multiple sshd's on different ports on the same machine.           * tunneling over forwarded connections or if you run multiple
            * sshd's on different ports on the same machine.
          */           */
         if (options.host_key_alias != NULL) {          if (options.host_key_alias != NULL) {
                 host = options.host_key_alias;                  host = xstrdup(options.host_key_alias);
                 debug("using hostkeyalias: %s", host);                  debug("using hostkeyalias: %s", host);
           } else {
                   host = put_host_port(hostname, port);
         }          }
   
         /*          /*
Line 659 
Line 660 
                 }                  }
                 break;                  break;
         case HOST_NEW:          case HOST_NEW:
                   if (options.host_key_alias == NULL && port != 0 &&
                       port != SSH_DEFAULT_PORT) {
                           debug("checking without port identifier");
                           if (check_host_key(hostname, hostaddr, 0, host_key, 2,
                               user_hostfile, system_hostfile) == 0) {
                                   debug("found matching key w/out port");
                                   break;
                           }
                   }
                 if (readonly)                  if (readonly)
                         goto fail;                          goto fail;
                 /* The host is new. */                  /* The host is new. */
Line 738 
Line 748 
                             "list of known hosts.", hostp, type);                              "list of known hosts.", hostp, type);
                 break;                  break;
         case HOST_CHANGED:          case HOST_CHANGED:
                   if (readonly == ROQUIET)
                           goto fail;
                 if (options.check_host_ip && host_ip_differ) {                  if (options.check_host_ip && host_ip_differ) {
                         char *key_msg;                          char *key_msg;
                         if (ip_status == HOST_NEW)                          if (ip_status == HOST_NEW)
Line 776 
Line 788 
                 /*                  /*
                  * If strict host key checking has not been requested, allow                   * If strict host key checking has not been requested, allow
                  * the connection but without MITM-able authentication or                   * the connection but without MITM-able authentication or
                  * agent forwarding.                   * forwarding.
                  */                   */
                 if (options.password_authentication) {                  if (options.password_authentication) {
                         error("Password authentication is disabled to avoid "                          error("Password authentication is disabled to avoid "
Line 811 
Line 823 
                         options.num_local_forwards =                          options.num_local_forwards =
                             options.num_remote_forwards = 0;                              options.num_remote_forwards = 0;
                 }                  }
                   if (options.tun_open != SSH_TUNMODE_NO) {
                           error("Tunnel forwarding is disabled to avoid "
                               "man-in-the-middle attacks.");
                           options.tun_open = SSH_TUNMODE_NO;
                   }
                 /*                  /*
                  * XXX Should permit the user to change to use the new id.                   * XXX Should permit the user to change to use the new id.
                  * This could be done by converting the host key to an                   * This could be done by converting the host key to an
Line 852 
Line 869 
         }          }
   
         xfree(ip);          xfree(ip);
           xfree(host);
         return 0;          return 0;
   
 fail:  fail:
         xfree(ip);          xfree(ip);
           xfree(host);
         return -1;          return -1;
 }  }
   
Line 889 
Line 908 
         /* return ok if the key can be found in an old keyfile */          /* return ok if the key can be found in an old keyfile */
         if (stat(options.system_hostfile2, &st) == 0 ||          if (stat(options.system_hostfile2, &st) == 0 ||
             stat(options.user_hostfile2, &st) == 0) {              stat(options.user_hostfile2, &st) == 0) {
                 if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,                  if (check_host_key(host, hostaddr, options.port, host_key,
                     options.user_hostfile2, options.system_hostfile2) == 0)                      RDONLY, options.user_hostfile2,
                       options.system_hostfile2) == 0)
                         return 0;                          return 0;
         }          }
         return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,          return check_host_key(host, hostaddr, options.port, host_key,
             options.user_hostfile, options.system_hostfile);              RDRW, options.user_hostfile, options.system_hostfile);
 }  }
   
 /*  /*
Line 918 
Line 938 
         host = xstrdup(orighost);          host = xstrdup(orighost);
         for (cp = host; *cp; cp++)          for (cp = host; *cp; cp++)
                 if (isupper(*cp))                  if (isupper(*cp))
                         *cp = 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();
Line 935 
Line 955 
                 ssh_kex(host, hostaddr);                  ssh_kex(host, hostaddr);
                 ssh_userauth1(local_user, server_user, host, sensitive);                  ssh_userauth1(local_user, server_user, host, sensitive);
         }          }
           xfree(local_user);
 }  }
   
 void  void
Line 948 
Line 969 
                 return;                  return;
         }          }
         size = roundup(strlen(password) + 1, 32);          size = roundup(strlen(password) + 1, 32);
         padded = xmalloc(size);          padded = xcalloc(1, size);
         memset(padded, 0, size);  
         strlcpy(padded, password, size);          strlcpy(padded, password, size);
         packet_put_string(padded, size);          packet_put_string(padded, size);
         memset(padded, 0, size);          memset(padded, 0, size);

Legend:
Removed from v.1.176  
changed lines
  Added in v.1.176.2.2