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

Diff for /src/usr.bin/ssh/sshconnect2.c between version 1.10.2.3 and 1.10.2.4

version 1.10.2.3, 2000/11/08 21:31:30 version 1.10.2.4, 2001/03/12 15:44:17
Line 26 
Line 26 
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <openssl/bn.h>  #include <openssl/bn.h>
 #include <openssl/rsa.h>  
 #include <openssl/dsa.h>  
 #include <openssl/md5.h>  #include <openssl/md5.h>
 #include <openssl/dh.h>  #include <openssl/dh.h>
 #include <openssl/hmac.h>  #include <openssl/hmac.h>
   
 #include "ssh.h"  #include "ssh.h"
   #include "ssh2.h"
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "rsa.h"  #include "rsa.h"
 #include "buffer.h"  #include "buffer.h"
 #include "packet.h"  #include "packet.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "compat.h"  #include "compat.h"
 #include "readconf.h"  
 #include "bufaux.h"  #include "bufaux.h"
 #include "ssh2.h"  #include "cipher.h"
 #include "kex.h"  #include "kex.h"
 #include "myproposal.h"  #include "myproposal.h"
 #include "key.h"  #include "key.h"
 #include "dsa.h"  
 #include "sshconnect.h"  #include "sshconnect.h"
 #include "authfile.h"  #include "authfile.h"
 #include "cli.h"  #include "cli.h"
 #include "dispatch.h"  #include "dispatch.h"
 #include "authfd.h"  #include "authfd.h"
   #include "log.h"
   #include "readconf.h"
   #include "readpass.h"
   
 void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);  void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
 void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);  void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
Line 64 
Line 64 
  * SSH2 key exchange   * SSH2 key exchange
  */   */
   
 unsigned char *session_id2 = NULL;  u_char *session_id2 = NULL;
 int session_id2_len = 0;  int session_id2_len = 0;
   
 void  void
Line 75 
Line 75 
         Buffer *client_kexinit, *server_kexinit;          Buffer *client_kexinit, *server_kexinit;
         char *sprop[PROPOSAL_MAX];          char *sprop[PROPOSAL_MAX];
   
         if (options.ciphers == NULL) {          if (options.ciphers == (char *)-1) {
                 if (options.cipher == SSH_CIPHER_3DES) {                  log("No valid ciphers for protocol version 2 given, using defaults.");
                         options.ciphers = "3des-cbc";                  options.ciphers = NULL;
                 } else if (options.cipher == SSH_CIPHER_BLOWFISH) {  
                         options.ciphers = "blowfish-cbc";  
                 } else if (options.cipher == SSH_CIPHER_DES) {  
                         fatal("cipher DES not supported for protocol version 2");  
                 }  
         }          }
         if (options.ciphers != NULL) {          if (options.ciphers != NULL) {
                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =                  myproposal[PROPOSAL_ENC_ALGS_CTOS] =
                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;                  myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
         }          }
         if (options.compression) {          if (options.compression) {
                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";                  myproposal[PROPOSAL_COMP_ALGS_CTOS] =
                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";                  myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
         } else {          } else {
                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";                  myproposal[PROPOSAL_COMP_ALGS_CTOS] =
                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";                  myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
         }          }
           if (options.macs != NULL) {
                   myproposal[PROPOSAL_MAC_ALGS_CTOS] =
                   myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
           }
   
         /* buffers with raw kexinit messages */          /* buffers with raw kexinit messages */
         server_kexinit = xmalloc(sizeof(*server_kexinit));          server_kexinit = xmalloc(sizeof(*server_kexinit));
Line 150 
Line 149 
 /* diffie-hellman-group1-sha1 */  /* diffie-hellman-group1-sha1 */
   
 void  void
 ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,  ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
                Buffer *client_kexinit, Buffer *server_kexinit)                 Buffer *client_kexinit, Buffer *server_kexinit)
 {  {
 #ifdef DEBUG_KEXDH  #ifdef DEBUG_KEXDH
         int i;          int i;
 #endif  #endif
         int plen, dlen;          int plen, dlen;
         unsigned int klen, kout;          u_int klen, kout;
         char *signature = NULL;          char *signature = NULL;
         unsigned int slen;          u_int slen;
         char *server_host_key_blob = NULL;          char *server_host_key_blob = NULL;
         Key *server_host_key;          Key *server_host_key;
         unsigned int sbloblen;          u_int sbloblen;
         DH *dh;          DH *dh;
         BIGNUM *dh_server_pub = 0;          BIGNUM *dh_server_pub = 0;
         BIGNUM *shared_secret = 0;          BIGNUM *shared_secret = 0;
         unsigned char *kbuf;          u_char *kbuf;
         unsigned char *hash;          u_char *hash;
   
         debug("Sending SSH2_MSG_KEXDH_INIT.");          debug("Sending SSH2_MSG_KEXDH_INIT.");
         /* generate and send 'e', client DH public key */          /* generate and send 'e', client DH public key */
         dh = dh_new_group1();          dh = dh_new_group1();
           dh_gen_key(dh);
         packet_start(SSH2_MSG_KEXDH_INIT);          packet_start(SSH2_MSG_KEXDH_INIT);
         packet_put_bignum2(dh->pub_key);          packet_put_bignum2(dh->pub_key);
         packet_send();          packet_send();
Line 196 
Line 196 
   
         /* key, cert */          /* key, cert */
         server_host_key_blob = packet_get_string(&sbloblen);          server_host_key_blob = packet_get_string(&sbloblen);
         server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);          server_host_key = key_from_blob(server_host_key_blob, sbloblen);
         if (server_host_key == NULL)          if (server_host_key == NULL)
                 fatal("cannot decode server_host_key_blob");                  fatal("cannot decode server_host_key_blob");
   
Line 252 
Line 252 
         );          );
         xfree(server_host_key_blob);          xfree(server_host_key_blob);
         DH_free(dh);          DH_free(dh);
           BN_free(dh_server_pub);
 #ifdef DEBUG_KEXDH  #ifdef DEBUG_KEXDH
         fprintf(stderr, "hash == ");          fprintf(stderr, "hash == ");
         for (i = 0; i< 20; i++)          for (i = 0; i< 20; i++)
                 fprintf(stderr, "%02x", (hash[i])&0xff);                  fprintf(stderr, "%02x", (hash[i])&0xff);
         fprintf(stderr, "\n");          fprintf(stderr, "\n");
 #endif  #endif
         if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)          if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
                 fatal("dsa_verify failed for server_host_key");                  fatal("key_verify failed for server_host_key");
         key_free(server_host_key);          key_free(server_host_key);
           xfree(signature);
   
         kex_derive_keys(kex, hash, shared_secret);          kex_derive_keys(kex, hash, shared_secret);
           BN_clear_free(shared_secret);
         packet_set_kex(kex);          packet_set_kex(kex);
   
         /* save session id */          /* save session id */
Line 282 
Line 285 
 int  int
 dh_estimate(int bits)  dh_estimate(int bits)
 {  {
   
         if (bits < 64)          if (bits < 64)
                 return (512);   /* O(2**63) */                  return (512);   /* O(2**63) */
         if (bits < 128)          if (bits < 128)
Line 300 
Line 303 
         int i;          int i;
 #endif  #endif
         int plen, dlen;          int plen, dlen;
         unsigned int klen, kout;          u_int klen, kout;
         char *signature = NULL;          char *signature = NULL;
         unsigned int slen, nbits;          u_int slen, nbits;
         char *server_host_key_blob = NULL;          char *server_host_key_blob = NULL;
         Key *server_host_key;          Key *server_host_key;
         unsigned int sbloblen;          u_int sbloblen;
         DH *dh;          DH *dh;
         BIGNUM *dh_server_pub = 0;          BIGNUM *dh_server_pub = 0;
         BIGNUM *shared_secret = 0;          BIGNUM *shared_secret = 0;
         BIGNUM *p = 0, *g = 0;          BIGNUM *p = 0, *g = 0;
         unsigned char *kbuf;          u_char *kbuf;
         unsigned char *hash;          u_char *hash;
   
         nbits = dh_estimate(kex->enc[MODE_OUT].cipher->key_len * 8);          nbits = dh_estimate(kex->enc[MODE_OUT].cipher->key_len * 8);
   
Line 337 
Line 340 
         if ((g = BN_new()) == NULL)          if ((g = BN_new()) == NULL)
                 fatal("BN_new");                  fatal("BN_new");
         packet_get_bignum2(g, &dlen);          packet_get_bignum2(g, &dlen);
         if ((dh = dh_new_group(g, p)) == NULL)          dh = dh_new_group(g, p);
                 fatal("dh_new_group");  
   
           dh_gen_key(dh);
   
 #ifdef DEBUG_KEXDH  #ifdef DEBUG_KEXDH
         fprintf(stderr, "\np= ");          fprintf(stderr, "\np= ");
         BN_print_fp(stderr, dh->p);          BN_print_fp(stderr, dh->p);
Line 366 
Line 370 
   
         /* key, cert */          /* key, cert */
         server_host_key_blob = packet_get_string(&sbloblen);          server_host_key_blob = packet_get_string(&sbloblen);
         server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);          server_host_key = key_from_blob(server_host_key_blob, sbloblen);
         if (server_host_key == NULL)          if (server_host_key == NULL)
                 fatal("cannot decode server_host_key_blob");                  fatal("cannot decode server_host_key_blob");
   
Line 416 
Line 420 
             buffer_ptr(client_kexinit), buffer_len(client_kexinit),              buffer_ptr(client_kexinit), buffer_len(client_kexinit),
             buffer_ptr(server_kexinit), buffer_len(server_kexinit),              buffer_ptr(server_kexinit), buffer_len(server_kexinit),
             server_host_key_blob, sbloblen,              server_host_key_blob, sbloblen,
             nbits, dh->p, dh->g,              nbits, dh->p, dh->g,
             dh->pub_key,              dh->pub_key,
             dh_server_pub,              dh_server_pub,
             shared_secret              shared_secret
         );          );
         xfree(server_host_key_blob);          xfree(server_host_key_blob);
         DH_free(dh);          DH_free(dh);
           BN_free(dh_server_pub);
 #ifdef DEBUG_KEXDH  #ifdef DEBUG_KEXDH
         fprintf(stderr, "hash == ");          fprintf(stderr, "hash == ");
         for (i = 0; i< 20; i++)          for (i = 0; i< 20; i++)
                 fprintf(stderr, "%02x", (hash[i])&0xff);                  fprintf(stderr, "%02x", (hash[i])&0xff);
         fprintf(stderr, "\n");          fprintf(stderr, "\n");
 #endif  #endif
         if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)          if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
                 fatal("dsa_verify failed for server_host_key");                  fatal("key_verify failed for server_host_key");
         key_free(server_host_key);          key_free(server_host_key);
           xfree(signature);
   
         kex_derive_keys(kex, hash, shared_secret);          kex_derive_keys(kex, hash, shared_secret);
           BN_clear_free(shared_secret);
         packet_set_kex(kex);          packet_set_kex(kex);
   
         /* save session id */          /* save session id */
Line 451 
Line 458 
   
 typedef int sign_cb_fn(  typedef int sign_cb_fn(
     Authctxt *authctxt, Key *key,      Authctxt *authctxt, Key *key,
     unsigned char **sigp, int *lenp, unsigned char *data, int datalen);      u_char **sigp, int *lenp, u_char *data, int datalen);
   
 struct Authctxt {  struct Authctxt {
         const char *server_user;          const char *server_user;
Line 470 
Line 477 
   
 void    input_userauth_success(int type, int plen, void *ctxt);  void    input_userauth_success(int type, int plen, void *ctxt);
 void    input_userauth_failure(int type, int plen, void *ctxt);  void    input_userauth_failure(int type, int plen, void *ctxt);
   void    input_userauth_banner(int type, int plen, void *ctxt);
 void    input_userauth_error(int type, int plen, void *ctxt);  void    input_userauth_error(int type, int plen, void *ctxt);
 void    input_userauth_info_req(int type, int plen, void *ctxt);  void    input_userauth_info_req(int type, int plen, void *ctxt);
   
Line 478 
Line 486 
 int     userauth_passwd(Authctxt *authctxt);  int     userauth_passwd(Authctxt *authctxt);
 int     userauth_kbdint(Authctxt *authctxt);  int     userauth_kbdint(Authctxt *authctxt);
   
 void    authmethod_clear();  void    authmethod_clear(void);
 Authmethod *authmethod_get(char *authlist);  Authmethod *authmethod_get(char *authlist);
 Authmethod *authmethod_lookup(const char *name);  Authmethod *authmethod_lookup(const char *name);
   
 Authmethod authmethods[] = {  Authmethod authmethods[] = {
         {"publickey",          {"publickey",
                 userauth_pubkey,                  userauth_pubkey,
                 &options.dsa_authentication,                  &options.pubkey_authentication,
                 NULL},                  NULL},
         {"password",          {"password",
                 userauth_passwd,                  userauth_passwd,
Line 509 
Line 517 
         int type;          int type;
         int plen;          int plen;
   
           if (options.challenge_reponse_authentication)
                   options.kbd_interactive_authentication = 1;
   
         debug("send SSH2_MSG_SERVICE_REQUEST");          debug("send SSH2_MSG_SERVICE_REQUEST");
         packet_start(SSH2_MSG_SERVICE_REQUEST);          packet_start(SSH2_MSG_SERVICE_REQUEST);
         packet_put_cstring("ssh-userauth");          packet_put_cstring("ssh-userauth");
Line 522 
Line 533 
                 char *reply = packet_get_string(&plen);                  char *reply = packet_get_string(&plen);
                 debug("service_accept: %s", reply);                  debug("service_accept: %s", reply);
                 xfree(reply);                  xfree(reply);
                 packet_done();  
         } else {          } else {
                 debug("buggy server: service_accept w/o service");                  debug("buggy server: service_accept w/o service");
         }          }
Line 546 
Line 556 
         dispatch_init(&input_userauth_error);          dispatch_init(&input_userauth_error);
         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);          dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);          dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
           dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */          dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
   
         if (authctxt.agent != NULL)          if (authctxt.agent != NULL)
                 ssh_close_authentication_connection(authctxt.agent);                  ssh_close_authentication_connection(authctxt.agent);
   
         debug("ssh-userauth2 successfull: method %s", authctxt.method->name);          debug("ssh-userauth2 successful: method %s", authctxt.method->name);
 }  }
 void  void
 input_userauth_error(int type, int plen, void *ctxt)  input_userauth_error(int type, int plen, void *ctxt)
 {  {
         fatal("input_userauth_error: bad message during authentication");          fatal("input_userauth_error: bad message during authentication: "
              "type %d", type);
 }  }
 void  void
   input_userauth_banner(int type, int plen, void *ctxt)
   {
           char *msg, *lang;
           debug3("input_userauth_banner");
           msg = packet_get_string(NULL);
           lang = packet_get_string(NULL);
           fprintf(stderr, "%s", msg);
           xfree(msg);
           xfree(lang);
   }
   void
 input_userauth_success(int type, int plen, void *ctxt)  input_userauth_success(int type, int plen, void *ctxt)
 {  {
         Authctxt *authctxt = ctxt;          Authctxt *authctxt = ctxt;
Line 582 
Line 605 
         packet_done();          packet_done();
   
         if (partial != 0)          if (partial != 0)
                 debug("partial success");                  log("Authenticated with partial success.");
         debug("authentications that can continue: %s", authlist);          debug("authentications that can continue: %s", authlist);
   
         for (;;) {          for (;;) {
                 method = authmethod_get(authlist);                  method = authmethod_get(authlist);
                 if (method == NULL)                  if (method == NULL)
                         fatal("Unable to find an authentication method");                          fatal("Permission denied (%s).", authlist);
                 authctxt->method = method;                  authctxt->method = method;
                 if (method->userauth(authctxt) != 0) {                  if (method->userauth(authctxt) != 0) {
                         debug2("we sent a %s packet, wait for reply", method->name);                          debug2("we sent a %s packet, wait for reply", method->name);
Line 597 
Line 620 
                         debug2("we did not send a packet, disable method");                          debug2("we did not send a packet, disable method");
                         method->enabled = NULL;                          method->enabled = NULL;
                 }                  }
         }          }
         xfree(authlist);          xfree(authlist);
 }  }
   
Line 627 
Line 650 
         if(attempt != 1)          if(attempt != 1)
                 error("Permission denied, please try again.");                  error("Permission denied, please try again.");
   
         snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",          snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
             authctxt->server_user, authctxt->host);              authctxt->server_user, authctxt->host);
         password = read_passphrase(prompt, 0);          password = read_passphrase(prompt, 0);
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          packet_start(SSH2_MSG_USERAUTH_REQUEST);
Line 635 
Line 658 
         packet_put_cstring(authctxt->service);          packet_put_cstring(authctxt->service);
         packet_put_cstring(authctxt->method->name);          packet_put_cstring(authctxt->method->name);
         packet_put_char(0);          packet_put_char(0);
         packet_put_cstring(password);          ssh_put_password(password);
         memset(password, 0, strlen(password));          memset(password, 0, strlen(password));
         xfree(password);          xfree(password);
         packet_send();          packet_send();
Line 647 
Line 670 
 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)  sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
 {  {
         Buffer b;          Buffer b;
         unsigned char *blob, *signature;          u_char *blob, *signature;
         int bloblen, slen;          int bloblen, slen;
         int skip = 0;          int skip = 0;
         int ret = -1;          int ret = -1;
         int have_sig = 1;          int have_sig = 1;
   
         dsa_make_key_blob(k, &blob, &bloblen);          debug3("sign_and_send_pubkey");
           if (key_to_blob(k, &blob, &bloblen) == 0) {
                   /* we cannot handle this key */
                   debug3("sign_and_send_pubkey: cannot handle key");
                   return 0;
           }
         /* data to be signed */          /* data to be signed */
         buffer_init(&b);          buffer_init(&b);
         if (datafellows & SSH_OLD_SESSIONID) {          if (datafellows & SSH_OLD_SESSIONID) {
                 buffer_append(&b, session_id2, session_id2_len);                  buffer_append(&b, session_id2, session_id2_len);
                 skip = session_id2_len;                  skip = session_id2_len;
         } else {          } else {
                 buffer_put_string(&b, session_id2, session_id2_len);                  buffer_put_string(&b, session_id2, session_id2_len);
                 skip = buffer_len(&b);                  skip = buffer_len(&b);
Line 667 
Line 694 
         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);          buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
         buffer_put_cstring(&b, authctxt->server_user);          buffer_put_cstring(&b, authctxt->server_user);
         buffer_put_cstring(&b,          buffer_put_cstring(&b,
             datafellows & SSH_BUG_PUBKEYAUTH ?              datafellows & SSH_BUG_PKSERVICE ?
             "ssh-userauth" :              "ssh-userauth" :
             authctxt->service);              authctxt->service);
         buffer_put_cstring(&b, authctxt->method->name);          if (datafellows & SSH_BUG_PKAUTH) {
         buffer_put_char(&b, have_sig);                  buffer_put_char(&b, have_sig);
         buffer_put_cstring(&b, KEX_DSS);          } else {
                   buffer_put_cstring(&b, authctxt->method->name);
                   buffer_put_char(&b, have_sig);
                   buffer_put_cstring(&b, key_ssh_name(k));
           }
         buffer_put_string(&b, blob, bloblen);          buffer_put_string(&b, blob, bloblen);
   
         /* generate signature */          /* generate signature */
Line 682 
Line 713 
                 buffer_free(&b);                  buffer_free(&b);
                 return 0;                  return 0;
         }          }
 #ifdef DEBUG_DSS  #ifdef DEBUG_PK
         buffer_dump(&b);          buffer_dump(&b);
 #endif  #endif
         if (datafellows & SSH_BUG_PUBKEYAUTH) {          if (datafellows & SSH_BUG_PKSERVICE) {
                 buffer_clear(&b);                  buffer_clear(&b);
                 buffer_append(&b, session_id2, session_id2_len);                  buffer_append(&b, session_id2, session_id2_len);
                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);                  buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
Line 693 
Line 724 
                 buffer_put_cstring(&b, authctxt->service);                  buffer_put_cstring(&b, authctxt->service);
                 buffer_put_cstring(&b, authctxt->method->name);                  buffer_put_cstring(&b, authctxt->method->name);
                 buffer_put_char(&b, have_sig);                  buffer_put_char(&b, have_sig);
                 buffer_put_cstring(&b, KEX_DSS);                  if (!(datafellows & SSH_BUG_PKAUTH))
                           buffer_put_cstring(&b, key_ssh_name(k));
                 buffer_put_string(&b, blob, bloblen);                  buffer_put_string(&b, blob, bloblen);
         }          }
         xfree(blob);          xfree(blob);
Line 719 
Line 751 
 }  }
   
 /* sign callback */  /* sign callback */
 int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,  int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
     unsigned char *data, int datalen)      u_char *data, int datalen)
 {  {
         return dsa_sign(key, sigp, lenp, data, datalen);          return key_sign(key, sigp, lenp, data, datalen);
 }  }
   
 int  int
 userauth_pubkey_identity(Authctxt *authctxt, char *filename)  userauth_pubkey_identity(Authctxt *authctxt, char *filename)
 {  {
         Key *k;          Key *k;
         int i, ret, try_next;          int i, ret, try_next, success = 0;
         struct stat st;          struct stat st;
           char *passphrase;
           char prompt[300];
   
         if (stat(filename, &st) != 0) {          if (stat(filename, &st) != 0) {
                 debug("key does not exist: %s", filename);                  debug("key does not exist: %s", filename);
Line 738 
Line 772 
         }          }
         debug("try pubkey: %s", filename);          debug("try pubkey: %s", filename);
   
         k = key_new(KEY_DSA);          k = key_new(KEY_UNSPEC);
         if (!load_private_key(filename, "", k, NULL)) {          if (!load_private_key(filename, "", k, NULL)) {
                 int success = 0;                  if (options.batch_mode) {
                 char *passphrase;                          key_free(k);
                 char prompt[300];                          return 0;
                   }
                 snprintf(prompt, sizeof prompt,                  snprintf(prompt, sizeof prompt,
                      "Enter passphrase for %s key '%.100s': ",                       "Enter passphrase for key '%.100s': ", filename);
                      key_type(k), filename);  
                 for (i = 0; i < options.number_of_password_prompts; i++) {                  for (i = 0; i < options.number_of_password_prompts; i++) {
                         passphrase = read_passphrase(prompt, 0);                          passphrase = read_passphrase(prompt, 0);
                         if (strcmp(passphrase, "") != 0) {                          if (strcmp(passphrase, "") != 0) {
Line 766 
Line 800 
                         return 0;                          return 0;
                 }                  }
         }          }
         ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);          ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
         key_free(k);          key_free(k);
         return ret;          return ret;
 }  }
   
 /* sign callback */  /* sign callback */
 int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,  int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
     unsigned char *data, int datalen)      u_char *data, int datalen)
 {  {
         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);          return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
 }  }
Line 782 
Line 816 
 userauth_pubkey_agent(Authctxt *authctxt)  userauth_pubkey_agent(Authctxt *authctxt)
 {  {
         static int called = 0;          static int called = 0;
           int ret = 0;
         char *comment;          char *comment;
         Key *k;          Key *k;
         int ret;  
   
         if (called == 0) {          if (called == 0) {
                 k = ssh_get_first_identity(authctxt->agent, &comment, 2);                  if (ssh_get_num_identities(authctxt->agent, 2) == 0)
                           debug2("userauth_pubkey_agent: no keys at all");
                 called = 1;                  called = 1;
         } else {  
                 k = ssh_get_next_identity(authctxt->agent, &comment, 2);  
         }          }
           k = ssh_get_next_identity(authctxt->agent, &comment, 2);
         if (k == NULL) {          if (k == NULL) {
                 debug2("no more DSA keys from agent");                  debug2("userauth_pubkey_agent: no more keys");
                 return 0;          } else {
                   debug("userauth_pubkey_agent: trying agent key %s", comment);
                   xfree(comment);
                   ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
                   key_free(k);
         }          }
         debug("trying DSA agent key %s", comment);          if (ret == 0)
         xfree(comment);                  debug2("userauth_pubkey_agent: no message sent");
         ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);  
         key_free(k);  
         return ret;          return ret;
 }  }
   
Line 809 
Line 845 
         static int idx = 0;          static int idx = 0;
         int sent = 0;          int sent = 0;
   
         if (authctxt->agent != NULL)          if (authctxt->agent != NULL) {
                 sent = userauth_pubkey_agent(authctxt);                  do {
         while (sent == 0 && idx < options.num_identity_files2)                          sent = userauth_pubkey_agent(authctxt);
                 sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);                  } while(!sent && authctxt->agent->howmany > 0);
           }
           while (!sent && idx < options.num_identity_files) {
                   if (options.identity_files_type[idx] != KEY_RSA1)
                           sent = userauth_pubkey_identity(authctxt,
                               options.identity_files[idx]);
                   idx++;
           }
         return sent;          return sent;
 }  }
   
Line 843 
Line 886 
 }  }
   
 /*  /*
  * parse SSH2_MSG_USERAUTH_INFO_REQUEST, prompt user and send   * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
  * SSH2_MSG_USERAUTH_INFO_RESPONSE  
  */   */
 void  void
 input_userauth_info_req(int type, int plen, void *ctxt)  input_userauth_info_req(int type, int plen, void *ctxt)
 {  {
         Authctxt *authctxt = ctxt;          Authctxt *authctxt = ctxt;
         char *name = NULL;          char *name, *inst, *lang, *prompt, *response;
         char *inst = NULL;          u_int num_prompts, i;
         char *lang = NULL;  
         char *prompt = NULL;  
         char *response = NULL;  
         unsigned int num_prompts, i;  
         int echo = 0;          int echo = 0;
   
         debug2("input_userauth_info_req");          debug2("input_userauth_info_req");
Line 866 
Line 904 
         name = packet_get_string(NULL);          name = packet_get_string(NULL);
         inst = packet_get_string(NULL);          inst = packet_get_string(NULL);
         lang = packet_get_string(NULL);          lang = packet_get_string(NULL);
   
         if (strlen(name) > 0)          if (strlen(name) > 0)
                 cli_mesg(name);                  cli_mesg(name);
         xfree(name);  
   
         if (strlen(inst) > 0)          if (strlen(inst) > 0)
                 cli_mesg(inst);                  cli_mesg(inst);
           xfree(name);
         xfree(inst);          xfree(inst);
         xfree(lang);                            /* unused */          xfree(lang);
   
         num_prompts = packet_get_int();          num_prompts = packet_get_int();
         /*          /*
Line 892 
Line 928 
   
                 response = cli_prompt(prompt, echo);                  response = cli_prompt(prompt, echo);
   
                 packet_put_cstring(response);                  ssh_put_password(response);
                 memset(response, 0, strlen(response));                  memset(response, 0, strlen(response));
                 xfree(response);                  xfree(response);
                 xfree(prompt);                  xfree(prompt);
Line 919 
Line 955 
  * finished processing server list to free resources.   * finished processing server list to free resources.
  */   */
 void  void
 authmethod_clear()  authmethod_clear(void)
 {  {
         if (authlist_current != NULL) {          if (authlist_current != NULL) {
                 xfree(authlist_current);                  xfree(authlist_current);
Line 931 
Line 967 
         }          }
         if (authname_current != NULL) {          if (authname_current != NULL) {
                 xfree(authname_current);                  xfree(authname_current);
                 authlist_state = NULL;                  authname_current = NULL;
         }          }
         if (authlist_state != NULL)          if (authlist_state != NULL)
                 authlist_state = NULL;                  authlist_state = NULL;
Line 974 
Line 1010 
  * use a built-in default list.  If the server sends a nil list after   * use a built-in default list.  If the server sends a nil list after
  * previously sending a valid list, continue using the list originally   * previously sending a valid list, continue using the list originally
  * sent.   * sent.
  */   */
   
 Authmethod *  Authmethod *
 authmethod_get(char *authlist)  authmethod_get(char *authlist)
 {  {
         char *name = NULL, *authname_old;          char *name = NULL, *authname_old;
         Authmethod *method = NULL;          Authmethod *method = NULL;
   
         /* Use a suitable default if we're passed a nil list.  */          /* Use a suitable default if we're passed a nil list.  */
         if (authlist == NULL || strlen(authlist) == 0)          if (authlist == NULL || strlen(authlist) == 0)
                 authlist = def_authlist;                  authlist = def_authlist;

Legend:
Removed from v.1.10.2.3  
changed lines
  Added in v.1.10.2.4