summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
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