[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.3.2.4 and 1.4

version 1.3.2.4, 2001/03/21 18:53:15 version 1.4, 2000/07/16 08:27:22
Line 2 
Line 2 
  * Author: Tatu Ylonen <ylo@cs.hut.fi>   * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved   *                    All rights reserved
    * Created: Sat Mar 18 22:15:47 1995 ylo
  * Code to connect to a remote host, and to perform the client side of the   * Code to connect to a remote host, and to perform the client side of the
  * login (authentication) dialog.   * login (authentication) dialog.
  *   *
  * As far as I am concerned, the code I have written for this software  
  * can be used freely for any purpose.  Any derived versions of this  
  * software must be clearly marked as such, and if the derived work is  
  * incompatible with the protocol description in the RFC file, it must be  
  * called by a name other than "ssh" or "Secure Shell".  
  */   */
   
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <openssl/bn.h>  #include <openssl/bn.h>
   #include <openssl/dsa.h>
   #include <openssl/rsa.h>
 #include <openssl/evp.h>  #include <openssl/evp.h>
   
 #ifdef KRB4  
 #include <krb.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 "cipher.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"  
   
 /* 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 56 
Line 42 
  * authenticate using the agent.   * authenticate using the agent.
  */   */
 int  int
 try_agent_authentication(void)  try_agent_authentication()
 {  {
         int type;          int status, 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;          BIGNUM *e, *n, *challenge;
         Key *key;  
         BIGNUM *challenge;  
   
         /* Get connection to the agent. */          /* Get connection to the agent. */
         auth = ssh_get_authentication_connection();          auth = ssh_get_authentication_connection();
         if (!auth)          if (!auth)
                 return 0;                  return 0;
   
           e = BN_new();
           n = BN_new();
         challenge = BN_new();          challenge = BN_new();
   
         /* Loop through identities served by the agent. */          /* Loop through identities served by the agent. */
         for (key = ssh_get_first_identity(auth, &comment, 1);          for (status = ssh_get_first_identity(auth, e, n, &comment);
              key != NULL;               status;
              key = ssh_get_next_identity(auth, &comment, 1)) {               status = ssh_get_next_identity(auth, e, n, &comment)) {
                   int plen, clen;
   
                 /* 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 85 
Line 72 
   
                 /* 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(key->rsa->n);                  packet_put_bignum(n);
                 packet_send();                  packet_send();
                 packet_write_wait();                  packet_write_wait();
   
Line 96 
Line 83 
                    does not support RSA authentication. */                     does not support RSA authentication. */
                 if (type == SSH_SMSG_FAILURE) {                  if (type == SSH_SMSG_FAILURE) {
                         debug("Server refused our key.");                          debug("Server refused our key.");
                         key_free(key);  
                         continue;                          continue;
                 }                  }
                 /* Otherwise it should have sent a challenge. */                  /* Otherwise it should have sent a challenge. */
Line 111 
Line 97 
                 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. */
                 if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {                  if (!ssh_decrypt_challenge(auth, e, n, challenge,
                         /*                                             session_id, 1, response)) {
                          * The agent failed to authenticate this identifier                          /* The agent failed to authenticate this identifier although it
                          * although it advertised it supports this.  Just                             advertised it supports this.  Just return a wrong value. */
                          * return a wrong value.  
                          */  
                         log("Authentication agent failed to decrypt challenge.");                          log("Authentication agent failed to decrypt challenge.");
                         memset(response, 0, sizeof(response));                          memset(response, 0, sizeof(response));
                 }                  }
                 key_free(key);  
                 debug("Sending response to RSA challenge.");                  debug("Sending response to RSA challenge.");
   
                 /* Send the decrypted challenge back to the server. */                  /* Send the decrypted challenge back to the server. */
Line 135 
Line 118 
   
                 /* 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);  
                         debug("RSA authentication accepted by server.");                          debug("RSA authentication accepted by server.");
                           BN_clear_free(e);
                           BN_clear_free(n);
                           BN_clear_free(challenge);
                         return 1;                          return 1;
                 }                  }
                 /* Otherwise it should return failure. */                  /* Otherwise it should return failure. */
Line 145 
Line 129 
                         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(e);
           BN_clear_free(n);
         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 158 
Line 145 
 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 211 
Line 195 
         int plen, clen;          int plen, clen;
   
         /* Try to load identification for the authentication key. */          /* Try to load identification for the authentication key. */
         public = key_new(KEY_RSA1);          public = key_new(KEY_RSA);
         if (!load_public_key(authfile, public, &comment)) {          if (!load_public_key(authfile, public, &comment)) {
                 key_free(public);                  key_free(public);
                 /* Could not load it.  Fail. */                  /* Could not load it.  Fail. */
Line 252 
Line 236 
   
         debug("Received RSA challenge from server.");          debug("Received RSA challenge from server.");
   
         private = key_new(KEY_RSA1);          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.
Line 285 
Line 269 
                         /* Expect the server to reject it... */                          /* Expect the server to reject it... */
                         packet_read_expect(&plen, SSH_SMSG_FAILURE);                          packet_read_expect(&plen, SSH_SMSG_FAILURE);
                         xfree(comment);                          xfree(comment);
                         key_free(private);  
                         BN_clear_free(challenge);  
                         return 0;                          return 0;
                 }                  }
                 /* Destroy the passphrase. */                  /* Destroy the passphrase. */
Line 380 
Line 362 
   
 #ifdef KRB4  #ifdef KRB4
 int  int
 try_kerberos_authentication(void)  try_kerberos_authentication()
 {  {
         KTEXT_ST auth;          /* Kerberos data */          KTEXT_ST auth;          /* Kerberos data */
         char *reply;          char *reply;
Line 399 
Line 381 
         if (stat(tkt_string(), &st) < 0)          if (stat(tkt_string(), &st) < 0)
                 return 0;                  return 0;
   
         strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ);          strncpy(inst, (char *) krb_get_phost(get_canonical_hostname()), 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. */
Line 458 
Line 440 
                 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);
   
Line 497 
Line 479 
   
 #ifdef AFS  #ifdef AFS
 int  int
 send_kerberos_tgt(void)  send_kerberos_tgt()
 {  {
         CREDENTIALS *creds;          CREDENTIALS *creds;
         char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];          char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
Line 523 
Line 505 
                 debug("Kerberos V4 ticket expired: %s", TKT_FILE);                  debug("Kerberos V4 ticket expired: %s", TKT_FILE);
                 return 0;                  return 0;
         }          }
         creds_to_radix(creds, (u_char *)buffer, sizeof buffer);          creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
         xfree(creds);          xfree(creds);
   
         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);          packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
Line 562 
Line 544 
                 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 591 
Line 573 
                 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, sizeof buffer) <= 0)                  if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
                         break;                          break;
                 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);                  packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
                 packet_put_string(buffer, strlen(buffer));                  packet_put_string(buffer, strlen(buffer));
Line 616 
Line 598 
  * 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.
  */   */
 int  int
 try_challenge_reponse_authentication(void)  try_skey_authentication()
 {  {
         int type, i;          int type, i;
         int payload_len;          int payload_len;
         u_int clen;          unsigned int clen;
         char prompt[1024];  
         char *challenge, *response;          char *challenge, *response;
   
         debug("Doing challenge reponse 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(&payload_len);          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_integrity_check(payload_len, (4 + clen), type);          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();
Line 668 
Line 645 
                         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 691 
Line 668 
                         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();
Line 720 
Line 697 
         Key k;          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;          int payload_len, clen, sum_len = 0;
         u_int32_t rand = 0;          u_int32_t rand = 0;
   
Line 782 
Line 759 
         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_RSA1;          k.type = KEY_RSA;
         k.rsa = host_key;          k.rsa = host_key;
         check_host_key(host, hostaddr, &k,          check_host_key(host, hostaddr, &k,
             options.user_hostfile, options.system_hostfile);              options.user_hostfile, options.system_hostfile);
Line 855 
Line 832 
         RSA_free(public_key);          RSA_free(public_key);
         RSA_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_FALLBACK_CIPHER));
                 options.cipher = ssh_cipher_default;                  options.cipher = SSH_FALLBACK_CIPHER;
           } else if (options.cipher == SSH_CIPHER_NOT_SET) {
                   if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
                           options.cipher = ssh_cipher_default;
                   else {
                           debug("Cipher %s not supported, using %.100s instead.",
                               cipher_name(ssh_cipher_default),
                               cipher_name(SSH_FALLBACK_CIPHER));
                           options.cipher = SSH_FALLBACK_CIPHER;
                   }
         }          }
         /* 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)))
Line 912 
Line 894 
  */   */
 void  void
 ssh_userauth(  ssh_userauth(
     const char *local_user,      const char* local_user,
     const char *server_user,      const char* server_user,
     char *host,      char *host,
     int host_key_valid, RSA *own_host_key)      int host_key_valid, RSA *own_host_key)
 {  {
Line 1017 
Line 999 
   
                 /* 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 (try_rsa_authentication(options.identity_files[i]))
                             options.identity_keys[i]->type == KEY_RSA1 &&  
                             try_rsa_authentication(options.identity_files[i]))  
                                 return;                                  return;
         }          }
         /* 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_reponse_authentication && !options.batch_mode) {              options.skey_authentication && !options.batch_mode) {
                 if (try_challenge_reponse_authentication())                  if (try_skey_authentication())
                         return;                          return;
         }          }
         /* Try password authentication if the server supports it. */          /* Try password authentication if the server supports it. */
Line 1033 
Line 1013 
             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))
                         return;                          return;

Legend:
Removed from v.1.3.2.4  
changed lines
  Added in v.1.4