summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 13:33:15 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 14:27:30 +0100
commitf0b009aea83e9ff3a50be30f51012099a5143c16 (patch)
tree3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /ssh-agent.c
parent47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff)
parent762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (diff)
Merge 6.7p1.
* New upstream release (http://www.openssh.com/txt/release-6.7): - sshd(8): The default set of ciphers and MACs has been altered to remove unsafe algorithms. In particular, CBC ciphers and arcfour* are disabled by default. The full set of algorithms remains available if configured explicitly via the Ciphers and MACs sshd_config options. - ssh(1), sshd(8): Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket (closes: #236718). - ssh(1), ssh-keygen(1): Add support for SSHFP DNS records for ED25519 key types. - sftp(1): Allow resumption of interrupted uploads. - ssh(1): When rekeying, skip file/DNS lookups of the hostkey if it is the same as the one sent during initial key exchange. - sshd(8): Allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family. - sshd(8): Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option. - ssh(1): Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a hash of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding miserly pathname limits for Unix domain sockets in multiplexing control paths. - sshd(8): Make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages. - Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It considers time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly (closes: #734553). - Use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}. * Restore TCP wrappers support, removed upstream in 6.7. It is true that dropping this reduces preauth attack surface in sshd. On the other hand, this support seems to be quite widely used, and abruptly dropping it (from the perspective of users who don't read openssh-unix-dev) could easily cause more serious problems in practice. It's not entirely clear what the right long-term answer for Debian is, but it at least probably doesn't involve dropping this feature shortly before a freeze. * Replace patch to disable OpenSSL version check with an updated version of Kurt Roeckx's patch from #732940 to just avoid checking the status field.
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index ba2461211..25f10c549 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.183 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.190 2014/07/25 21:22:03 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
@@ -49,8 +49,10 @@
49#endif 49#endif
50#include "openbsd-compat/sys-queue.h" 50#include "openbsd-compat/sys-queue.h"
51 51
52#ifdef WITH_OPENSSL
52#include <openssl/evp.h> 53#include <openssl/evp.h>
53#include "openbsd-compat/openssl-compat.h" 54#include "openbsd-compat/openssl-compat.h"
55#endif
54 56
55#include <errno.h> 57#include <errno.h>
56#include <fcntl.h> 58#include <fcntl.h>
@@ -124,6 +126,9 @@ int max_fd = 0;
124pid_t parent_pid = -1; 126pid_t parent_pid = -1;
125time_t parent_alive_interval = 0; 127time_t parent_alive_interval = 0;
126 128
129/* pid of process for which cleanup_socket is applicable */
130pid_t cleanup_pid = 0;
131
127/* pathname and directory for AUTH_SOCKET */ 132/* pathname and directory for AUTH_SOCKET */
128char socket_name[MAXPATHLEN]; 133char socket_name[MAXPATHLEN];
129char socket_dir[MAXPATHLEN]; 134char socket_dir[MAXPATHLEN];
@@ -221,9 +226,11 @@ process_request_identities(SocketEntry *e, int version)
221 buffer_put_int(&msg, tab->nentries); 226 buffer_put_int(&msg, tab->nentries);
222 TAILQ_FOREACH(id, &tab->idlist, next) { 227 TAILQ_FOREACH(id, &tab->idlist, next) {
223 if (id->key->type == KEY_RSA1) { 228 if (id->key->type == KEY_RSA1) {
229#ifdef WITH_SSH1
224 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 230 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
225 buffer_put_bignum(&msg, id->key->rsa->e); 231 buffer_put_bignum(&msg, id->key->rsa->e);
226 buffer_put_bignum(&msg, id->key->rsa->n); 232 buffer_put_bignum(&msg, id->key->rsa->n);
233#endif
227 } else { 234 } else {
228 u_char *blob; 235 u_char *blob;
229 u_int blen; 236 u_int blen;
@@ -238,6 +245,7 @@ process_request_identities(SocketEntry *e, int version)
238 buffer_free(&msg); 245 buffer_free(&msg);
239} 246}
240 247
248#ifdef WITH_SSH1
241/* ssh1 only */ 249/* ssh1 only */
242static void 250static void
243process_authentication_challenge1(SocketEntry *e) 251process_authentication_challenge1(SocketEntry *e)
@@ -273,7 +281,7 @@ process_authentication_challenge1(SocketEntry *e)
273 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 281 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
274 Key *private = id->key; 282 Key *private = id->key;
275 /* Decrypt the challenge using the private key. */ 283 /* Decrypt the challenge using the private key. */
276 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 284 if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0)
277 goto failure; 285 goto failure;
278 286
279 /* The response is MD5 of decrypted challenge plus session id. */ 287 /* The response is MD5 of decrypted challenge plus session id. */
@@ -308,6 +316,7 @@ send:
308 BN_clear_free(challenge); 316 BN_clear_free(challenge);
309 buffer_free(&msg); 317 buffer_free(&msg);
310} 318}
319#endif
311 320
312/* ssh2 only */ 321/* ssh2 only */
313static void 322static void
@@ -359,12 +368,16 @@ process_sign_request2(SocketEntry *e)
359static void 368static void
360process_remove_identity(SocketEntry *e, int version) 369process_remove_identity(SocketEntry *e, int version)
361{ 370{
362 u_int blen, bits; 371 u_int blen;
363 int success = 0; 372 int success = 0;
364 Key *key = NULL; 373 Key *key = NULL;
365 u_char *blob; 374 u_char *blob;
375#ifdef WITH_SSH1
376 u_int bits;
377#endif /* WITH_SSH1 */
366 378
367 switch (version) { 379 switch (version) {
380#ifdef WITH_SSH1
368 case 1: 381 case 1:
369 key = key_new(KEY_RSA1); 382 key = key_new(KEY_RSA1);
370 bits = buffer_get_int(&e->request); 383 bits = buffer_get_int(&e->request);
@@ -375,6 +388,7 @@ process_remove_identity(SocketEntry *e, int version)
375 logit("Warning: identity keysize mismatch: actual %u, announced %u", 388 logit("Warning: identity keysize mismatch: actual %u, announced %u",
376 key_size(key), bits); 389 key_size(key), bits);
377 break; 390 break;
391#endif /* WITH_SSH1 */
378 case 2: 392 case 2:
379 blob = buffer_get_string(&e->request, &blen); 393 blob = buffer_get_string(&e->request, &blen);
380 key = key_from_blob(blob, blen); 394 key = key_from_blob(blob, blen);
@@ -471,6 +485,7 @@ process_add_identity(SocketEntry *e, int version)
471 Key *k = NULL; 485 Key *k = NULL;
472 486
473 switch (version) { 487 switch (version) {
488#ifdef WITH_SSH1
474 case 1: 489 case 1:
475 k = key_new_private(KEY_RSA1); 490 k = key_new_private(KEY_RSA1);
476 (void) buffer_get_int(&e->request); /* ignored */ 491 (void) buffer_get_int(&e->request); /* ignored */
@@ -484,7 +499,9 @@ process_add_identity(SocketEntry *e, int version)
484 buffer_get_bignum(&e->request, k->rsa->p); /* q */ 499 buffer_get_bignum(&e->request, k->rsa->p); /* q */
485 500
486 /* Generate additional parameters */ 501 /* Generate additional parameters */
487 rsa_generate_additional_parameters(k->rsa); 502 if (rsa_generate_additional_parameters(k->rsa) != 0)
503 fatal("%s: rsa_generate_additional_parameters "
504 "error", __func__);
488 505
489 /* enable blinding */ 506 /* enable blinding */
490 if (RSA_blinding_on(k->rsa, NULL) != 1) { 507 if (RSA_blinding_on(k->rsa, NULL) != 1) {
@@ -493,6 +510,7 @@ process_add_identity(SocketEntry *e, int version)
493 goto send; 510 goto send;
494 } 511 }
495 break; 512 break;
513#endif /* WITH_SSH1 */
496 case 2: 514 case 2:
497 k = key_private_deserialize(&e->request); 515 k = key_private_deserialize(&e->request);
498 if (k == NULL) { 516 if (k == NULL) {
@@ -501,11 +519,10 @@ process_add_identity(SocketEntry *e, int version)
501 } 519 }
502 break; 520 break;
503 } 521 }
504 comment = buffer_get_string(&e->request, NULL); 522 if (k == NULL)
505 if (k == NULL) {
506 free(comment);
507 goto send; 523 goto send;
508 } 524 comment = buffer_get_string(&e->request, NULL);
525
509 while (buffer_len(&e->request)) { 526 while (buffer_len(&e->request)) {
510 switch ((type = buffer_get_char(&e->request))) { 527 switch ((type = buffer_get_char(&e->request))) {
511 case SSH_AGENT_CONSTRAIN_LIFETIME: 528 case SSH_AGENT_CONSTRAIN_LIFETIME:
@@ -733,6 +750,7 @@ process_message(SocketEntry *e)
733 case SSH_AGENTC_UNLOCK: 750 case SSH_AGENTC_UNLOCK:
734 process_lock_agent(e, type == SSH_AGENTC_LOCK); 751 process_lock_agent(e, type == SSH_AGENTC_LOCK);
735 break; 752 break;
753#ifdef WITH_SSH1
736 /* ssh1 */ 754 /* ssh1 */
737 case SSH_AGENTC_RSA_CHALLENGE: 755 case SSH_AGENTC_RSA_CHALLENGE:
738 process_authentication_challenge1(e); 756 process_authentication_challenge1(e);
@@ -750,6 +768,7 @@ process_message(SocketEntry *e)
750 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 768 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
751 process_remove_all_identities(e, 1); 769 process_remove_all_identities(e, 1);
752 break; 770 break;
771#endif
753 /* ssh2 */ 772 /* ssh2 */
754 case SSH2_AGENTC_SIGN_REQUEST: 773 case SSH2_AGENTC_SIGN_REQUEST:
755 process_sign_request2(e); 774 process_sign_request2(e);
@@ -949,6 +968,7 @@ after_select(fd_set *readset, fd_set *writeset)
949 break; 968 break;
950 } 969 }
951 buffer_append(&sockets[i].input, buf, len); 970 buffer_append(&sockets[i].input, buf, len);
971 explicit_bzero(buf, sizeof(buf));
952 process_message(&sockets[i]); 972 process_message(&sockets[i]);
953 } 973 }
954 break; 974 break;
@@ -960,6 +980,9 @@ after_select(fd_set *readset, fd_set *writeset)
960static void 980static void
961cleanup_socket(void) 981cleanup_socket(void)
962{ 982{
983 if (cleanup_pid != 0 && getpid() != cleanup_pid)
984 return;
985 debug("%s: cleanup", __func__);
963 if (socket_name[0]) 986 if (socket_name[0])
964 unlink(socket_name); 987 unlink(socket_name);
965 if (socket_dir[0]) 988 if (socket_dir[0])
@@ -1001,15 +1024,10 @@ check_parent_exists(void)
1001static void 1024static void
1002usage(void) 1025usage(void)
1003{ 1026{
1004 fprintf(stderr, "usage: %s [options] [command [arg ...]]\n", 1027 fprintf(stderr,
1005 __progname); 1028 "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n"
1006 fprintf(stderr, "Options:\n"); 1029 " [command [arg ...]]\n"
1007 fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); 1030 " ssh-agent [-c | -s] -k\n");
1008 fprintf(stderr, " -s Generate Bourne shell commands on stdout.\n");
1009 fprintf(stderr, " -k Kill the current agent.\n");
1010 fprintf(stderr, " -d Debug mode.\n");
1011 fprintf(stderr, " -a socket Bind agent socket to given name.\n");
1012 fprintf(stderr, " -t life Default identity lifetime (seconds).\n");
1013 exit(1); 1031 exit(1);
1014} 1032}
1015 1033
@@ -1021,17 +1039,16 @@ main(int ac, char **av)
1021 u_int nalloc; 1039 u_int nalloc;
1022 char *shell, *format, *pidstr, *agentsocket = NULL; 1040 char *shell, *format, *pidstr, *agentsocket = NULL;
1023 fd_set *readsetp = NULL, *writesetp = NULL; 1041 fd_set *readsetp = NULL, *writesetp = NULL;
1024 struct sockaddr_un sunaddr;
1025#ifdef HAVE_SETRLIMIT 1042#ifdef HAVE_SETRLIMIT
1026 struct rlimit rlim; 1043 struct rlimit rlim;
1027#endif 1044#endif
1028 int prev_mask;
1029 extern int optind; 1045 extern int optind;
1030 extern char *optarg; 1046 extern char *optarg;
1031 pid_t pid; 1047 pid_t pid;
1032 char pidstrbuf[1 + 3 * sizeof pid]; 1048 char pidstrbuf[1 + 3 * sizeof pid];
1033 struct timeval *tvp = NULL; 1049 struct timeval *tvp = NULL;
1034 size_t len; 1050 size_t len;
1051 mode_t prev_mask;
1035 1052
1036 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1053 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1037 sanitise_stdfd(); 1054 sanitise_stdfd();
@@ -1045,7 +1062,9 @@ main(int ac, char **av)
1045 prctl(PR_SET_DUMPABLE, 0); 1062 prctl(PR_SET_DUMPABLE, 0);
1046#endif 1063#endif
1047 1064
1065#ifdef WITH_OPENSSL
1048 OpenSSL_add_all_algorithms(); 1066 OpenSSL_add_all_algorithms();
1067#endif
1049 1068
1050 __progname = ssh_get_progname(av[0]); 1069 __progname = ssh_get_progname(av[0]);
1051 seed_rng(); 1070 seed_rng();
@@ -1142,27 +1161,14 @@ main(int ac, char **av)
1142 * Create socket early so it will exist before command gets run from 1161 * Create socket early so it will exist before command gets run from
1143 * the parent. 1162 * the parent.
1144 */ 1163 */
1145 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1146 if (sock < 0) {
1147 perror("socket");
1148 *socket_name = '\0'; /* Don't unlink any existing file */
1149 cleanup_exit(1);
1150 }
1151 memset(&sunaddr, 0, sizeof(sunaddr));
1152 sunaddr.sun_family = AF_UNIX;
1153 strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
1154 prev_mask = umask(0177); 1164 prev_mask = umask(0177);
1155 if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { 1165 sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
1156 perror("bind"); 1166 if (sock < 0) {
1167 /* XXX - unix_listener() calls error() not perror() */
1157 *socket_name = '\0'; /* Don't unlink any existing file */ 1168 *socket_name = '\0'; /* Don't unlink any existing file */
1158 umask(prev_mask);
1159 cleanup_exit(1); 1169 cleanup_exit(1);
1160 } 1170 }
1161 umask(prev_mask); 1171 umask(prev_mask);
1162 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
1163 perror("listen");
1164 cleanup_exit(1);
1165 }
1166 1172
1167 /* 1173 /*
1168 * Fork, and have the parent execute the command, if any, or present 1174 * Fork, and have the parent execute the command, if any, or present
@@ -1231,6 +1237,8 @@ main(int ac, char **av)
1231 1237
1232skip: 1238skip:
1233 1239
1240 cleanup_pid = getpid();
1241
1234#ifdef ENABLE_PKCS11 1242#ifdef ENABLE_PKCS11
1235 pkcs11_init(0); 1243 pkcs11_init(0);
1236#endif 1244#endif