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

Diff for /src/usr.bin/ssh/Attic/sshconnect1.c between version 1.8.2.7 and 1.9

version 1.8.2.7, 2002/03/08 17:04:43 version 1.9, 2000/11/12 19:50:38
Line 16 
Line 16 
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <openssl/bn.h>  #include <openssl/bn.h>
 #include <openssl/md5.h>  #include <openssl/dsa.h>
   #include <openssl/rsa.h>
   #include <openssl/evp.h>
   
 #ifdef KRB4  
 #include <krb.h>  
 #endif  
 #ifdef KRB5  
 #include <krb5.h>  
 #endif  
 #ifdef AFS  
 #include <kafs.h>  
 #include "radix.h"  
 #endif  
   
 #include "ssh.h"  
 #include "ssh1.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 "mpaux.h"  #include "mpaux.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "log.h"  
 #include "readconf.h"  #include "readconf.h"
 #include "key.h"  #include "key.h"
 #include "authfd.h"  #include "authfd.h"
 #include "sshconnect.h"  #include "sshconnect.h"
 #include "authfile.h"  #include "authfile.h"
 #include "readpass.h"  
 #include "cipher.h"  
 #include "canohost.h"  
 #include "auth.h"  
   
 /* Session id for the current session. */  /* Session id for the current session. */
 u_char session_id[16];  unsigned char session_id[16];
 u_int supported_authentications = 0;  unsigned int supported_authentications = 0;
   
 extern Options options;  extern Options options;
 extern char *__progname;  extern char *__progname;
Line 59 
Line 44 
  * 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.
  */   */
 static int  int
 try_agent_authentication(void)  try_agent_authentication()
 {  {
         int type;          int type;
         char *comment;          char *comment;
         AuthenticationConnection *auth;          AuthenticationConnection *auth;
         u_char response[16];          unsigned char response[16];
         u_int i;          unsigned int i;
           int plen, clen;
         Key *key;          Key *key;
         BIGNUM *challenge;          BIGNUM *challenge;
   
Line 75 
Line 61 
         if (!auth)          if (!auth)
                 return 0;                  return 0;
   
         if ((challenge = BN_new()) == NULL)          challenge = BN_new();
                 fatal("try_agent_authentication: BN_new failed");          key = key_new(KEY_RSA1);
   
         /* Loop through identities served by the agent. */          /* Loop through identities served by the agent. */
         for (key = ssh_get_first_identity(auth, &comment, 1);          for (key = ssh_get_first_identity(auth, &comment, 1);
             key != NULL;               key != NULL;
             key = ssh_get_next_identity(auth, &comment, 1)) {               key = ssh_get_next_identity(auth, &comment, 1)) {
   
                 /* Try this identity. */                  /* Try this identity. */
                 debug("Trying RSA authentication via agent with '%.100s'", comment);                  debug("Trying RSA authentication via agent with '%.100s'", comment);
Line 93 
Line 80 
                 packet_write_wait();                  packet_write_wait();
   
                 /* Wait for server's response. */                  /* Wait for server's response. */
                 type = packet_read();                  type = packet_read(&plen);
   
                 /* The server sends failure if it doesn\'t like our key or                  /* The server sends failure if it doesn\'t like our key or
                    does not support RSA authentication. */                     does not support RSA authentication. */
Line 107 
Line 94 
                         packet_disconnect("Protocol error during RSA authentication: %d",                          packet_disconnect("Protocol error during RSA authentication: %d",
                                           type);                                            type);
   
                 packet_get_bignum(challenge);                  packet_get_bignum(challenge, &clen);
                 packet_check_eom();  
   
                   packet_integrity_check(plen, clen, type);
   
                 debug("Received RSA challenge from server.");                  debug("Received RSA challenge from server.");
   
                 /* Ask the agent to decrypt the challenge. */                  /* Ask the agent to decrypt the challenge. */
Line 133 
Line 121 
                 packet_write_wait();                  packet_write_wait();
   
                 /* Wait for response from the server. */                  /* Wait for response from the server. */
                 type = packet_read();                  type = packet_read(&plen);
   
                 /* The server returns success if it accepted the authentication. */                  /* The server returns success if it accepted the authentication. */
                 if (type == SSH_SMSG_SUCCESS) {                  if (type == SSH_SMSG_SUCCESS) {
                         ssh_close_authentication_connection(auth);  
                         BN_clear_free(challenge);                          BN_clear_free(challenge);
                         debug("RSA authentication accepted by server.");                          debug("RSA authentication accepted by server.");
                         return 1;                          return 1;
Line 147 
Line 134 
                         packet_disconnect("Protocol error waiting RSA auth response: %d",                          packet_disconnect("Protocol error waiting RSA auth response: %d",
                                           type);                                            type);
         }          }
         ssh_close_authentication_connection(auth);  
         BN_clear_free(challenge);          BN_clear_free(challenge);
         debug("RSA authentication using agent refused.");          debug("RSA authentication using agent refused.");
         return 0;          return 0;
Line 157 
Line 143 
  * Computes the proper response to a RSA challenge, and sends the response to   * Computes the proper response to a RSA challenge, and sends the response to
  * the server.   * the server.
  */   */
 static void  void
 respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)  respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
 {  {
         u_char buf[32], response[16];          unsigned char buf[32], response[16];
         MD5_CTX md;          MD5_CTX md;
         int i, len;          int i, len;
   
         /* Decrypt the challenge using the private key. */          /* Decrypt the challenge using the private key. */
         /* XXX think about Bleichenbacher, too */          rsa_private_decrypt(challenge, challenge, prv);
         if (rsa_private_decrypt(challenge, challenge, prv) <= 0)  
                 packet_disconnect(  
                     "respond_to_rsa_challenge: rsa_private_decrypt failed");  
   
         /* Compute the response. */          /* Compute the response. */
         /* The response is MD5 of decrypted challenge plus session id. */          /* The response is MD5 of decrypted challenge plus session id. */
         len = BN_num_bytes(challenge);          len = BN_num_bytes(challenge);
         if (len <= 0 || len > sizeof(buf))          if (len <= 0 || len > sizeof(buf))
                 packet_disconnect(                  packet_disconnect("respond_to_rsa_challenge: bad challenge length %d",
                     "respond_to_rsa_challenge: bad challenge length %d", len);                                    len);
   
         memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
         BN_bn2bin(challenge, buf + sizeof(buf) - len);          BN_bn2bin(challenge, buf + sizeof(buf) - len);
Line 202 
Line 185 
  * Checks if the user has authentication file, and if so, tries to authenticate   * Checks if the user has authentication file, and if so, tries to authenticate
  * the user using it.   * the user using it.
  */   */
 static int  int
 try_rsa_authentication(int idx)  try_rsa_authentication(const char *authfile)
 {  {
         BIGNUM *challenge;          BIGNUM *challenge;
         Key *public, *private;          Key *public;
         char buf[300], *passphrase, *comment, *authfile;          Key *private;
         int i, type, quit;          char *passphrase, *comment;
           int type, i;
           int plen, clen;
   
         public = options.identity_keys[idx];          /* Try to load identification for the authentication key. */
         authfile = options.identity_files[idx];          public = key_new(KEY_RSA1);
         comment = xstrdup(authfile);          if (!load_public_key(authfile, public, &comment)) {
                   key_free(public);
                   /* Could not load it.  Fail. */
                   return 0;
           }
         debug("Trying RSA authentication with key '%.100s'", comment);          debug("Trying RSA authentication with key '%.100s'", comment);
   
         /* Tell the server that we are willing to authenticate using this key. */          /* Tell the server that we are willing to authenticate using this key. */
Line 222 
Line 210 
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   
           /* We no longer need the public key. */
           key_free(public);
   
         /* Wait for server's response. */          /* Wait for server's response. */
         type = packet_read();          type = packet_read(&plen);
   
         /*          /*
          * The server responds with failure if it doesn\'t like our key or           * The server responds with failure if it doesn\'t like our key or
Line 239 
Line 230 
                 packet_disconnect("Protocol error during RSA authentication: %d", type);                  packet_disconnect("Protocol error during RSA authentication: %d", type);
   
         /* Get the challenge from the packet. */          /* Get the challenge from the packet. */
         if ((challenge = BN_new()) == NULL)          challenge = BN_new();
                 fatal("try_rsa_authentication: BN_new failed");          packet_get_bignum(challenge, &clen);
         packet_get_bignum(challenge);  
         packet_check_eom();  
   
           packet_integrity_check(plen, clen, type);
   
         debug("Received RSA challenge from server.");          debug("Received RSA challenge from server.");
   
           private = key_new(KEY_RSA1);
         /*          /*
          * If the key is not stored in external hardware, we have to           * 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 (public->flags && KEY_FLAG_EXT)          if (!load_private_key(authfile, "", private, NULL)) {
                 private = public;                  char buf[300];
         else                  snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
                 private = key_load_private_type(KEY_RSA1, authfile, "", NULL);                      comment);
         if (private == NULL && !options.batch_mode) {                  if (!options.batch_mode)
                 snprintf(buf, sizeof(buf),  
                     "Enter passphrase for RSA key '%.100s': ", comment);  
                 for (i = 0; i < options.number_of_password_prompts; i++) {  
                         passphrase = read_passphrase(buf, 0);                          passphrase = read_passphrase(buf, 0);
                         if (strcmp(passphrase, "") != 0) {                  else {
                                 private = key_load_private_type(KEY_RSA1,                          debug("Will not query passphrase for %.100s in batch mode.",
                                     authfile, passphrase, NULL);                                comment);
                                 quit = 0;                          passphrase = xstrdup("");
                         } else {                  }
                                 debug2("no passphrase given, try next key");  
                                 quit = 1;                  /* Load the authentication file using the pasphrase. */
                         }                  if (!load_private_key(authfile, passphrase, private, NULL)) {
                         memset(passphrase, 0, strlen(passphrase));                          memset(passphrase, 0, strlen(passphrase));
                         xfree(passphrase);                          xfree(passphrase);
                         if (private != NULL || quit)                          error("Bad passphrase.");
                                 break;  
                         debug2("bad passphrase given, try again...");                          /* Send a dummy response packet to avoid protocol error. */
                           packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
                           for (i = 0; i < 16; i++)
                                   packet_put_char(0);
                           packet_send();
                           packet_write_wait();
   
                           /* Expect the server to reject it... */
                           packet_read_expect(&plen, SSH_SMSG_FAILURE);
                           xfree(comment);
                           return 0;
                 }                  }
                   /* Destroy the passphrase. */
                   memset(passphrase, 0, strlen(passphrase));
                   xfree(passphrase);
         }          }
         /* We no longer need the comment. */          /* We no longer need the comment. */
         xfree(comment);          xfree(comment);
   
         if (private == NULL) {  
                 if (!options.batch_mode)  
                         error("Bad passphrase.");  
   
                 /* Send a dummy response packet to avoid protocol error. */  
                 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);  
                 for (i = 0; i < 16; i++)  
                         packet_put_char(0);  
                 packet_send();  
                 packet_write_wait();  
   
                 /* Expect the server to reject it... */  
                 packet_read_expect(SSH_SMSG_FAILURE);  
                 BN_clear_free(challenge);  
                 return 0;  
         }  
   
         /* Compute and send a response to the challenge. */          /* Compute and send a response to the challenge. */
         respond_to_rsa_challenge(challenge, private->rsa);          respond_to_rsa_challenge(challenge, private->rsa);
   
         /* Destroy the private key unless it in external hardware. */          /* Destroy the private key. */
         if (!(private->flags & KEY_FLAG_EXT))          key_free(private);
                 key_free(private);  
   
         /* We no longer need the challenge. */          /* We no longer need the challenge. */
         BN_clear_free(challenge);          BN_clear_free(challenge);
   
         /* Wait for response from the server. */          /* Wait for response from the server. */
         type = packet_read();          type = packet_read(&plen);
         if (type == SSH_SMSG_SUCCESS) {          if (type == SSH_SMSG_SUCCESS) {
                 debug("RSA authentication accepted by server.");                  debug("RSA authentication accepted by server.");
                 return 1;                  return 1;
Line 321 
Line 304 
  * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv   * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
  * authentication and RSA host authentication.   * authentication and RSA host authentication.
  */   */
 static int  int
 try_rhosts_rsa_authentication(const char *local_user, Key * host_key)  try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
 {  {
         int type;          int type;
         BIGNUM *challenge;          BIGNUM *challenge;
           int plen, clen;
   
         debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");          debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
   
         /* 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_RHOSTS_RSA);          packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
         packet_put_cstring(local_user);          packet_put_string(local_user, strlen(local_user));
         packet_put_int(BN_num_bits(host_key->rsa->n));          packet_put_int(BN_num_bits(host_key->n));
         packet_put_bignum(host_key->rsa->e);          packet_put_bignum(host_key->e);
         packet_put_bignum(host_key->rsa->n);          packet_put_bignum(host_key->n);
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   
         /* Wait for server's response. */          /* Wait for server's response. */
         type = packet_read();          type = packet_read(&plen);
   
         /* The server responds with failure if it doesn't admit our          /* The server responds with failure if it doesn't admit our
            .rhosts authentication or doesn't know our host key. */             .rhosts authentication or doesn't know our host key. */
Line 352 
Line 336 
                 packet_disconnect("Protocol error during RSA authentication: %d", type);                  packet_disconnect("Protocol error during RSA authentication: %d", type);
   
         /* Get the challenge from the packet. */          /* Get the challenge from the packet. */
         if ((challenge = BN_new()) == NULL)          challenge = BN_new();
                 fatal("try_rhosts_rsa_authentication: BN_new failed");          packet_get_bignum(challenge, &clen);
         packet_get_bignum(challenge);  
         packet_check_eom();  
   
           packet_integrity_check(plen, clen, type);
   
         debug("Received RSA challenge for host key from server.");          debug("Received RSA challenge for host key from server.");
   
         /* Compute a response to the challenge. */          /* Compute a response to the challenge. */
         respond_to_rsa_challenge(challenge, host_key->rsa);          respond_to_rsa_challenge(challenge, host_key);
   
         /* We no longer need the challenge. */          /* We no longer need the challenge. */
         BN_clear_free(challenge);          BN_clear_free(challenge);
   
         /* Wait for response from the server. */          /* Wait for response from the server. */
         type = packet_read();          type = packet_read(&plen);
         if (type == SSH_SMSG_SUCCESS) {          if (type == SSH_SMSG_SUCCESS) {
                 debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");                  debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
                 return 1;                  return 1;
Line 378 
Line 362 
 }  }
   
 #ifdef KRB4  #ifdef KRB4
 static int  int
 try_krb4_authentication(void)  try_kerberos_authentication()
 {  {
         KTEXT_ST auth;          /* Kerberos data */          KTEXT_ST auth;          /* Kerberos data */
         char *reply;          char *reply;
         char inst[INST_SZ];          char inst[INST_SZ];
         char *realm;          char *realm;
         CREDENTIALS cred;          CREDENTIALS cred;
         int r, type;          int r, type, plen;
         socklen_t slen;          socklen_t slen;
         Key_schedule schedule;          Key_schedule schedule;
         u_long checksum, cksum;          u_long checksum, cksum;
Line 398 
Line 382 
         if (stat(tkt_string(), &st) < 0)          if (stat(tkt_string(), &st) < 0)
                 return 0;                  return 0;
   
         strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),          strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), INST_SZ);
             INST_SZ);  
   
         realm = (char *)krb_realmofhost(get_canonical_hostname(1));          realm = (char *) krb_realmofhost(get_canonical_hostname());
         if (!realm) {          if (!realm) {
                 debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));                  debug("Kerberos V4: no realm for %s", get_canonical_hostname());
                 return 0;                  return 0;
         }          }
         /* This can really be anything. */          /* This can really be anything. */
         checksum = (u_long)getpid();          checksum = (u_long) getpid();
   
         r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);          r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
         if (r != KSUCCESS) {          if (r != KSUCCESS) {
                 debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);                  debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]);
                 return 0;                  return 0;
         }          }
         /* Get session key to decrypt the server's reply with. */          /* Get session key to decrypt the server's reply with. */
Line 434 
Line 417 
         slen = sizeof(local);          slen = sizeof(local);
         memset(&local, 0, sizeof(local));          memset(&local, 0, sizeof(local));
         if (getsockname(packet_get_connection_in(),          if (getsockname(packet_get_connection_in(),
             (struct sockaddr *)&local, &slen) < 0)                          (struct sockaddr *) & local, &slen) < 0)
                 debug("getsockname failed: %s", strerror(errno));                  debug("getsockname failed: %s", strerror(errno));
   
         slen = sizeof(foreign);          slen = sizeof(foreign);
         memset(&foreign, 0, sizeof(foreign));          memset(&foreign, 0, sizeof(foreign));
         if (getpeername(packet_get_connection_in(),          if (getpeername(packet_get_connection_in(),
             (struct sockaddr *)&foreign, &slen) < 0) {                          (struct sockaddr *) & foreign, &slen) < 0) {
                 debug("getpeername failed: %s", strerror(errno));                  debug("getpeername failed: %s", strerror(errno));
                 fatal_cleanup();                  fatal_cleanup();
         }          }
         /* Get server reply. */          /* Get server reply. */
         type = packet_read();          type = packet_read(&plen);
         switch (type) {          switch (type) {
         case SSH_SMSG_FAILURE:          case SSH_SMSG_FAILURE:
                 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */                  /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
                 debug("Kerberos v4 authentication failed.");                  debug("Kerberos V4 authentication failed.");
                 return 0;                  return 0;
                 break;                  break;
   
         case SSH_SMSG_AUTH_KERBEROS_RESPONSE:          case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
                 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */                  /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
                 debug("Kerberos v4 authentication accepted.");                  debug("Kerberos V4 authentication accepted.");
   
                 /* Get server's response. */                  /* Get server's response. */
                 reply = packet_get_string((u_int *) &auth.length);                  reply = packet_get_string((unsigned int *) &auth.length);
                 memcpy(auth.dat, reply, auth.length);                  memcpy(auth.dat, reply, auth.length);
                 xfree(reply);                  xfree(reply);
   
                 packet_check_eom();                  packet_integrity_check(plen, 4 + auth.length, type);
   
                 /*                  /*
                  * If his response isn't properly encrypted with the session                   * If his response isn't properly encrypted with the session
Line 470 
Line 453 
                  * bogus. Bail out.                   * bogus. Bail out.
                  */                   */
                 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,                  r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
                     &foreign, &local, &msg_data);                                  &foreign, &local, &msg_data);
                 if (r != KSUCCESS) {                  if (r != KSUCCESS) {
                         debug("Kerberos v4 krb_rd_priv failed: %s",                          debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]);
                             krb_err_txt[r]);                          packet_disconnect("Kerberos V4 challenge failed!");
                         packet_disconnect("Kerberos v4 challenge failed!");  
                 }                  }
                 /* Fetch the (incremented) checksum that we supplied in the request. */                  /* Fetch the (incremented) checksum that we supplied in the request. */
                 memcpy((char *)&cksum, (char *)msg_data.app_data,                  (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum));
                     sizeof(cksum));  
                 cksum = ntohl(cksum);                  cksum = ntohl(cksum);
   
                 /* If it matches, we're golden. */                  /* If it matches, we're golden. */
                 if (cksum == checksum + 1) {                  if (cksum == checksum + 1) {
                         debug("Kerberos v4 challenge successful.");                          debug("Kerberos V4 challenge successful.");
                         return 1;                          return 1;
                 } else                  } else
                         packet_disconnect("Kerberos v4 challenge failed!");                          packet_disconnect("Kerberos V4 challenge failed!");
                 break;                  break;
   
         default:          default:
                 packet_disconnect("Protocol error on Kerberos v4 response: %d", type);                  packet_disconnect("Protocol error on Kerberos V4 response: %d", type);
         }          }
         return 0;          return 0;
 }  }
   
 #endif /* KRB4 */  #endif /* KRB4 */
   
 #ifdef KRB5  
 static int  
 try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)  
 {  
         krb5_error_code problem;  
         const char *tkfile;  
         struct stat buf;  
         krb5_ccache ccache = NULL;  
         const char *remotehost;  
         krb5_data ap;  
         int type;  
         krb5_ap_rep_enc_part *reply = NULL;  
         int ret;  
   
         memset(&ap, 0, sizeof(ap));  
   
         problem = krb5_init_context(context);  
         if (problem) {  
                 debug("Kerberos v5: krb5_init_context failed");  
                 ret = 0;  
                 goto out;  
         }  
   
         tkfile = krb5_cc_default_name(*context);  
         if (strncmp(tkfile, "FILE:", 5) == 0)  
                 tkfile += 5;  
   
         if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {  
                 debug("Kerberos v5: could not get default ccache (permission denied).");  
                 ret = 0;  
                 goto out;  
         }  
   
         problem = krb5_cc_default(*context, &ccache);  
         if (problem) {  
                 debug("Kerberos v5: krb5_cc_default failed: %s",  
                     krb5_get_err_text(*context, problem));  
                 ret = 0;  
                 goto out;  
         }  
   
         remotehost = get_canonical_hostname(1);  
   
         problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,  
             "host", remotehost, NULL, ccache, &ap);  
         if (problem) {  
                 debug("Kerberos v5: krb5_mk_req failed: %s",  
                     krb5_get_err_text(*context, problem));  
                 ret = 0;  
                 goto out;  
         }  
   
         packet_start(SSH_CMSG_AUTH_KERBEROS);  
         packet_put_string((char *) ap.data, ap.length);  
         packet_send();  
         packet_write_wait();  
   
         xfree(ap.data);  
         ap.length = 0;  
   
         type = packet_read();  
         switch (type) {  
         case SSH_SMSG_FAILURE:  
                 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */  
                 debug("Kerberos v5 authentication failed.");  
                 ret = 0;  
                 break;  
   
         case SSH_SMSG_AUTH_KERBEROS_RESPONSE:  
                 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */  
                 debug("Kerberos v5 authentication accepted.");  
   
                 /* Get server's response. */  
                 ap.data = packet_get_string((unsigned int *) &ap.length);  
                 packet_check_eom();  
                 /* XXX je to dobre? */  
   
                 problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);  
                 if (problem) {  
                         ret = 0;  
                 }  
                 ret = 1;  
                 break;  
   
         default:  
                 packet_disconnect("Protocol error on Kerberos v5 response: %d",  
                     type);  
                 ret = 0;  
                 break;  
   
         }  
   
  out:  
         if (ccache != NULL)  
                 krb5_cc_close(*context, ccache);  
         if (reply != NULL)  
                 krb5_free_ap_rep_enc_part(*context, reply);  
         if (ap.length > 0)  
                 krb5_data_free(&ap);  
   
         return (ret);  
 }  
   
 static void  
 send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)  
 {  
         int fd, type;  
         krb5_error_code problem;  
         krb5_data outbuf;  
         krb5_ccache ccache = NULL;  
         krb5_creds creds;  
         krb5_kdc_flags flags;  
         const char *remotehost;  
   
         memset(&creds, 0, sizeof(creds));  
         memset(&outbuf, 0, sizeof(outbuf));  
   
         fd = packet_get_connection_in();  
   
         problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);  
         if (problem)  
                 goto out;  
   
         problem = krb5_cc_default(context, &ccache);  
         if (problem)  
                 goto out;  
   
         problem = krb5_cc_get_principal(context, ccache, &creds.client);  
         if (problem)  
                 goto out;  
   
         problem = krb5_build_principal(context, &creds.server,  
             strlen(creds.client->realm), creds.client->realm,  
             "krbtgt", creds.client->realm, NULL);  
         if (problem)  
                 goto out;  
   
         creds.times.endtime = 0;  
   
         flags.i = 0;  
         flags.b.forwarded = 1;  
         flags.b.forwardable = krb5_config_get_bool(context,  NULL,  
             "libdefaults", "forwardable", NULL);  
   
         remotehost = get_canonical_hostname(1);  
   
         problem = krb5_get_forwarded_creds(context, auth_context,  
             ccache, flags.i, remotehost, &creds, &outbuf);  
         if (problem)  
                 goto out;  
   
         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);  
         packet_put_string((char *)outbuf.data, outbuf.length);  
         packet_send();  
         packet_write_wait();  
   
         type = packet_read();  
   
         if (type == SSH_SMSG_SUCCESS) {  
                 char *pname;  
   
                 krb5_unparse_name(context, creds.client, &pname);  
                 debug("Kerberos v5 TGT forwarded (%s).", pname);  
                 xfree(pname);  
         } else  
                 debug("Kerberos v5 TGT forwarding failed.");  
   
         return;  
   
  out:  
         if (problem)  
                 debug("Kerberos v5 TGT forwarding failed: %s",  
                     krb5_get_err_text(context, problem));  
         if (creds.client)  
                 krb5_free_principal(context, creds.client);  
         if (creds.server)  
                 krb5_free_principal(context, creds.server);  
         if (ccache)  
                 krb5_cc_close(context, ccache);  
         if (outbuf.data)  
                 xfree(outbuf.data);  
 }  
 #endif /* KRB5 */  
   
 #ifdef AFS  #ifdef AFS
 static void  int
 send_krb4_tgt(void)  send_kerberos_tgt()
 {  {
         CREDENTIALS *creds;          CREDENTIALS *creds;
           char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
           int r, type, plen;
           char buffer[8192];
         struct stat st;          struct stat st;
         char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];  
         int problem, type;  
   
         /* Don't do anything if we don't have any tickets. */          /* Don't do anything if we don't have any tickets. */
         if (stat(tkt_string(), &st) < 0)          if (stat(tkt_string(), &st) < 0)
                 return;                  return 0;
   
         creds = xmalloc(sizeof(*creds));          creds = xmalloc(sizeof(*creds));
   
         problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);          if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) {
         if (problem)                  debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]);
                 goto out;                  return 0;
           }
         problem = krb_get_cred("krbtgt", prealm, prealm, creds);          if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) {
         if (problem)                  debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]);
                 goto out;                  return 0;
           }
         if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {          if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
                 problem = RD_AP_EXP;                  debug("Kerberos V4 ticket expired: %s", TKT_FILE);
                 goto out;                  return 0;
         }          }
         creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));          creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
           xfree(creds);
   
         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);          packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
         packet_put_cstring(buffer);          packet_put_string(buffer, strlen(buffer));
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   
         type = packet_read();          type = packet_read(&plen);
   
         if (type == SSH_SMSG_SUCCESS)          if (type == SSH_SMSG_FAILURE)
                 debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",                  debug("Kerberos TGT for realm %s rejected.", prealm);
                     creds->pname, creds->pinst[0] ? "." : "",          else if (type != SSH_SMSG_SUCCESS)
                     creds->pinst, creds->realm);                  packet_disconnect("Protocol error on Kerberos TGT response: %d", type);
         else  
                 debug("Kerberos v4 TGT rejected.");  
   
         xfree(creds);          return 1;
         return;  
   
  out:  
         debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);  
         xfree(creds);  
 }  }
   
 static void  void
 send_afs_tokens(void)  send_afs_tokens(void)
 {  {
         CREDENTIALS creds;          CREDENTIALS creds;
         struct ViceIoctl parms;          struct ViceIoctl parms;
         struct ClearToken ct;          struct ClearToken ct;
         int i, type, len;          int i, type, len, plen;
         char buf[2048], *p, *server_cell;          char buf[2048], *p, *server_cell;
         char buffer[8192];          char buffer[8192];
   
Line 753 
Line 545 
                 p = buf;                  p = buf;
   
                 /* Get secret token. */                  /* Get secret token. */
                 memcpy(&creds.ticket_st.length, p, sizeof(u_int));                  memcpy(&creds.ticket_st.length, p, sizeof(unsigned int));
                 if (creds.ticket_st.length > MAX_KTXT_LEN)                  if (creds.ticket_st.length > MAX_KTXT_LEN)
                         break;                          break;
                 p += sizeof(u_int);                  p += sizeof(unsigned int);
                 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);                  memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
                 p += creds.ticket_st.length;                  p += creds.ticket_st.length;
   
Line 771 
Line 563 
                 server_cell = p;                  server_cell = p;
   
                 /* Flesh out our credentials. */                  /* Flesh out our credentials. */
                 strlcpy(creds.service, "afs", sizeof(creds.service));                  strlcpy(creds.service, "afs", sizeof creds.service);
                 creds.instance[0] = '\0';                  creds.instance[0] = '\0';
                 strlcpy(creds.realm, server_cell, REALM_SZ);                  strlcpy(creds.realm, server_cell, REALM_SZ);
                 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);                  memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
                 creds.issue_date = ct.BeginTimestamp;                  creds.issue_date = ct.BeginTimestamp;
                 creds.lifetime = krb_time_to_life(creds.issue_date,                  creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp);
                     ct.EndTimestamp);  
                 creds.kvno = ct.AuthHandle;                  creds.kvno = ct.AuthHandle;
                 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);                  snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
                 creds.pinst[0] = '\0';                  creds.pinst[0] = '\0';
   
                 /* Encode token, ship it off. */                  /* Encode token, ship it off. */
                 if (creds_to_radix(&creds, (u_char *)buffer,                  if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
                     sizeof(buffer)) <= 0)  
                         break;                          break;
                 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);                  packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
                 packet_put_cstring(buffer);                  packet_put_string(buffer, strlen(buffer));
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
   
                 /* Roger, Roger. Clearance, Clarence. What's your vector,                  /* Roger, Roger. Clearance, Clarence. What's your vector,
                    Victor? */                     Victor? */
                 type = packet_read();                  type = packet_read(&plen);
   
                 if (type == SSH_SMSG_FAILURE)                  if (type == SSH_SMSG_FAILURE)
                         debug("AFS token for cell %s rejected.", server_cell);                          debug("AFS token for cell %s rejected.", server_cell);
Line 808 
Line 598 
  * Tries to authenticate with any string-based challenge/response system.   * Tries to authenticate with any string-based challenge/response system.
  * Note that the client code is not tied to s/key or TIS.   * Note that the client code is not tied to s/key or TIS.
  */   */
 static int  int
 try_challenge_response_authentication(void)  try_skey_authentication()
 {  {
         int type, i;          int type, i;
         u_int clen;          int payload_len;
         char prompt[1024];          unsigned int clen;
         char *challenge, *response;          char *challenge, *response;
   
         debug("Doing challenge response authentication.");          debug("Doing skey authentication.");
   
         for (i = 0; i < options.number_of_password_prompts; i++) {          /* request a challenge */
                 /* request a challenge */          packet_start(SSH_CMSG_AUTH_TIS);
                 packet_start(SSH_CMSG_AUTH_TIS);          packet_send();
                 packet_send();          packet_write_wait();
                 packet_write_wait();  
   
                 type = packet_read();          type = packet_read(&payload_len);
                 if (type != SSH_SMSG_FAILURE &&          if (type != SSH_SMSG_FAILURE &&
                     type != SSH_SMSG_AUTH_TIS_CHALLENGE) {              type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
                         packet_disconnect("Protocol error: got %d in response "                  packet_disconnect("Protocol error: got %d in response "
                             "to SSH_CMSG_AUTH_TIS", type);                                    "to skey-auth", type);
                 }          }
                 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {          if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
                         debug("No challenge.");                  debug("No challenge for skey authentication.");
                         return 0;                  return 0;
                 }          }
                 challenge = packet_get_string(&clen);          challenge = packet_get_string(&clen);
                 packet_check_eom();          packet_integrity_check(payload_len, (4 + clen), type);
                 snprintf(prompt, sizeof prompt, "%s%s", challenge,          if (options.cipher == SSH_CIPHER_NONE)
                     strchr(challenge, '\n') ? "" : "\nResponse: ");                  log("WARNING: Encryption is disabled! "
                 xfree(challenge);                      "Reponse will be transmitted in clear text.");
           fprintf(stderr, "%s\n", challenge);
           xfree(challenge);
           fflush(stderr);
           for (i = 0; i < options.number_of_password_prompts; i++) {
                 if (i != 0)                  if (i != 0)
                         error("Permission denied, please try again.");                          error("Permission denied, please try again.");
                 if (options.cipher == SSH_CIPHER_NONE)                  response = read_passphrase("Response: ", 0);
                         log("WARNING: Encryption is disabled! "  
                             "Reponse will be transmitted in clear text.");  
                 response = read_passphrase(prompt, 0);  
                 if (strcmp(response, "") == 0) {  
                         xfree(response);  
                         break;  
                 }  
                 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);                  packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
                 ssh_put_password(response);                  packet_put_string(response, strlen(response));
                 memset(response, 0, strlen(response));                  memset(response, 0, strlen(response));
                 xfree(response);                  xfree(response);
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
                 type = packet_read();                  type = packet_read(&payload_len);
                 if (type == SSH_SMSG_SUCCESS)                  if (type == SSH_SMSG_SUCCESS)
                         return 1;                          return 1;
                 if (type != SSH_SMSG_FAILURE)                  if (type != SSH_SMSG_FAILURE)
                         packet_disconnect("Protocol error: got %d in response "                          packet_disconnect("Protocol error: got %d in response "
                             "to SSH_CMSG_AUTH_TIS_RESPONSE", type);                                            "to skey-auth-reponse", type);
         }          }
         /* failure */          /* failure */
         return 0;          return 0;
Line 869 
Line 655 
 /*  /*
  * Tries to authenticate with plain passwd authentication.   * Tries to authenticate with plain passwd authentication.
  */   */
 static int  int
 try_password_authentication(char *prompt)  try_password_authentication(char *prompt)
 {  {
         int type, i;          int type, i, payload_len;
         char *password;          char *password;
   
         debug("Doing password authentication.");          debug("Doing password authentication.");
Line 883 
Line 669 
                         error("Permission denied, please try again.");                          error("Permission denied, please try again.");
                 password = read_passphrase(prompt, 0);                  password = read_passphrase(prompt, 0);
                 packet_start(SSH_CMSG_AUTH_PASSWORD);                  packet_start(SSH_CMSG_AUTH_PASSWORD);
                 ssh_put_password(password);                  packet_put_string(password, strlen(password));
                 memset(password, 0, strlen(password));                  memset(password, 0, strlen(password));
                 xfree(password);                  xfree(password);
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
   
                 type = packet_read();                  type = packet_read(&payload_len);
                 if (type == SSH_SMSG_SUCCESS)                  if (type == SSH_SMSG_SUCCESS)
                         return 1;                          return 1;
                 if (type != SSH_SMSG_FAILURE)                  if (type != SSH_SMSG_FAILURE)
Line 907 
Line 693 
 {  {
         int i;          int i;
         BIGNUM *key;          BIGNUM *key;
         Key *host_key, *server_key;          RSA *host_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;
         u_char session_key[SSH_SESSION_KEY_LENGTH];          unsigned char session_key[SSH_SESSION_KEY_LENGTH];
         u_char cookie[8];          unsigned char cookie[8];
         u_int supported_ciphers;          unsigned int supported_ciphers;
         u_int server_flags, client_flags;          unsigned int server_flags, client_flags;
           int payload_len, clen, sum_len = 0;
         u_int32_t rand = 0;          u_int32_t rand = 0;
   
         debug("Waiting for server public key.");          debug("Waiting for server public key.");
   
         /* Wait for a public key packet from the server. */          /* Wait for a public key packet from the server. */
         packet_read_expect(SSH_SMSG_PUBLIC_KEY);          packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
   
         /* Get cookie from the packet. */          /* Get cookie from the packet. */
         for (i = 0; i < 8; i++)          for (i = 0; i < 8; i++)
                 cookie[i] = packet_get_char();                  cookie[i] = packet_get_char();
   
         /* Get the public key. */          /* Get the public key. */
         server_key = key_new(KEY_RSA1);          public_key = RSA_new();
         bits = packet_get_int();          bits = packet_get_int();/* bits */
         packet_get_bignum(server_key->rsa->e);          public_key->e = BN_new();
         packet_get_bignum(server_key->rsa->n);          packet_get_bignum(public_key->e, &clen);
           sum_len += clen;
           public_key->n = BN_new();
           packet_get_bignum(public_key->n, &clen);
           sum_len += clen;
   
         rbits = BN_num_bits(server_key->rsa->n);          rbits = BN_num_bits(public_key->n);
         if (bits != rbits) {          if (bits != rbits) {
                 log("Warning: Server lies about size of server public key: "                  log("Warning: Server lies about size of server public key: "
                     "actual size is %d bits vs. announced %d.", rbits, bits);                      "actual size is %d bits vs. announced %d.", rbits, bits);
                 log("Warning: This may be due to an old implementation of ssh.");                  log("Warning: This may be due to an old implementation of ssh.");
         }          }
         /* Get the host key. */          /* Get the host key. */
         host_key = key_new(KEY_RSA1);          host_key = RSA_new();
         bits = packet_get_int();          bits = packet_get_int();/* bits */
         packet_get_bignum(host_key->rsa->e);          host_key->e = BN_new();
         packet_get_bignum(host_key->rsa->n);          packet_get_bignum(host_key->e, &clen);
           sum_len += clen;
           host_key->n = BN_new();
           packet_get_bignum(host_key->n, &clen);
           sum_len += clen;
   
         rbits = BN_num_bits(host_key->rsa->n);          rbits = BN_num_bits(host_key->n);
         if (bits != rbits) {          if (bits != rbits) {
                 log("Warning: Server lies about size of server host key: "                  log("Warning: Server lies about size of server host key: "
                     "actual size is %d bits vs. announced %d.", rbits, bits);                      "actual size is %d bits vs. announced %d.", rbits, bits);
Line 956 
Line 753 
   
         supported_ciphers = packet_get_int();          supported_ciphers = packet_get_int();
         supported_authentications = packet_get_int();          supported_authentications = packet_get_int();
         packet_check_eom();  
   
         debug("Received server public key (%d bits) and host key (%d bits).",          debug("Received server public key (%d bits) and host key (%d bits).",
             BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));                BN_num_bits(public_key->n), BN_num_bits(host_key->n));
   
         if (verify_host_key(host, hostaddr, host_key) == -1)          packet_integrity_check(payload_len,
                 fatal("Host key verification failed.");                                 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
                                  SSH_SMSG_PUBLIC_KEY);
           k.type = KEY_RSA1;
           k.rsa = host_key;
           check_host_key(host, hostaddr, &k,
               options.user_hostfile, options.system_hostfile);
   
         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->rsa->n, server_key->rsa->n);          compute_session_id(session_id, cookie, host_key->n, public_key->n);
   
         /* Generate a session key. */          /* Generate a session key. */
         arc4random_stir();          arc4random_stir();
Line 988 
Line 789 
          * is the highest byte of the integer.  The session key is xored with           * is the highest byte of the integer.  The session key is xored with
          * the first 16 bytes of the session id.           * the first 16 bytes of the session id.
          */           */
         if ((key = BN_new()) == NULL)          key = BN_new();
                 fatal("respond_to_rsa_challenge: BN_new failed");  
         BN_set_word(key, 0);          BN_set_word(key, 0);
         for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {          for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
                 BN_lshift(key, key, 8);                  BN_lshift(key, key, 8);
Line 1003 
Line 803 
          * Encrypt the integer using the public key and host key of the           * Encrypt the integer using the public key and host key of the
          * server (key with smaller modulus first).           * server (key with smaller modulus first).
          */           */
         if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {          if (BN_cmp(public_key->n, host_key->n) < 0) {
                 /* Public key has smaller modulus. */                  /* Public key has smaller modulus. */
                 if (BN_num_bits(host_key->rsa->n) <                  if (BN_num_bits(host_key->n) <
                     BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {                      BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
                         fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "                          fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
                             "SSH_KEY_BITS_RESERVED %d",                                "SSH_KEY_BITS_RESERVED %d",
                             BN_num_bits(host_key->rsa->n),                                BN_num_bits(host_key->n),
                             BN_num_bits(server_key->rsa->n),                                BN_num_bits(public_key->n),
                             SSH_KEY_BITS_RESERVED);                                SSH_KEY_BITS_RESERVED);
                 }                  }
                 rsa_public_encrypt(key, key, server_key->rsa);                  rsa_public_encrypt(key, key, public_key);
                 rsa_public_encrypt(key, key, host_key->rsa);                  rsa_public_encrypt(key, key, host_key);
         } else {          } else {
                 /* Host key has smaller modulus (or they are equal). */                  /* Host key has smaller modulus (or they are equal). */
                 if (BN_num_bits(server_key->rsa->n) <                  if (BN_num_bits(public_key->n) <
                     BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {                      BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
                         fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "                          fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
                             "SSH_KEY_BITS_RESERVED %d",                                "SSH_KEY_BITS_RESERVED %d",
                             BN_num_bits(server_key->rsa->n),                                BN_num_bits(public_key->n),
                             BN_num_bits(host_key->rsa->n),                                BN_num_bits(host_key->n),
                             SSH_KEY_BITS_RESERVED);                                SSH_KEY_BITS_RESERVED);
                 }                  }
                 rsa_public_encrypt(key, key, host_key->rsa);                  rsa_public_encrypt(key, key, host_key);
                 rsa_public_encrypt(key, key, server_key->rsa);                  rsa_public_encrypt(key, key, public_key);
         }          }
   
         /* Destroy the public keys since we no longer need them. */          /* Destroy the public keys since we no longer need them. */
         key_free(server_key);          RSA_free(public_key);
         key_free(host_key);          RSA_free(host_key);
   
         if (options.cipher == SSH_CIPHER_NOT_SET) {          if (options.cipher == SSH_CIPHER_ILLEGAL) {
                 if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))  
                         options.cipher = ssh_cipher_default;  
         } else if (options.cipher == SSH_CIPHER_ILLEGAL ||  
             !(cipher_mask_ssh1(1) & (1 << options.cipher))) {  
                 log("No valid SSH1 cipher, using %.100s instead.",                  log("No valid SSH1 cipher, using %.100s instead.",
                     cipher_name(ssh_cipher_default));                      cipher_name(ssh_cipher_default));
                 options.cipher = ssh_cipher_default;                  options.cipher = ssh_cipher_default;
           } else if (options.cipher == SSH_CIPHER_NOT_SET) {
                   if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
                           options.cipher = ssh_cipher_default;
         }          }
         /* Check that the selected cipher is supported. */          /* Check that the selected cipher is supported. */
         if (!(supported_ciphers & (1 << options.cipher)))          if (!(supported_ciphers & (1 << options.cipher)))
                 fatal("Selected cipher type %.100s not supported by server.",                  fatal("Selected cipher type %.100s not supported by server.",
                     cipher_name(options.cipher));                        cipher_name(options.cipher));
   
         debug("Encryption type: %.100s", cipher_name(options.cipher));          debug("Encryption type: %.100s", cipher_name(options.cipher));
   
Line 1080 
Line 879 
          * Expect a success message from the server.  Note that this message           * Expect a success message from the server.  Note that this message
          * will be received in encrypted form.           * will be received in encrypted form.
          */           */
         packet_read_expect(SSH_SMSG_SUCCESS);          packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
   
         debug("Received encrypted confirmation.");          debug("Received encrypted confirmation.");
 }  }
Line 1089 
Line 888 
  * Authenticate user   * Authenticate user
  */   */
 void  void
 ssh_userauth1(const char *local_user, const char *server_user, char *host,  ssh_userauth(
     Key **keys, int nkeys)      const char* local_user,
       const char* server_user,
       char *host,
       int host_key_valid, RSA *own_host_key)
 {  {
 #ifdef KRB5  
         krb5_context context = NULL;  
         krb5_auth_context auth_context = NULL;  
 #endif  
         int i, type;          int i, type;
           int payload_len;
   
         if (supported_authentications == 0)          if (supported_authentications == 0)
                 fatal("ssh_userauth1: server supports no auth methods");                  fatal("ssh_userauth: server supports no auth methods");
   
         /* 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);
         packet_put_cstring(server_user);          packet_put_string(server_user, strlen(server_user));
         packet_send();          packet_send();
         packet_write_wait();          packet_write_wait();
   
Line 1112 
Line 911 
          * needed (the user has no password).  Otherwise the server responds           * needed (the user has no password).  Otherwise the server responds
          * with failure.           * with failure.
          */           */
         type = packet_read();          type = packet_read(&payload_len);
   
         /* check whether the connection was accepted without authentication. */          /* check whether the connection was accepted without authentication. */
         if (type == SSH_SMSG_SUCCESS)          if (type == SSH_SMSG_SUCCESS)
                 goto success;                  return;
         if (type != SSH_SMSG_FAILURE)          if (type != SSH_SMSG_FAILURE)
                 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);                  packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
                                     type);
   
 #ifdef KRB5  #ifdef AFS
         if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&          /* Try Kerberos tgt passing if the server supports it. */
             options.kerberos_authentication) {          if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
                 debug("Trying Kerberos v5 authentication.");              options.kerberos_tgt_passing) {
                   if (options.cipher == SSH_CIPHER_NONE)
                 if (try_krb5_authentication(&context, &auth_context)) {                          log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
                         type = packet_read();                  (void) send_kerberos_tgt();
                         if (type == SSH_SMSG_SUCCESS)  
                                 goto success;  
                         if (type != SSH_SMSG_FAILURE)  
                                 packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);  
                 }  
         }          }
 #endif /* KRB5 */          /* Try AFS token passing if the server supports it. */
           if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
               options.afs_token_passing && k_hasafs()) {
                   if (options.cipher == SSH_CIPHER_NONE)
                           log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
                   send_afs_tokens();
           }
   #endif /* AFS */
   
 #ifdef KRB4  #ifdef KRB4
         if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&          if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
             options.kerberos_authentication) {              options.kerberos_authentication) {
                 debug("Trying Kerberos v4 authentication.");                  debug("Trying Kerberos authentication.");
                   if (try_kerberos_authentication()) {
                 if (try_krb4_authentication()) {                          /* The server should respond with success or failure. */
                         type = packet_read();                          type = packet_read(&payload_len);
                         if (type == SSH_SMSG_SUCCESS)                          if (type == SSH_SMSG_SUCCESS)
                                 goto success;                                  return;
                         if (type != SSH_SMSG_FAILURE)                          if (type != SSH_SMSG_FAILURE)
                                 packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);                                  packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
                 }                  }
         }          }
 #endif /* KRB4 */  #endif /* KRB4 */
Line 1158 
Line 960 
             options.rhosts_authentication) {              options.rhosts_authentication) {
                 debug("Trying rhosts authentication.");                  debug("Trying rhosts authentication.");
                 packet_start(SSH_CMSG_AUTH_RHOSTS);                  packet_start(SSH_CMSG_AUTH_RHOSTS);
                 packet_put_cstring(local_user);                  packet_put_string(local_user, strlen(local_user));
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
   
                 /* The server should respond with success or failure. */                  /* The server should respond with success or failure. */
                 type = packet_read();                  type = packet_read(&payload_len);
                 if (type == SSH_SMSG_SUCCESS)                  if (type == SSH_SMSG_SUCCESS)
                         goto success;                          return;
                 if (type != SSH_SMSG_FAILURE)                  if (type != SSH_SMSG_FAILURE)
                         packet_disconnect("Protocol error: got %d in response to rhosts auth",                          packet_disconnect("Protocol error: got %d in response to rhosts auth",
                                           type);                                            type);
Line 1175 
Line 977 
          * authentication.           * authentication.
          */           */
         if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&          if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
             options.rhosts_rsa_authentication) {              options.rhosts_rsa_authentication && host_key_valid) {
                 for (i = 0; i < nkeys; i++) {                  if (try_rhosts_rsa_authentication(local_user, own_host_key))
                         if (keys[i] != NULL && keys[i]->type == KEY_RSA1 &&                          return;
                             try_rhosts_rsa_authentication(local_user, keys[i]))  
                                 goto success;  
                 }  
         }          }
         /* Try RSA authentication if the server supports it. */          /* Try RSA authentication if the server supports it. */
         if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&          if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
Line 1191 
Line 990 
                  * it, whereas identity files may require passphrases.                   * it, whereas identity files may require passphrases.
                  */                   */
                 if (try_agent_authentication())                  if (try_agent_authentication())
                         goto success;                          return;
   
                 /* Try RSA authentication for each identity. */                  /* Try RSA authentication for each identity. */
                 for (i = 0; i < options.num_identity_files; i++)                  for (i = 0; i < options.num_identity_files; i++)
                         if (options.identity_keys[i] != NULL &&                          if (options.identity_files_type[i] == KEY_RSA1 &&
                             options.identity_keys[i]->type == KEY_RSA1 &&                              try_rsa_authentication(options.identity_files[i]))
                             try_rsa_authentication(i))                                  return;
                                 goto success;  
         }          }
         /* Try challenge response authentication if the server supports it. */          /* Try skey authentication if the server supports it. */
         if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&          if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
             options.challenge_response_authentication && !options.batch_mode) {              options.skey_authentication && !options.batch_mode) {
                 if (try_challenge_response_authentication())                  if (try_skey_authentication())
                         goto success;                          return;
         }          }
         /* Try password authentication if the server supports it. */          /* Try password authentication if the server supports it. */
         if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&          if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
             options.password_authentication && !options.batch_mode) {              options.password_authentication && !options.batch_mode) {
                 char prompt[80];                  char prompt[80];
   
                 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",                  snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
                     server_user, host);                      server_user, host);
                 if (try_password_authentication(prompt))                  if (try_password_authentication(prompt))
                         goto success;                          return;
         }          }
         /* All authentication methods have failed.  Exit with an error message. */          /* All authentication methods have failed.  Exit with an error message. */
         fatal("Permission denied.");          fatal("Permission denied.");
         /* NOTREACHED */          /* NOTREACHED */
   
  success:  
 #ifdef KRB5  
         /* Try Kerberos v5 TGT passing. */  
         if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&  
             options.kerberos_tgt_passing && context && auth_context) {  
                 if (options.cipher == SSH_CIPHER_NONE)  
                         log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");  
                 send_krb5_tgt(context, auth_context);  
         }  
         if (auth_context)  
                 krb5_auth_con_free(context, auth_context);  
         if (context)  
                 krb5_free_context(context);  
 #endif  
   
 #ifdef AFS  
         /* Try Kerberos v4 TGT passing if the server supports it. */  
         if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&  
             options.kerberos_tgt_passing) {  
                 if (options.cipher == SSH_CIPHER_NONE)  
                         log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");  
                 send_krb4_tgt();  
         }  
         /* Try AFS token passing if the server supports it. */  
         if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&  
             options.afs_token_passing && k_hasafs()) {  
                 if (options.cipher == SSH_CIPHER_NONE)  
                         log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");  
                 send_afs_tokens();  
         }  
 #endif /* AFS */  
   
         return; /* need statement after label */  
 }  }

Legend:
Removed from v.1.8.2.7  
changed lines
  Added in v.1.9