[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.213 and 1.214

version 1.213, 2015/01/08 10:14:08 version 1.214, 2015/01/14 20:05:27
Line 64 
Line 64 
 #include "pathnames.h"  #include "pathnames.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "hostfile.h"  #include "hostfile.h"
   #include "ssherr.h"
   
 #ifdef GSSAPI  #ifdef GSSAPI
 #include "ssh-gss.h"  #include "ssh-gss.h"
Line 125 
Line 126 
         } while (0)          } while (0)
   
         while ((alg = strsep(&avail, ",")) && *alg != '\0') {          while ((alg = strsep(&avail, ",")) && *alg != '\0') {
                 if ((ktype = key_type_from_name(alg)) == KEY_UNSPEC)                  if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
                         fatal("%s: unknown alg %s", __func__, alg);                          fatal("%s: unknown alg %s", __func__, alg);
                 if (lookup_key_in_hostkeys_by_type(hostkeys,                  if (lookup_key_in_hostkeys_by_type(hostkeys,
                     key_type_plain(ktype), NULL))                      sshkey_type_plain(ktype), NULL))
                         ALG_APPEND(first, alg);                          ALG_APPEND(first, alg);
                 else                  else
                         ALG_APPEND(last, alg);                          ALG_APPEND(last, alg);
Line 236 
Line 237 
  * Authenticate user   * Authenticate user
  */   */
   
 typedef struct Authctxt Authctxt;  typedef struct cauthctxt Authctxt;
 typedef struct Authmethod Authmethod;  typedef struct cauthmethod Authmethod;
 typedef struct identity Identity;  typedef struct identity Identity;
 typedef struct idlist Idlist;  typedef struct idlist Idlist;
   
 struct identity {  struct identity {
         TAILQ_ENTRY(identity) next;          TAILQ_ENTRY(identity) next;
         AuthenticationConnection *ac;   /* set if agent supports key */          int     agent_fd;               /* >=0 if agent supports key */
         Key     *key;                   /* public/private key */          struct sshkey   *key;           /* public/private key */
         char    *filename;              /* comment for agent-only keys */          char    *filename;              /* comment for agent-only keys */
         int     tried;          int     tried;
         int     isprivate;              /* key points to the private key */          int     isprivate;              /* key points to the private key */
Line 252 
Line 253 
 };  };
 TAILQ_HEAD(idlist, identity);  TAILQ_HEAD(idlist, identity);
   
 struct Authctxt {  struct cauthctxt {
         const char *server_user;          const char *server_user;
         const char *local_user;          const char *local_user;
         const char *host;          const char *host;
         const char *service;          const char *service;
         Authmethod *method;          struct cauthmethod *method;
         sig_atomic_t success;          sig_atomic_t success;
         char *authlist;          char *authlist;
           int attempt;
         /* pubkey */          /* pubkey */
         Idlist keys;          struct idlist keys;
         AuthenticationConnection *agent;          int agent_fd;
         /* hostbased */          /* hostbased */
         Sensitive *sensitive;          Sensitive *sensitive;
         /* kbd-interactive */          /* kbd-interactive */
Line 270 
Line 272 
         /* generic */          /* generic */
         void *methoddata;          void *methoddata;
 };  };
 struct Authmethod {  
   struct cauthmethod {
         char    *name;          /* string to compare against server's list */          char    *name;          /* string to compare against server's list */
         int     (*userauth)(Authctxt *authctxt);          int     (*userauth)(Authctxt *authctxt);
         void    (*cleanup)(Authctxt *authctxt);          void    (*cleanup)(Authctxt *authctxt);
Line 576 
Line 579 
                     key->type, pktype);                      key->type, pktype);
                 goto done;                  goto done;
         }          }
         fp = key_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);          fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
         debug2("input_userauth_pk_ok: fp %s", fp);          debug2("input_userauth_pk_ok: fp %s", fp);
         free(fp);          free(fp);
   
Line 950 
Line 953 
 }  }
   
 static int  static int
 identity_sign(Identity *id, u_char **sigp, u_int *lenp,  identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
     u_char *data, u_int datalen)      const u_char *data, size_t datalen, u_int compat)
 {  {
         Key *prv;          Key *prv;
         int ret;          int ret;
   
         /* the agent supports this key */          /* the agent supports this key */
         if (id->ac)          if (id->agent_fd)
                 return (ssh_agent_sign(id->ac, id->key, sigp, lenp,                  return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
                     data, datalen));                      data, datalen, compat);
   
         /*          /*
          * we have already loaded the private key or           * we have already loaded the private key or
          * the private key is stored in external hardware           * the private key is stored in external hardware
          */           */
         if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))          if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
                 return (key_sign(id->key, sigp, lenp, data, datalen));                  return (sshkey_sign(id->key, sigp, lenp, data, datalen,
                       compat));
         /* load the private key from the file */          /* load the private key from the file */
         if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)          if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
                 return (-1);                  return (-1); /* XXX return decent error code */
         ret = key_sign(prv, sigp, lenp, data, datalen);          ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat);
         key_free(prv);          sshkey_free(prv);
         return (ret);          return (ret);
 }  }
   
Line 979 
Line 984 
 {  {
         Buffer b;          Buffer b;
         u_char *blob, *signature;          u_char *blob, *signature;
         u_int bloblen, slen;          u_int bloblen;
           size_t slen;
         u_int skip = 0;          u_int skip = 0;
         int ret = -1;          int ret = -1;
         int have_sig = 1;          int have_sig = 1;
Line 1020 
Line 1026 
   
         /* generate signature */          /* generate signature */
         ret = identity_sign(id, &signature, &slen,          ret = identity_sign(id, &signature, &slen,
             buffer_ptr(&b), buffer_len(&b));              buffer_ptr(&b), buffer_len(&b), datafellows);
         if (ret == -1) {          if (ret != 0) {
                 free(blob);                  free(blob);
                 buffer_free(&b);                  buffer_free(&b);
                 return 0;                  return 0;
Line 1096 
Line 1102 
 {  {
         Key *private;          Key *private;
         char prompt[300], *passphrase;          char prompt[300], *passphrase;
         int perm_ok = 0, quit, i;          int r, perm_ok = 0, quit, i;
         struct stat st;          struct stat st;
   
         if (stat(filename, &st) < 0) {          if (stat(filename, &st) < 0) {
Line 1104 
Line 1110 
                     filename, strerror(errno));                      filename, strerror(errno));
                 return NULL;                  return NULL;
         }          }
         private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);          snprintf(prompt, sizeof prompt,
         if (!perm_ok) {              "Enter passphrase for key '%.100s': ", filename);
                 if (private != NULL)          for (i = 0; i <= options.number_of_password_prompts; i++) {
                         key_free(private);                  if (i == 0)
                 return NULL;                          passphrase = "";
         }                  else {
         if (private == NULL) {  
                 if (options.batch_mode)  
                         return NULL;  
                 snprintf(prompt, sizeof prompt,  
                     "Enter passphrase for key '%.100s': ", filename);  
                 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 (*passphrase == '\0') {
                                 private = key_load_private_type(KEY_UNSPEC,  
                                     filename, passphrase, NULL, NULL);  
                                 quit = 0;  
                         } else {  
                                 debug2("no passphrase given, try next key");                                  debug2("no passphrase given, try next key");
                                   free(passphrase);
                                   break;
                           }
                   }
                   switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename,
                       passphrase, &private, NULL, &perm_ok))) {
                   case 0:
                           break;
                   case SSH_ERR_KEY_WRONG_PASSPHRASE:
                           if (options.batch_mode) {
                                 quit = 1;                                  quit = 1;
                                   break;
                         }                          }
                           debug2("bad passphrase given, try again...");
                           break;
                   case SSH_ERR_SYSTEM_ERROR:
                           if (errno == ENOENT) {
                                   debug2("Load key \"%s\": %s",
                                       filename, ssh_err(r));
                                   quit = 1;
                                   break;
                           }
                           /* FALLTHROUGH */
                   default:
                           error("Load key \"%s\": %s", filename, ssh_err(r));
                           quit = 1;
                           break;
                   }
                   if (i > 0) {
                         explicit_bzero(passphrase, strlen(passphrase));                          explicit_bzero(passphrase, strlen(passphrase));
                         free(passphrase);                          free(passphrase);
                         if (private != NULL || quit)  
                                 break;  
                         debug2("bad passphrase given, try again...");  
                 }                  }
                   if (private != NULL || quit)
                           break;
         }          }
         return private;          return private;
 }  }
Line 1144 
Line 1166 
 static void  static void
 pubkey_prepare(Authctxt *authctxt)  pubkey_prepare(Authctxt *authctxt)
 {  {
         Identity *id, *id2, *tmp;          struct identity *id, *id2, *tmp;
         Idlist agent, files, *preferred;          struct idlist agent, files, *preferred;
         Key *key;          struct sshkey *key;
         AuthenticationConnection *ac;          int agent_fd, i, r, found;
         char *comment;          size_t j;
         int i, found;          struct ssh_identitylist *idlist;
   
         TAILQ_INIT(&agent);     /* keys from the agent */          TAILQ_INIT(&agent);     /* keys from the agent */
         TAILQ_INIT(&files);     /* keys from the config file */          TAILQ_INIT(&files);     /* keys from the config file */
Line 1179 
Line 1201 
                         if (id2->key == NULL ||                          if (id2->key == NULL ||
                             (id2->key->flags & SSHKEY_FLAG_EXT) == 0)                              (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
                                 continue;                                  continue;
                         if (key_equal(id->key, id2->key)) {                          if (sshkey_equal(id->key, id2->key)) {
                                 TAILQ_REMOVE(&files, id, next);                                  TAILQ_REMOVE(&files, id, next);
                                 TAILQ_INSERT_TAIL(preferred, id, next);                                  TAILQ_INSERT_TAIL(preferred, id, next);
                                 found = 1;                                  found = 1;
Line 1194 
Line 1216 
                 }                  }
         }          }
         /* list of keys supported by the agent */          /* list of keys supported by the agent */
         if ((ac = ssh_get_authentication_connection())) {          if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
                 for (key = ssh_get_first_identity(ac, &comment, 2);                  if (r != SSH_ERR_AGENT_NOT_PRESENT)
                     key != NULL;                          debug("%s: ssh_get_authentication_socket: %s",
                     key = ssh_get_next_identity(ac, &comment, 2)) {                              __func__, ssh_err(r));
           } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) {
                   if (r != SSH_ERR_AGENT_NO_IDENTITIES)
                           debug("%s: ssh_fetch_identitylist: %s",
                               __func__, ssh_err(r));
           } else {
                   for (j = 0; j < idlist->nkeys; j++) {
                         found = 0;                          found = 0;
                         TAILQ_FOREACH(id, &files, next) {                          TAILQ_FOREACH(id, &files, next) {
                                 /* agent keys from the config file are preferred */                                  /*
                                 if (key_equal(key, id->key)) {                                   * agent keys from the config file are
                                         key_free(key);                                   * preferred
                                         free(comment);                                   */
                                   if (sshkey_equal(idlist->keys[j], id->key)) {
                                         TAILQ_REMOVE(&files, id, next);                                          TAILQ_REMOVE(&files, id, next);
                                         TAILQ_INSERT_TAIL(preferred, id, next);                                          TAILQ_INSERT_TAIL(preferred, id, next);
                                         id->ac = ac;                                          id->agent_fd = agent_fd;
                                         found = 1;                                          found = 1;
                                         break;                                          break;
                                 }                                  }
                         }                          }
                         if (!found && !options.identities_only) {                          if (!found && !options.identities_only) {
                                 id = xcalloc(1, sizeof(*id));                                  id = xcalloc(1, sizeof(*id));
                                 id->key = key;                                  /* XXX "steals" key/comment from idlist */
                                 id->filename = comment;                                  id->key = idlist->keys[j];
                                 id->ac = ac;                                  id->filename = idlist->comments[j];
                                   idlist->keys[j] = NULL;
                                   idlist->comments[j] = NULL;
                                   id->agent_fd = agent_fd;
                                 TAILQ_INSERT_TAIL(&agent, id, next);                                  TAILQ_INSERT_TAIL(&agent, id, next);
                         }                          }
                 }                  }
                   ssh_free_identitylist(idlist);
                 /* append remaining agent keys */                  /* append remaining agent keys */
                 for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {                  for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
                         TAILQ_REMOVE(&agent, id, next);                          TAILQ_REMOVE(&agent, id, next);
                         TAILQ_INSERT_TAIL(preferred, id, next);                          TAILQ_INSERT_TAIL(preferred, id, next);
                 }                  }
                 authctxt->agent = ac;                  authctxt->agent_fd = agent_fd;
         }          }
         /* append remaining keys from the config file */          /* append remaining keys from the config file */
         for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {          for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
Line 1242 
Line 1275 
 {  {
         Identity *id;          Identity *id;
   
         if (authctxt->agent != NULL)          if (authctxt->agent_fd != -1)
                 ssh_close_authentication_connection(authctxt->agent);                  ssh_close_authentication_socket(authctxt->agent_fd);
         for (id = TAILQ_FIRST(&authctxt->keys); id;          for (id = TAILQ_FIRST(&authctxt->keys); id;
             id = TAILQ_FIRST(&authctxt->keys)) {              id = TAILQ_FIRST(&authctxt->keys)) {
                 TAILQ_REMOVE(&authctxt->keys, id, next);                  TAILQ_REMOVE(&authctxt->keys, id, next);
                 if (id->key)                  if (id->key)
                         key_free(id->key);                          sshkey_free(id->key);
                 free(id->filename);                  free(id->filename);
                 free(id);                  free(id);
         }          }

Legend:
Removed from v.1.213  
changed lines
  Added in v.1.214