[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.69 and 1.70

version 1.69, 2000/04/19 07:05:50 version 1.70, 2000/04/26 20:56:30
Line 5 
Line 5 
  * Created: Sat Mar 18 22:15:47 1995 ylo   * 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.
  *  
  * SSH2 support added by Markus Friedl.  
  */   */
   
 #include "includes.h"  #include "includes.h"
Line 38 
Line 36 
 #include "key.h"  #include "key.h"
 #include "dsa.h"  #include "dsa.h"
 #include "hostfile.h"  #include "hostfile.h"
   #include "authfile.h"
   
 /* Session id for the current session. */  /* Session id for the current session. */
 unsigned char session_id[16];  unsigned char session_id[16];
   unsigned int supported_authentications = 0;
   
 /* authentications supported by server */  unsigned char *session_id2 = NULL;
 unsigned int supported_authentications;  int session_id2_len = 0;
   
 static char *client_version_string = NULL;  char *client_version_string = NULL;
 static char *server_version_string = NULL;  char *server_version_string = NULL;
   
 extern Options options;  extern Options options;
 extern char *__progname;  extern char *__progname;
Line 316 
Line 316 
         return 1;          return 1;
 }  }
   
   
 /*  /*
  * Checks if the user has an authentication agent, and if so, tries to   * Checks if the user has an authentication agent, and if so, tries to
  * authenticate using the agent.   * authenticate using the agent.
Line 467 
Line 468 
 try_rsa_authentication(const char *authfile)  try_rsa_authentication(const char *authfile)
 {  {
         BIGNUM *challenge;          BIGNUM *challenge;
         RSA *private_key;          Key *public;
         RSA *public_key;          Key *private;
         char *passphrase, *comment;          char *passphrase, *comment;
         int type, i;          int type, i;
         int plen, clen;          int plen, clen;
   
         /* Try to load identification for the authentication key. */          /* Try to load identification for the authentication key. */
         public_key = RSA_new();          public = key_new(KEY_RSA);
         if (!load_public_key(authfile, public_key, &comment)) {          if (!load_public_key(authfile, public, &comment)) {
                 RSA_free(public_key);                  key_free(public);
                 /* Could not load it.  Fail. */                  /* Could not load it.  Fail. */
                 return 0;                  return 0;
         }          }
Line 484 
Line 485 
   
         /* Tell the server that we are willing to authenticate using this key. */          /* Tell the server that we are willing to authenticate using this key. */
         packet_start(SSH_CMSG_AUTH_RSA);          packet_start(SSH_CMSG_AUTH_RSA);
         packet_put_bignum(public_key->n);          packet_put_bignum(public->rsa->n);
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   
         /* We no longer need the public key. */          /* We no longer need the public key. */
         RSA_free(public_key);          key_free(public);
   
         /* Wait for server's response. */          /* Wait for server's response. */
         type = packet_read(&plen);          type = packet_read(&plen);
Line 515 
Line 516 
   
         debug("Received RSA challenge from server.");          debug("Received RSA challenge from server.");
   
         private_key = RSA_new();          private = key_new(KEY_RSA);
         /*          /*
          * Load the private key.  Try first with empty passphrase; if it           * Load the private key.  Try first with empty passphrase; if it
          * fails, ask for a passphrase.           * fails, ask for a passphrase.
          */           */
         if (!load_private_key(authfile, "", private_key, NULL)) {          if (!load_private_key(authfile, "", private, NULL)) {
                 char buf[300];                  char buf[300];
                 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",                  snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
                     comment);                      comment);
Line 533 
Line 534 
                 }                  }
   
                 /* Load the authentication file using the pasphrase. */                  /* Load the authentication file using the pasphrase. */
                 if (!load_private_key(authfile, passphrase, private_key, NULL)) {                  if (!load_private_key(authfile, passphrase, private, NULL)) {
                         memset(passphrase, 0, strlen(passphrase));                          memset(passphrase, 0, strlen(passphrase));
                         xfree(passphrase);                          xfree(passphrase);
                         error("Bad passphrase.");                          error("Bad passphrase.");
Line 558 
Line 559 
         xfree(comment);          xfree(comment);
   
         /* Compute and send a response to the challenge. */          /* Compute and send a response to the challenge. */
         respond_to_rsa_challenge(challenge, private_key);          respond_to_rsa_challenge(challenge, private->rsa);
   
         /* Destroy the private key. */          /* Destroy the private key. */
         RSA_free(private_key);          key_free(private);
   
         /* We no longer need the challenge. */          /* We no longer need the challenge. */
         BN_clear_free(challenge);          BN_clear_free(challenge);
Line 963 
Line 964 
         return 0;          return 0;
 }  }
   
   
 char *  char *
 chop(char *s)  chop(char *s)
 {  {
Line 1060 
Line 1062 
                 fatal("Protocol major versions differ: %d vs. %d",                  fatal("Protocol major versions differ: %d vs. %d",
                     (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,                      (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
                     remote_major);                      remote_major);
           if (compat20)
                   packet_set_ssh2_format();
         /* 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,
Line 1122 
Line 1125 
  */   */
   
 void  void
 check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)  check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
           const char *user_hostfile, const char *system_hostfile)
 {  {
         Key *file_key;          Key *file_key;
         char *ip = NULL;          char *ip = NULL;
Line 1140 
Line 1144 
          * essentially disables host authentication for localhost; however,           * essentially disables host authentication for localhost; however,
          * this is probably not a real problem.           * this is probably not a real problem.
          */           */
           /**  hostaddr == 0! */
         switch (hostaddr->sa_family) {          switch (hostaddr->sa_family) {
         case AF_INET:          case AF_INET:
                 local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;                  local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
Line 1180 
Line 1185 
          * 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_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key);          host_status = check_host_in_hostfile(user_hostfile, host, host_key, file_key);
         if (host_status == HOST_NEW)          if (host_status == HOST_NEW)
                 host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key);                  host_status = check_host_in_hostfile(system_hostfile, host, host_key, file_key);
         /*          /*
          * 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 && !local && strcmp(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(options.user_hostfile, ip, host_key, ip_key);                  ip_status = check_host_in_hostfile(user_hostfile, ip, host_key, ip_key);
   
                 if (ip_status == HOST_NEW)                  if (ip_status == HOST_NEW)
                         ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key);                          ip_status = check_host_in_hostfile(system_hostfile, ip, host_key, ip_key);
                 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 1209 
Line 1214 
                 debug("Host '%.200s' is known and matches the host key.", host);                  debug("Host '%.200s' is known and matches the host key.", host);
                 if (options.check_host_ip) {                  if (options.check_host_ip) {
                         if (ip_status == HOST_NEW) {                          if (ip_status == HOST_NEW) {
                                 if (!add_host_to_hostfile(options.user_hostfile, ip, host_key))                                  if (!add_host_to_hostfile(user_hostfile, ip, host_key))
                                         log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",                                          log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
                                             ip, options.user_hostfile);                                              ip, user_hostfile);
                                 else                                  else
                                         log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",                                          log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",
                                             ip);                                              ip);
Line 1245 
Line 1250 
                         hostp = host;                          hostp = host;
   
                 /* If not in strict mode, add the key automatically to the local known_hosts file. */                  /* If not in strict mode, add the key automatically to the local known_hosts file. */
                 if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key))                  if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
                         log("Failed to add the host to the list of known hosts (%.500s).",                          log("Failed to add the host to the list of known hosts (%.500s).",
                             options.user_hostfile);                              user_hostfile);
                 else                  else
                         log("Warning: Permanently added '%.200s' to the list of known hosts.",                          log("Warning: Permanently added '%.200s' to the list of known hosts.",
                             hostp);                              hostp);
Line 1279 
Line 1284 
                 error("It is also possible that the host key has just been changed.");                  error("It is also possible that the host key has just been changed.");
                 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.",
                       options.user_hostfile);                        user_hostfile);
   
                 /*                  /*
                  * 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 1313 
Line 1318 
         if (options.check_host_ip)          if (options.check_host_ip)
                 xfree(ip);                  xfree(ip);
 }  }
 void  
 check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)  
 {  
         Key k;  
         k.type = KEY_RSA;  
         k.rsa = host_key;  
         check_host_key(host, hostaddr, &k);  
 }  
   
 /*  /*
  * SSH2 key exchange   * SSH2 key exchange
  */   */
   
 void  void
 ssh_kex2(char *host, struct sockaddr *hostaddr)  ssh_kex2(char *host, struct sockaddr *hostaddr)
 {  {
Line 1435 
Line 1433 
   
         /* key, cert */          /* key, cert */
         server_host_key_blob = packet_get_string(&sbloblen);          server_host_key_blob = packet_get_string(&sbloblen);
         server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen);          server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
         if (server_host_key == NULL)          if (server_host_key == NULL)
                 fatal("cannot decode server_host_key_blob");                  fatal("cannot decode server_host_key_blob");
   
         check_host_key(host, hostaddr, server_host_key);          check_host_key(host, hostaddr, server_host_key,
               options.user_hostfile2, options.system_hostfile2);
   
         /* DH paramter f, server public DH key */          /* DH paramter f, server public DH key */
         dh_server_pub = BN_new();          dh_server_pub = BN_new();
Line 1498 
Line 1497 
                 fprintf(stderr, "%02x", (hash[i])&0xff);                  fprintf(stderr, "%02x", (hash[i])&0xff);
         fprintf(stderr, "\n");          fprintf(stderr, "\n");
 #endif  #endif
         dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);          if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
                   fatal("dsa_verify failed for server_host_key");
         key_free(server_host_key);          key_free(server_host_key);
   
         kex_derive_keys(kex, hash, shared_secret);          kex_derive_keys(kex, hash, shared_secret);
Line 1507 
Line 1507 
         /* have keys, free DH */          /* have keys, free DH */
         DH_free(dh);          DH_free(dh);
   
           /* save session id */
           session_id2_len = 20;
           session_id2 = xmalloc(session_id2_len);
           memcpy(session_id2, hash, session_id2_len);
   
         debug("Wait SSH2_MSG_NEWKEYS.");          debug("Wait SSH2_MSG_NEWKEYS.");
         packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);          packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
         packet_done();          packet_done();
Line 1530 
Line 1535 
 /*  /*
  * Authenticate user   * Authenticate user
  */   */
   int
   ssh2_try_passwd(const char *server_user, const char *host, const char *service)
   {
           char prompt[80];
           char *password;
   
           snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
               server_user, host);
           password = read_passphrase(prompt, 0);
           packet_start(SSH2_MSG_USERAUTH_REQUEST);
           packet_put_cstring(server_user);
           packet_put_cstring(service);
           packet_put_cstring("password");
           packet_put_char(0);
           packet_put_cstring(password);
           memset(password, 0, strlen(password));
           xfree(password);
           packet_send();
           packet_write_wait();
           return 1;
   }
   
   int
   ssh2_try_pubkey(char *filename,
       const char *server_user, const char *host, const char *service)
   {
           Buffer b;
           Key *k;
           unsigned char *blob, *signature;
           int bloblen, slen;
   
           debug("try pubkey: %s", filename);
   
           k = key_new(KEY_DSA);
           if (!load_private_key(filename, "", k, NULL)) {
                   int success = 0;
                   char *passphrase;
                   char prompt[300];
                   snprintf(prompt, sizeof prompt,
                        "Enter passphrase for DSA key '%.100s': ",
                        filename);
                   passphrase = read_passphrase(prompt, 0);
                   success = load_private_key(filename, passphrase, k, NULL);
                   memset(passphrase, 0, strlen(passphrase));
                   xfree(passphrase);
                   if (!success)
                           return 0;
           }
           dsa_make_key_blob(k, &blob, &bloblen);
   
           /* data to be signed */
           buffer_init(&b);
           buffer_append(&b, session_id2, session_id2_len);
           buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
           buffer_put_cstring(&b, server_user);
           buffer_put_cstring(&b, service);
           buffer_put_cstring(&b, "publickey");
           buffer_put_char(&b, 1);
           buffer_put_cstring(&b, KEX_DSS);
           buffer_put_string(&b, blob, bloblen);
   
           /* generate signature */
           dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
           key_free(k);
   #ifdef DEBUG_DSS
           buffer_dump(&b);
   #endif
           /* append signature */
           buffer_put_string(&b, signature, slen);
           xfree(signature);
   
           /* skip session id and packet type */
           if (buffer_len(&b) < session_id2_len + 1)
                   fatal("ssh2_try_pubkey: internal error");
           buffer_consume(&b, session_id2_len + 1);
   
           /* put remaining data from buffer into packet */
           packet_start(SSH2_MSG_USERAUTH_REQUEST);
           packet_put_raw(buffer_ptr(&b), buffer_len(&b));
           buffer_free(&b);
   
           /* send */
           packet_send();
           packet_write_wait();
           return 1;
   }
   
 void  void
 ssh_userauth2(int host_key_valid, RSA *own_host_key,  ssh_userauth2(const char *server_user, char *host)
     uid_t original_real_uid, char *host)  
 {  {
         int type;          int type;
         int plen;          int plen;
           int sent;
         unsigned int dlen;          unsigned int dlen;
         int partial;          int partial;
         struct passwd *pw;          int i = 0;
         char prompt[80];  
         char *server_user, *local_user;  
         char *auths;          char *auths;
         char *password;  
         char *service = "ssh-connection";               /* service name */          char *service = "ssh-connection";               /* service name */
   
         debug("send SSH2_MSG_SERVICE_REQUEST");          debug("send SSH2_MSG_SERVICE_REQUEST");
Line 1566 
Line 1655 
         packet_done();          packet_done();
         debug("got SSH2_MSG_SERVICE_ACCEPT");          debug("got SSH2_MSG_SERVICE_ACCEPT");
   
         /*XX COMMONCODE: */  
         /* Get local user name.  Use it as server user if no user name was given. */  
         pw = getpwuid(original_real_uid);  
         if (!pw)  
                 fatal("User id %d not found from user database.", original_real_uid);  
         local_user = xstrdup(pw->pw_name);  
         server_user = options.user ? options.user : local_user;  
   
         /* INITIAL request for auth */          /* INITIAL request for auth */
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          packet_start(SSH2_MSG_USERAUTH_REQUEST);
         packet_put_cstring(server_user);          packet_put_cstring(server_user);
Line 1583 
Line 1664 
         packet_write_wait();          packet_write_wait();
   
         for (;;) {          for (;;) {
                   sent = 0;
                 type = packet_read(&plen);                  type = packet_read(&plen);
                 if (type == SSH2_MSG_USERAUTH_SUCCESS)                  if (type == SSH2_MSG_USERAUTH_SUCCESS)
                         break;                          break;
Line 1595 
Line 1677 
                 packet_done();                  packet_done();
                 if (partial)                  if (partial)
                         debug("partial success");                          debug("partial success");
                 if (strstr(auths, "password") == NULL)                  if (strstr(auths, "publickey") != NULL) {
                         fatal("passwd auth not supported: %s", auths);                          while (i < options.num_identity_files2) {
                                   sent = ssh2_try_pubkey(
                                       options.identity_files2[i++],
                                       server_user, host, service);
                                   if (sent)
                                           break;
                           }
                   }
                   if (!sent) {
                           if (strstr(auths, "password") != NULL) {
                                   sent = ssh2_try_passwd(server_user, host, service);
                           } else {
                                   fatal("passwd auth not supported: %s", auths);
                           }
                           if (!sent)
                                   fatal("no more auths: %s", auths);
                   }
                 xfree(auths);                  xfree(auths);
                 /* try passwd */  
                 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",  
                     server_user, host);  
                 password = read_passphrase(prompt, 0);  
                 packet_start(SSH2_MSG_USERAUTH_REQUEST);  
                 packet_put_cstring(server_user);  
                 packet_put_cstring(service);  
                 packet_put_cstring("password");  
                 packet_put_char(0);  
                 packet_put_cstring(password);  
                 memset(password, 0, strlen(password));  
                 xfree(password);  
                 packet_send();  
                 packet_write_wait();  
         }          }
         packet_done();          packet_done();
         debug("ssh-userauth2 successfull");          debug("ssh-userauth2 successfull");
Line 1627 
Line 1711 
         BIGNUM *key;          BIGNUM *key;
         RSA *host_key;          RSA *host_key;
         RSA *public_key;          RSA *public_key;
           Key k;
         int bits, rbits;          int bits, rbits;
         int ssh_cipher_default = SSH_CIPHER_3DES;          int ssh_cipher_default = SSH_CIPHER_3DES;
         unsigned char session_key[SSH_SESSION_KEY_LENGTH];          unsigned char session_key[SSH_SESSION_KEY_LENGTH];
Line 1691 
Line 1776 
         packet_integrity_check(payload_len,          packet_integrity_check(payload_len,
                                8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,                                 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
                                SSH_SMSG_PUBLIC_KEY);                                 SSH_SMSG_PUBLIC_KEY);
           k.type = KEY_RSA;
           k.rsa = host_key;
           check_host_key(host, hostaddr, &k,
               options.user_hostfile, options.system_hostfile);
   
         check_rsa_host_key(host, hostaddr, host_key);  
   
         client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;          client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
   
         compute_session_id(session_id, cookie, host_key->n, public_key->n);          compute_session_id(session_id, cookie, host_key->n, public_key->n);
Line 1819 
Line 1906 
  * Authenticate user   * Authenticate user
  */   */
 void  void
 ssh_userauth(int host_key_valid, RSA *own_host_key,  ssh_userauth(
     uid_t original_real_uid, char *host)      const char* local_user,
       const char* server_user,
       char *host,
       int host_key_valid, RSA *own_host_key)
 {  {
         int i, type;          int i, type;
         int payload_len;          int payload_len;
         struct passwd *pw;  
         const char *server_user, *local_user;  
   
         /* Get local user name.  Use it as server user if no user name was given. */          if (supported_authentications == 0)
         pw = getpwuid(original_real_uid);                  fatal("ssh_userauth: server supports no auth methods");
         if (!pw)  
                 fatal("User id %d not found from user database.", original_real_uid);  
         local_user = xstrdup(pw->pw_name);  
         server_user = options.user ? options.user : local_user;  
   
         /* Send the name of the user to log in as on the server. */          /* Send the name of the user to log in as on the server. */
         packet_start(SSH_CMSG_USER);          packet_start(SSH_CMSG_USER);
Line 1951 
Line 2035 
         fatal("Permission denied.");          fatal("Permission denied.");
         /* NOTREACHED */          /* NOTREACHED */
 }  }
   
 /*  /*
  * Starts a dialog with the server, and authenticates the current user on the   * Starts a dialog with the server, and authenticates the current user on the
  * server.  This does not need any extra privileges.  The basic connection   * server.  This does not need any extra privileges.  The basic connection
Line 1962 
Line 2047 
 ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,  ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
     struct sockaddr *hostaddr, uid_t original_real_uid)      struct sockaddr *hostaddr, uid_t original_real_uid)
 {  {
           struct passwd *pw;
         char *host, *cp;          char *host, *cp;
           char *server_user, *local_user;
   
           /* Get local user name.  Use it as server user if no user name was given. */
           pw = getpwuid(original_real_uid);
           if (!pw)
                   fatal("User id %d not found from user database.", original_real_uid);
           local_user = xstrdup(pw->pw_name);
           server_user = options.user ? options.user : local_user;
   
         /* Convert the user-supplied hostname into all lowercase. */          /* Convert the user-supplied hostname into all lowercase. */
         host = xstrdup(orighost);          host = xstrdup(orighost);
         for (cp = host; *cp; cp++)          for (cp = host; *cp; cp++)
Line 1980 
Line 2074 
         /* authenticate user */          /* authenticate user */
         if (compat20) {          if (compat20) {
                 ssh_kex2(host, hostaddr);                  ssh_kex2(host, hostaddr);
                 ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host);                  ssh_userauth2(server_user, host);
         } else {          } else {
                 supported_authentications = 0;  
                 ssh_kex(host, hostaddr);                  ssh_kex(host, hostaddr);
                 if (supported_authentications == 0)                  ssh_userauth(local_user, server_user, host, host_key_valid, own_host_key);
                         fatal("supported_authentications == 0.");  
                 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);  
         }          }
 }  }

Legend:
Removed from v.1.69  
changed lines
  Added in v.1.70