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

Diff for /src/usr.bin/ssh/ssh-agent.c between version 1.202 and 1.203

version 1.202, 2015/04/24 06:26:49 version 1.203, 2015/05/15 05:44:21
Line 57 
Line 57 
 #include <limits.h>  #include <limits.h>
 #include <time.h>  #include <time.h>
 #include <unistd.h>  #include <unistd.h>
   #include <util.h>
   
 #include "key.h"        /* XXX for typedef */  #include "key.h"        /* XXX for typedef */
 #include "buffer.h"     /* XXX for typedef */  #include "buffer.h"     /* XXX for typedef */
Line 125 
Line 126 
 char socket_dir[PATH_MAX];  char socket_dir[PATH_MAX];
   
 /* locking */  /* locking */
   #define LOCK_SIZE       32
   #define LOCK_SALT_SIZE  16
   #define LOCK_ROUNDS     1
 int locked = 0;  int locked = 0;
 char *lock_passwd = NULL;  char lock_passwd[LOCK_SIZE];
   char lock_salt[LOCK_SALT_SIZE];
   
 extern char *__progname;  extern char *__progname;
   
Line 645 
Line 650 
 static void  static void
 process_lock_agent(SocketEntry *e, int lock)  process_lock_agent(SocketEntry *e, int lock)
 {  {
         int r, success = 0;          int r, success = 0, delay;
         char *passwd;          char *passwd, passwdhash[LOCK_SIZE];
           static u_int fail_count = 0;
           size_t pwlen;
   
         if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0)          if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
                 fatal("%s: buffer error: %s", __func__, ssh_err(r));                  fatal("%s: buffer error: %s", __func__, ssh_err(r));
         if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {          if (pwlen == 0) {
                 locked = 0;                  debug("empty password not supported");
                 explicit_bzero(lock_passwd, strlen(lock_passwd));          } else if (locked && !lock) {
                 free(lock_passwd);                  if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
                 lock_passwd = NULL;                      passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
                 success = 1;                          fatal("bcrypt_pbkdf");
                   if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) {
                           debug("agent unlocked");
                           locked = 0;
                           fail_count = 0;
                           explicit_bzero(lock_passwd, sizeof(lock_passwd));
                           success = 1;
                   } else {
                           /* delay in 0.1s increments up to 10s */
                           if (fail_count < 100)
                                   fail_count++;
                           delay = 100000 * fail_count;
                           debug("unlock failed, delaying %0.1lf seconds",
                               (double)delay/1000000);
                           usleep(delay);
                   }
                   explicit_bzero(passwdhash, sizeof(passwdhash));
         } else if (!locked && lock) {          } else if (!locked && lock) {
                   debug("agent locked");
                 locked = 1;                  locked = 1;
                 lock_passwd = xstrdup(passwd);                  arc4random_buf(lock_salt, sizeof(lock_salt));
                   if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
                       lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0)
                           fatal("bcrypt_pbkdf");
                 success = 1;                  success = 1;
         }          }
         explicit_bzero(passwd, strlen(passwd));          explicit_bzero(passwd, pwlen);
         free(passwd);          free(passwd);
         send_status(e, success);          send_status(e, success);
 }  }

Legend:
Removed from v.1.202  
changed lines
  Added in v.1.203