summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/ssh-agent.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2016-01-19 18:55:44 +0000
committerdes <des@FreeBSD.org>2016-01-19 18:55:44 +0000
commitb856a4573162fbc9ddf1c38fd82b6c728c310d1b (patch)
treeb2a4ad7a06e845ba72a87d2beedfbbcbb7aeb5bb /crypto/openssh/ssh-agent.c
parent76107b08804f309434efce7480edc2bbd15e1bf7 (diff)
parentf8195792ec11c7b20879183ea72e1495f0870617 (diff)
downloadFreeBSD-src-b856a4573162fbc9ddf1c38fd82b6c728c310d1b.zip
FreeBSD-src-b856a4573162fbc9ddf1c38fd82b6c728c310d1b.tar.gz
Upgrade to OpenSSH 6.9p1.
Diffstat (limited to 'crypto/openssh/ssh-agent.c')
-rw-r--r--crypto/openssh/ssh-agent.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
index 92315cc..a1938a6 100644
--- a/crypto/openssh/ssh-agent.c
+++ b/crypto/openssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.199 2015/03/04 21:12:59 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.203 2015/05/15 05:44:21 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -69,6 +69,9 @@ __RCSID("$FreeBSD$");
#include <time.h>
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
#include "key.h" /* XXX for typedef */
#include "buffer.h" /* XXX for typedef */
@@ -141,8 +144,12 @@ char socket_name[PATH_MAX];
char socket_dir[PATH_MAX];
/* locking */
+#define LOCK_SIZE 32
+#define LOCK_SALT_SIZE 16
+#define LOCK_ROUNDS 1
int locked = 0;
-char *lock_passwd = NULL;
+char lock_passwd[LOCK_SIZE];
+char lock_salt[LOCK_SALT_SIZE];
extern char *__progname;
@@ -680,23 +687,45 @@ send:
static void
process_lock_agent(SocketEntry *e, int lock)
{
- int r, success = 0;
- char *passwd;
+ int r, success = 0, delay;
+ 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));
- if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
- locked = 0;
- explicit_bzero(lock_passwd, strlen(lock_passwd));
- free(lock_passwd);
- lock_passwd = NULL;
- success = 1;
+ if (pwlen == 0) {
+ debug("empty password not supported");
+ } else if (locked && !lock) {
+ if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
+ passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
+ 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) {
+ debug("agent locked");
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;
}
- explicit_bzero(passwd, strlen(passwd));
+ explicit_bzero(passwd, pwlen);
free(passwd);
send_status(e, success);
}
@@ -953,7 +982,7 @@ new_socket(sock_type type, int fd)
}
old_alloc = sockets_alloc;
new_alloc = sockets_alloc + 10;
- sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0]));
+ sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
for (i = old_alloc; i < new_alloc; i++)
sockets[i].type = AUTH_UNUSED;
sockets_alloc = new_alloc;
@@ -1161,7 +1190,7 @@ static void
usage(void)
{
fprintf(stderr,
- "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash]\n"
+ "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
" [-t life] [command [arg ...]]\n"
" ssh-agent [-c | -s] -k\n");
fprintf(stderr, " -x Exit when the last client disconnects.\n");
@@ -1171,7 +1200,7 @@ usage(void)
int
main(int ac, char **av)
{
- int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
+ int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
int sock, fd, ch, result, saved_errno;
u_int nalloc;
char *shell, *format, *pidstr, *agentsocket = NULL;
@@ -1207,7 +1236,7 @@ main(int ac, char **av)
__progname = ssh_get_progname(av[0]);
seed_rng();
- while ((ch = getopt(ac, av, "cdksE:a:t:x")) != -1) {
+ while ((ch = getopt(ac, av, "cDdksE:a:t:x")) != -1) {
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1228,10 +1257,15 @@ main(int ac, char **av)
s_flag++;
break;
case 'd':
- if (d_flag)
+ if (d_flag || D_flag)
usage();
d_flag++;
break;
+ case 'D':
+ if (d_flag || D_flag)
+ usage();
+ D_flag++;
+ break;
case 'a':
agentsocket = optarg;
break;
@@ -1251,7 +1285,7 @@ main(int ac, char **av)
ac -= optind;
av += optind;
- if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
+ if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
usage();
if (ac == 0 && !c_flag && !s_flag) {
@@ -1320,8 +1354,10 @@ main(int ac, char **av)
* Fork, and have the parent execute the command, if any, or present
* the socket data. The child continues as the authentication agent.
*/
- if (d_flag) {
- log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1);
+ if (D_flag || d_flag) {
+ log_init(__progname,
+ d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
+ SYSLOG_FACILITY_AUTH, 1);
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME);
@@ -1393,7 +1429,7 @@ skip:
parent_alive_interval = 10;
idtab_init();
signal(SIGPIPE, SIG_IGN);
- signal(SIGINT, d_flag ? cleanup_handler : SIG_IGN);
+ signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
signal(SIGHUP, cleanup_handler);
signal(SIGTERM, cleanup_handler);
nalloc = 0;
OpenPOWER on IntegriCloud