[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.72.2.5 and 1.73

version 1.72.2.5, 2001/03/21 18:53:14 version 1.73, 2000/05/17 08:20:15
Line 2 
Line 2 
  * 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
  *                    All rights reserved   *                    All rights reserved
    * Created: Sat Mar 18 22:15:47 1995 ylo
  * Code to connect to a remote host, and to perform the client side of the   * Code to connect to a remote host, and to perform the client side of the
  * login (authentication) dialog.   * login (authentication) dialog.
  *  
  * As far as I am concerned, the code I have written for this software  
  * can be used freely for any purpose.  Any derived versions of this  
  * software must be clearly marked as such, and if the derived work is  
  * incompatible with the protocol description in the RFC file, it must be  
  * called by a name other than "ssh" or "Secure Shell".  
  */   */
   
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <openssl/bn.h>  #include <openssl/bn.h>
   #include <openssl/dsa.h>
   #include <openssl/rsa.h>
   
 #include "ssh.h"  
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "rsa.h"  #include "rsa.h"
   #include "ssh.h"
 #include "buffer.h"  #include "buffer.h"
 #include "packet.h"  #include "packet.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "compat.h"  #include "compat.h"
   #include "readconf.h"
 #include "key.h"  #include "key.h"
 #include "sshconnect.h"  #include "sshconnect.h"
 #include "hostfile.h"  #include "hostfile.h"
 #include "log.h"  
 #include "readconf.h"  
 #include "atomicio.h"  
 #include "misc.h"  
   
 char *client_version_string = NULL;  char *client_version_string = NULL;
 char *server_version_string = NULL;  char *server_version_string = NULL;
Line 38 
Line 32 
 extern Options options;  extern Options options;
 extern char *__progname;  extern char *__progname;
   
 /* AF_UNSPEC or AF_INET or AF_INET6 */  
 extern int IPv4or6;  
   
 /*  /*
  * Connect to the given ssh server using a proxy command.   * Connect to the given ssh server using a proxy command.
  */   */
Line 113 
Line 104 
   
                 /* Stderr is left as it is so that error messages get                  /* Stderr is left as it is so that error messages get
                    printed on the user's terminal. */                     printed on the user's terminal. */
                 argv[0] = _PATH_BSHELL;                  argv[0] = "/bin/sh";
                 argv[1] = "-c";                  argv[1] = "-c";
                 argv[2] = command_string;                  argv[2] = command_string;
                 argv[3] = NULL;                  argv[3] = NULL;
   
                 /* Execute the proxy command.  Note that we gave up any                  /* Execute the proxy command.  Note that we gave up any
                    extra privileges above. */                     extra privileges above. */
                 execv(argv[0], argv);                  execv("/bin/sh", argv);
                 perror(argv[0]);                  perror("/bin/sh");
                 exit(1);                  exit(1);
         }          }
         /* Parent. */          /* Parent. */
Line 191 
Line 182 
             int anonymous, uid_t original_real_uid,              int anonymous, uid_t original_real_uid,
             const char *proxy_command)              const char *proxy_command)
 {  {
         int gaierr;  
         int on = 1;  
         int sock = -1, attempt;          int sock = -1, attempt;
         char ntop[NI_MAXHOST], strport[NI_MAXSERV];          struct servent *sp;
         struct addrinfo hints, *ai, *aitop;          struct addrinfo hints, *ai, *aitop;
           char ntop[NI_MAXHOST], strport[NI_MAXSERV];
           int gaierr;
         struct linger linger;          struct linger linger;
         struct servent *sp;  
   
         debug("ssh_connect: getuid %u geteuid %u anon %d",          debug("ssh_connect: getuid %d geteuid %d anon %d",
               (u_int) getuid(), (u_int) geteuid(), anonymous);                (int) getuid(), (int) geteuid(), anonymous);
   
         /* Get default port if port has not been set. */          /* Get default port if port has not been set. */
         if (port == 0) {          if (port == 0) {
Line 249 
Line 239 
   
                         /* Create a socket for connecting. */                          /* Create a socket for connecting. */
                         sock = ssh_create_socket(original_real_uid,                          sock = ssh_create_socket(original_real_uid,
                             !anonymous && geteuid() == 0,                              !anonymous && geteuid() == 0 && port < IPPORT_RESERVED,
                             ai->ai_family);                              ai->ai_family);
                         if (sock < 0)                          if (sock < 0)
                                 continue;                                  continue;
Line 261 
Line 251 
                         temporarily_use_uid(original_real_uid);                          temporarily_use_uid(original_real_uid);
                         if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {                          if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
                                 /* Successful connection. */                                  /* Successful connection. */
                                 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);                                  memcpy(hostaddr, ai->ai_addr, sizeof(*hostaddr));
                                 restore_uid();                                  restore_uid();
                                 break;                                  break;
                         } else {                          } else {
Line 299 
Line 289 
         /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */          /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
         linger.l_onoff = 1;          linger.l_onoff = 1;
         linger.l_linger = 5;          linger.l_linger = 5;
         setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));          setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
   
         /* Set keepalives if requested. */  
         if (options.keepalives &&  
             setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,  
             sizeof(on)) < 0)  
                 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));  
   
         /* Set the connection. */          /* Set the connection. */
         packet_set_connection(sock, sock);          packet_set_connection(sock, sock);
   
Line 318 
Line 302 
  * identification string.   * identification string.
  */   */
 void  void
 ssh_exchange_identification(void)  ssh_exchange_identification()
 {  {
         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, i, mismatch;          int remote_major, remote_minor, i, mismatch;
         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;  
   
         /* Read other side\'s version identification. */          /* Read other side\'s version identification. */
         for (;;) {          for (i = 0; i < sizeof(buf) - 1; i++) {
                 for (i = 0; i < sizeof(buf) - 1; i++) {                  int len = read(connection_in, &buf[i], 1);
                         int len = atomicio(read, connection_in, &buf[i], 1);                  if (len < 0)
                         if (len < 0)                          fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
                                 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));                  if (len != 1)
                         if (len != 1)                          fatal("ssh_exchange_identification: Connection closed by remote host");
                                 fatal("ssh_exchange_identification: Connection closed by remote host");                  if (buf[i] == '\r') {
                         if (buf[i] == '\r') {                          buf[i] = '\n';
                                 buf[i] = '\n';                          buf[i + 1] = 0;
                                 buf[i + 1] = 0;                          continue;               /**XXX wait for \n */
                                 continue;               /**XXX wait for \n */  
                         }  
                         if (buf[i] == '\n') {  
                                 buf[i + 1] = 0;  
                                 break;  
                         }  
                 }                  }
                 buf[sizeof(buf) - 1] = 0;                  if (buf[i] == '\n') {
                 if (strncmp(buf, "SSH-", 4) == 0)                          buf[i + 1] = 0;
                         break;                          break;
                 debug("ssh_exchange_identification: %s", buf);                  }
         }          }
           buf[sizeof(buf) - 1] = 0;
         server_version_string = xstrdup(buf);          server_version_string = xstrdup(buf);
   
         /*          /*
Line 378 
Line 356 
                 }                  }
                 if (remote_minor < 3) {                  if (remote_minor < 3) {
                         fatal("Remote machine has too old SSH software version.");                          fatal("Remote machine has too old SSH software version.");
                 } else if (remote_minor == 3 || remote_minor == 4) {                  } else if (remote_minor == 3) {
                         /* We speak 1.3, too. */                          /* We speak 1.3, too. */
                         enable_compat13();                          enable_compat13();
                         minor1 = 3;  
                         if (options.forward_agent) {                          if (options.forward_agent) {
                                 log("Agent forwarding disabled for protocol 1.3");                                  log("Agent forwarding disabled for protocol 1.3");
                                 options.forward_agent = 0;                                  options.forward_agent = 0;
Line 407 
Line 384 
         /* Send our own protocol version identification. */          /* Send our own protocol version identification. */
         snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",          snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
             compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,              compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
             compat20 ? PROTOCOL_MINOR_2 : minor1,              compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1,
             SSH_VERSION);              SSH_VERSION);
         if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))          if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
                 fatal("write: %.100s", strerror(errno));                  fatal("write: %.100s", strerror(errno));
Line 417 
Line 394 
         debug("Local version string %.100s", client_version_string);          debug("Local version string %.100s", client_version_string);
 }  }
   
 /* defaults to 'no' */  
 int  int
 read_yes_or_no(const char *prompt, int defval)  read_yes_or_no(const char *prompt, int defval)
 {  {
Line 425 
Line 401 
         FILE *f;          FILE *f;
         int retval = -1;          int retval = -1;
   
         if (options.batch_mode)          if (isatty(0))
                 return 0;  
   
         if (isatty(STDIN_FILENO))  
                 f = stdin;                  f = stdin;
         else          else
                 f = fopen(_PATH_TTY, "rw");                  f = fopen("/dev/tty", "rw");
   
         if (f == NULL)          if (f == NULL)
                 return 0;                  return 0;
Line 453 
Line 426 
                         retval = defval;                          retval = defval;
                 if (strcmp(buf, "yes") == 0)                  if (strcmp(buf, "yes") == 0)
                         retval = 1;                          retval = 1;
                 else if (strcmp(buf, "no") == 0)                  if (strcmp(buf, "no") == 0)
                         retval = 0;                          retval = 0;
                 else  
                         fprintf(stderr, "Please type 'yes' or 'no'.\n");  
   
                 if (retval != -1) {                  if (retval != -1) {
                         if (f != stdin)                          if (f != stdin)
Line 477 
Line 448 
         Key *file_key;          Key *file_key;
         char *type = key_type(host_key);          char *type = key_type(host_key);
         char *ip = NULL;          char *ip = NULL;
         char hostline[1000], *hostp, *fp;          char hostline[1000], *hostp;
         HostStatus host_status;          HostStatus host_status;
         HostStatus ip_status;          HostStatus ip_status;
         int local = 0, host_ip_differ = 0;          int local = 0, host_ip_differ = 0;
         char ntop[NI_MAXHOST];          char ntop[NI_MAXHOST];
         int host_line, ip_line;  
         const char *host_file = NULL, *ip_file = NULL;  
   
         /*          /*
          * Force accepting of the host key for loopback/localhost. The           * Force accepting of the host key for loopback/localhost. The
Line 505 
Line 474 
                 local = 0;                  local = 0;
                 break;                  break;
         }          }
         if (local && options.host_key_alias == NULL) {          if (local) {
                 debug("Forcing accepting of host key for "                  debug("Forcing accepting of host key for loopback/localhost.");
                     "loopback/localhost.");  
                 return;                  return;
         }          }
   
         /*          /*
          * We don't have the remote ip-address for connections           * Turn off check_host_ip for proxy connects, since
          * using a proxy command           * we don't have the remote ip-address
          */           */
         if (options.proxy_command == NULL) {          if (options.proxy_command != NULL && options.check_host_ip)
                   options.check_host_ip = 0;
   
           if (options.check_host_ip) {
                 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 = xstrdup(ntop);
         } else {  
                 ip = xstrdup("<no hostip for proxy command>");  
         }          }
         /*  
          * 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  
          */  
         if (options.check_host_ip &&  
             (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))  
                 options.check_host_ip = 0;  
   
         /*          /*
          * Allow the user to record the key under a different name. This is  
          * useful for ssh tunneling over forwarded connections or if you run  
          * multiple sshd's on different ports on the same machine.  
          */  
         if (options.host_key_alias != NULL) {  
                 host = options.host_key_alias;  
                 debug("using hostkeyalias: %s", host);  
         }  
   
         /*  
          * Store the host key from the known host file in here so that we can           * Store the host key from the known host file in here so that we can
          * compare it with the key for the IP address.           * compare it with the key for the IP address.
          */           */
Line 551 
Line 503 
          * Check if the host key is present in the user\'s list of known           * Check if the host key is present in the user\'s list of known
          * hosts or in the systemwide list.           * hosts or in the systemwide list.
          */           */
         host_file = user_hostfile;          host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key);
         host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);          if (host_status == HOST_NEW)
         if (host_status == HOST_NEW) {                  host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key);
                 host_file = system_hostfile;  
                 host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);  
         }  
         /*          /*
          * Also perform check for the ip address, skip the check if we are           * Also perform check for the ip address, skip the check if we are
          * localhost or the hostname was an ip address to begin with           * localhost or the hostname was an ip address to begin with
          */           */
         if (options.check_host_ip) {          if (options.check_host_ip && !local && strcmp(host, ip)) {
                 Key *ip_key = key_new(host_key->type);                  Key *ip_key = key_new(host_key->type);
                   ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key);
   
                 ip_file = user_hostfile;                  if (ip_status == HOST_NEW)
                 ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);                          ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key);
                 if (ip_status == HOST_NEW) {  
                         ip_file = system_hostfile;  
                         ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);  
                 }  
                 if (host_status == HOST_CHANGED &&                  if (host_status == HOST_CHANGED &&
                     (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))                      (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
                         host_ip_differ = 1;                          host_ip_differ = 1;
Line 585 
Line 531 
                 /* The host is known and the key matches. */                  /* The host is known and the key matches. */
                 debug("Host '%.200s' is known and matches the %s host key.",                  debug("Host '%.200s' is known and matches the %s host key.",
                     host, type);                      host, type);
                 debug("Found key in %s:%d", host_file, host_line);                  if (options.check_host_ip) {
                 if (options.check_host_ip && ip_status == HOST_NEW) {                          if (ip_status == HOST_NEW) {
                         if (!add_host_to_hostfile(user_hostfile, ip, host_key))                                  if (!add_host_to_hostfile(user_hostfile, ip, host_key))
                                 log("Failed to add the %s host key for IP address '%.128s' to the list of known hosts (%.30s).",                                          log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
                                     type, ip, user_hostfile);                                              type, ip, user_hostfile);
                         else                                  else
                                 log("Warning: Permanently added the %s host key for IP address '%.128s' to the list of known hosts.",                                          log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
                                     type, ip);                                              type, ip);
                           } else if (ip_status != HOST_OK)
                                   log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'",
                                       type, host, ip);
                 }                  }
                 break;                  break;
         case HOST_NEW:          case HOST_NEW:
Line 604 
Line 553 
                 } else if (options.strict_host_key_checking == 2) {                  } else if (options.strict_host_key_checking == 2) {
                         /* The default */                          /* The default */
                         char prompt[1024];                          char prompt[1024];
                         fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);                          char *fp = key_fingerprint(host_key);
                         snprintf(prompt, sizeof(prompt),                          snprintf(prompt, sizeof(prompt),
                             "The authenticity of host '%.200s (%s)' can't be established.\n"                              "The authenticity of host '%.200s' can't be established.\n"
                             "%s key fingerprint is %s.\n"                              "%s key fingerprint is %s.\n"
                             "Are you sure you want to continue connecting (yes/no)? ",                              "Are you sure you want to continue connecting (yes/no)? ",
                             host, ip, type, fp);                              host, type, fp);
                         xfree(fp);  
                         if (!read_yes_or_no(prompt, -1))                          if (!read_yes_or_no(prompt, -1))
                                 fatal("Aborted by user!");                                  fatal("Aborted by user!\n");
                 }                  }
                 if (options.check_host_ip && ip_status == HOST_NEW) {                  if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) {
                         snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);                          snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
                         hostp = hostline;                          hostp = hostline;
                 } else                  } else
Line 644 
Line 592 
                         error("and the key for the according IP address %s", ip);                          error("and the key for the according IP address %s", ip);
                         error("%s. This could either mean that", msg);                          error("%s. This could either mean that", msg);
                         error("DNS SPOOFING is happening or the IP address for the host");                          error("DNS SPOOFING is happening or the IP address for the host");
                         error("and its host key have changed at the same time.");                          error("and its host key have changed at the same time");
                         if (ip_status != HOST_NEW)  
                                 error("Offending key for IP in %s:%d", ip_file, ip_line);  
                 }                  }
                 /* The host key has changed. */                  /* The host key has changed. */
                 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);  
                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");                  error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                 error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");                  error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");                  error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");                  error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
                 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");                  error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
                 error("It is also possible that the %s host key has just been changed.", type);                  error("It is also possible that the %s host key has just been changed.", type);
                 error("The fingerprint for the %s key sent by the remote host is\n%s.",  
                     type, fp);  
                 error("Please contact your system administrator.");                  error("Please contact your system administrator.");
                 error("Add correct host key in %.100s to get rid of this message.",                  error("Add correct host key in %.100s to get rid of this message.",
                     user_hostfile);                        user_hostfile);
                 error("Offending key in %s:%d", host_file, host_line);  
                 xfree(fp);  
   
                 /*                  /*
                  * If strict host key checking is in use, the user will have                   * If strict host key checking is in use, the user will have
Line 684 
Line 625 
                         error("Agent forwarding is disabled to avoid trojan horses.");                          error("Agent forwarding is disabled to avoid trojan horses.");
                         options.forward_agent = 0;                          options.forward_agent = 0;
                 }                  }
                 if (options.forward_x11) {  
                         error("X11 forwarding is disabled to avoid trojan horses.");  
                         options.forward_x11 = 0;  
                 }  
                 if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) {  
                         error("Port forwarding is disabled to avoid trojan horses.");  
                         options.num_local_forwards = options.num_remote_forwards = 0;  
                 }  
                 /*                  /*
                  * 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 701 
Line 634 
                  */                   */
                 break;                  break;
         }          }
           if (options.check_host_ip)
         if (options.check_host_ip && host_status != HOST_CHANGED &&                  xfree(ip);
             ip_status == HOST_CHANGED) {  
                 log("Warning: the %s host key for '%.200s' "  
                     "differs from the key for the IP address '%.128s'",  
                     type, host, ip);  
                 if (host_status == HOST_OK)  
                         log("Matching host key in %s:%d", host_file, host_line);  
                 log("Offending key for IP in %s:%d", ip_file, ip_line);  
                 if (options.strict_host_key_checking == 1) {  
                         fatal("Exiting, you have requested strict checking.");  
                 } else if (options.strict_host_key_checking == 2) {  
                         if (!read_yes_or_no("Are you sure you want " \  
                             "to continue connecting (yes/no)? ", -1))  
                                 fatal("Aborted by user!");  
                 }  
         }  
   
         xfree(ip);  
 }  }
   
 /*  /*
Line 740 
Line 656 
         /* Get local user name.  Use it as server user if no user name was given. */          /* Get local user name.  Use it as server user if no user name was given. */
         pw = getpwuid(original_real_uid);          pw = getpwuid(original_real_uid);
         if (!pw)          if (!pw)
                 fatal("User id %u not found from user database.", original_real_uid);                  fatal("User id %d not found from user database.", original_real_uid);
         local_user = xstrdup(pw->pw_name);          local_user = xstrdup(pw->pw_name);
         server_user = options.user ? options.user : local_user;          server_user = options.user ? options.user : local_user;
   
Line 765 
Line 681 
                 ssh_kex(host, hostaddr);                  ssh_kex(host, hostaddr);
                 ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key);                  ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key);
         }          }
 }  
   
 void  
 ssh_put_password(char *password)  
 {  
         int size;  
         char *padded;  
   
         if (datafellows & SSH_BUG_PASSWORDPAD) {  
                 packet_put_string(password, strlen(password));  
                 return;  
         }  
         size = roundup(strlen(password) + 1, 32);  
         padded = xmalloc(size);  
         memset(padded, 0, size);  
         strlcpy(padded, password, size);  
         packet_put_string(padded, size);  
         memset(padded, 0, size);  
         xfree(padded);  
 }  }

Legend:
Removed from v.1.72.2.5  
changed lines
  Added in v.1.73