summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 17:00:17 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 17:00:17 +0100
commit544df7a04ae5b5c1fc30be7c445ad685d7a02dc9 (patch)
tree33d2a87dd50fe5894ac6ec4579c83401b7ab00a4 /ssh-agent.c
parentbaccdb349b31c47cd76fb63211f754ed33a9707e (diff)
parent7de4b03a6e4071d454b72927ffaf52949fa34545 (diff)
Import openssh_6.9p1.orig.tar.gz
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index aeda656ac..34b19b754 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.199 2015/03/04 21:12:59 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.203 2015/05/15 05:44:21 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -68,6 +68,9 @@
68#include <time.h> 68#include <time.h>
69#include <string.h> 69#include <string.h>
70#include <unistd.h> 70#include <unistd.h>
71#ifdef HAVE_UTIL_H
72# include <util.h>
73#endif
71 74
72#include "key.h" /* XXX for typedef */ 75#include "key.h" /* XXX for typedef */
73#include "buffer.h" /* XXX for typedef */ 76#include "buffer.h" /* XXX for typedef */
@@ -140,8 +143,12 @@ char socket_name[PATH_MAX];
140char socket_dir[PATH_MAX]; 143char socket_dir[PATH_MAX];
141 144
142/* locking */ 145/* locking */
146#define LOCK_SIZE 32
147#define LOCK_SALT_SIZE 16
148#define LOCK_ROUNDS 1
143int locked = 0; 149int locked = 0;
144char *lock_passwd = NULL; 150char lock_passwd[LOCK_SIZE];
151char lock_salt[LOCK_SALT_SIZE];
145 152
146extern char *__progname; 153extern char *__progname;
147 154
@@ -660,23 +667,45 @@ send:
660static void 667static void
661process_lock_agent(SocketEntry *e, int lock) 668process_lock_agent(SocketEntry *e, int lock)
662{ 669{
663 int r, success = 0; 670 int r, success = 0, delay;
664 char *passwd; 671 char *passwd, passwdhash[LOCK_SIZE];
672 static u_int fail_count = 0;
673 size_t pwlen;
665 674
666 if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0) 675 if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
667 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 676 fatal("%s: buffer error: %s", __func__, ssh_err(r));
668 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 677 if (pwlen == 0) {
669 locked = 0; 678 debug("empty password not supported");
670 explicit_bzero(lock_passwd, strlen(lock_passwd)); 679 } else if (locked && !lock) {
671 free(lock_passwd); 680 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
672 lock_passwd = NULL; 681 passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
673 success = 1; 682 fatal("bcrypt_pbkdf");
683 if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) {
684 debug("agent unlocked");
685 locked = 0;
686 fail_count = 0;
687 explicit_bzero(lock_passwd, sizeof(lock_passwd));
688 success = 1;
689 } else {
690 /* delay in 0.1s increments up to 10s */
691 if (fail_count < 100)
692 fail_count++;
693 delay = 100000 * fail_count;
694 debug("unlock failed, delaying %0.1lf seconds",
695 (double)delay/1000000);
696 usleep(delay);
697 }
698 explicit_bzero(passwdhash, sizeof(passwdhash));
674 } else if (!locked && lock) { 699 } else if (!locked && lock) {
700 debug("agent locked");
675 locked = 1; 701 locked = 1;
676 lock_passwd = xstrdup(passwd); 702 arc4random_buf(lock_salt, sizeof(lock_salt));
703 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
704 lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0)
705 fatal("bcrypt_pbkdf");
677 success = 1; 706 success = 1;
678 } 707 }
679 explicit_bzero(passwd, strlen(passwd)); 708 explicit_bzero(passwd, pwlen);
680 free(passwd); 709 free(passwd);
681 send_status(e, success); 710 send_status(e, success);
682} 711}
@@ -929,7 +958,7 @@ new_socket(sock_type type, int fd)
929 } 958 }
930 old_alloc = sockets_alloc; 959 old_alloc = sockets_alloc;
931 new_alloc = sockets_alloc + 10; 960 new_alloc = sockets_alloc + 10;
932 sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); 961 sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
933 for (i = old_alloc; i < new_alloc; i++) 962 for (i = old_alloc; i < new_alloc; i++)
934 sockets[i].type = AUTH_UNUSED; 963 sockets[i].type = AUTH_UNUSED;
935 sockets_alloc = new_alloc; 964 sockets_alloc = new_alloc;
@@ -1137,7 +1166,7 @@ static void
1137usage(void) 1166usage(void)
1138{ 1167{
1139 fprintf(stderr, 1168 fprintf(stderr,
1140 "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash]\n" 1169 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n"
1141 " [-t life] [command [arg ...]]\n" 1170 " [-t life] [command [arg ...]]\n"
1142 " ssh-agent [-c | -s] -k\n"); 1171 " ssh-agent [-c | -s] -k\n");
1143 exit(1); 1172 exit(1);
@@ -1146,7 +1175,7 @@ usage(void)
1146int 1175int
1147main(int ac, char **av) 1176main(int ac, char **av)
1148{ 1177{
1149 int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; 1178 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
1150 int sock, fd, ch, result, saved_errno; 1179 int sock, fd, ch, result, saved_errno;
1151 u_int nalloc; 1180 u_int nalloc;
1152 char *shell, *format, *pidstr, *agentsocket = NULL; 1181 char *shell, *format, *pidstr, *agentsocket = NULL;
@@ -1181,7 +1210,7 @@ main(int ac, char **av)
1181 __progname = ssh_get_progname(av[0]); 1210 __progname = ssh_get_progname(av[0]);
1182 seed_rng(); 1211 seed_rng();
1183 1212
1184 while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) { 1213 while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) {
1185 switch (ch) { 1214 switch (ch) {
1186 case 'E': 1215 case 'E':
1187 fingerprint_hash = ssh_digest_alg_by_name(optarg); 1216 fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -1202,10 +1231,15 @@ main(int ac, char **av)
1202 s_flag++; 1231 s_flag++;
1203 break; 1232 break;
1204 case 'd': 1233 case 'd':
1205 if (d_flag) 1234 if (d_flag || D_flag)
1206 usage(); 1235 usage();
1207 d_flag++; 1236 d_flag++;
1208 break; 1237 break;
1238 case 'D':
1239 if (d_flag || D_flag)
1240 usage();
1241 D_flag++;
1242 break;
1209 case 'a': 1243 case 'a':
1210 agentsocket = optarg; 1244 agentsocket = optarg;
1211 break; 1245 break;
@@ -1222,7 +1256,7 @@ main(int ac, char **av)
1222 ac -= optind; 1256 ac -= optind;
1223 av += optind; 1257 av += optind;
1224 1258
1225 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) 1259 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
1226 usage(); 1260 usage();
1227 1261
1228 if (ac == 0 && !c_flag && !s_flag) { 1262 if (ac == 0 && !c_flag && !s_flag) {
@@ -1291,8 +1325,10 @@ main(int ac, char **av)
1291 * Fork, and have the parent execute the command, if any, or present 1325 * Fork, and have the parent execute the command, if any, or present
1292 * the socket data. The child continues as the authentication agent. 1326 * the socket data. The child continues as the authentication agent.
1293 */ 1327 */
1294 if (d_flag) { 1328 if (D_flag || d_flag) {
1295 log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1); 1329 log_init(__progname,
1330 d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
1331 SYSLOG_FACILITY_AUTH, 1);
1296 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 1332 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
1297 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 1333 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
1298 SSH_AUTHSOCKET_ENV_NAME); 1334 SSH_AUTHSOCKET_ENV_NAME);
@@ -1364,7 +1400,7 @@ skip:
1364 parent_alive_interval = 10; 1400 parent_alive_interval = 10;
1365 idtab_init(); 1401 idtab_init();
1366 signal(SIGPIPE, SIG_IGN); 1402 signal(SIGPIPE, SIG_IGN);
1367 signal(SIGINT, d_flag ? cleanup_handler : SIG_IGN); 1403 signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
1368 signal(SIGHUP, cleanup_handler); 1404 signal(SIGHUP, cleanup_handler);
1369 signal(SIGTERM, cleanup_handler); 1405 signal(SIGTERM, cleanup_handler);
1370 nalloc = 0; 1406 nalloc = 0;