summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c79
1 files changed, 70 insertions, 9 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index cca720ee2..eb593de73 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -35,7 +35,7 @@
35 35
36#include "includes.h" 36#include "includes.h"
37#include "openbsd-compat/sys-queue.h" 37#include "openbsd-compat/sys-queue.h"
38RCSID("$OpenBSD: ssh-agent.c,v 1.105 2002/10/01 20:34:12 markus Exp $"); 38RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $");
39 39
40#include <openssl/evp.h> 40#include <openssl/evp.h>
41#include <openssl/md5.h> 41#include <openssl/md5.h>
@@ -50,6 +50,8 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.105 2002/10/01 20:34:12 markus Exp $");
50#include "authfd.h" 50#include "authfd.h"
51#include "compat.h" 51#include "compat.h"
52#include "log.h" 52#include "log.h"
53#include "readpass.h"
54#include "misc.h"
53 55
54#ifdef SMARTCARD 56#ifdef SMARTCARD
55#include "scard.h" 57#include "scard.h"
@@ -77,6 +79,7 @@ typedef struct identity {
77 Key *key; 79 Key *key;
78 char *comment; 80 char *comment;
79 u_int death; 81 u_int death;
82 u_int confirm;
80} Identity; 83} Identity;
81 84
82typedef struct { 85typedef struct {
@@ -106,6 +109,9 @@ extern char *__progname;
106char *__progname; 109char *__progname;
107#endif 110#endif
108 111
112/* Default lifetime (0 == forever) */
113static int lifetime = 0;
114
109static void 115static void
110close_socket(SocketEntry *e) 116close_socket(SocketEntry *e)
111{ 117{
@@ -159,6 +165,30 @@ lookup_identity(Key *key, int version)
159 return (NULL); 165 return (NULL);
160} 166}
161 167
168/* Check confirmation of keysign request */
169static int
170confirm_key(Identity *id)
171{
172 char *p, prompt[1024];
173 int ret = -1;
174
175 p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
176 snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n"
177 "Key fingerprint %s.", id->comment, p);
178 xfree(p);
179 p = read_passphrase(prompt, RP_ALLOW_EOF);
180 if (p != NULL) {
181 /*
182 * Accept empty responses and responses consisting
183 * of the word "yes" as affirmative.
184 */
185 if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
186 ret = 0;
187 xfree(p);
188 }
189 return (ret);
190}
191
162/* send list of supported public keys to 'client' */ 192/* send list of supported public keys to 'client' */
163static void 193static void
164process_request_identities(SocketEntry *e, int version) 194process_request_identities(SocketEntry *e, int version)
@@ -222,7 +252,7 @@ process_authentication_challenge1(SocketEntry *e)
222 goto failure; 252 goto failure;
223 253
224 id = lookup_identity(key, 1); 254 id = lookup_identity(key, 1);
225 if (id != NULL) { 255 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
226 Key *private = id->key; 256 Key *private = id->key;
227 /* Decrypt the challenge using the private key. */ 257 /* Decrypt the challenge using the private key. */
228 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 258 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
@@ -282,7 +312,7 @@ process_sign_request2(SocketEntry *e)
282 key = key_from_blob(blob, blen); 312 key = key_from_blob(blob, blen);
283 if (key != NULL) { 313 if (key != NULL) {
284 Identity *id = lookup_identity(key, 2); 314 Identity *id = lookup_identity(key, 2);
285 if (id != NULL) 315 if (id != NULL && (!id->confirm || confirm_key(id) == 0))
286 ok = key_sign(id->key, &signature, &slen, data, dlen); 316 ok = key_sign(id->key, &signature, &slen, data, dlen);
287 } 317 }
288 key_free(key); 318 key_free(key);
@@ -402,7 +432,7 @@ static void
402process_add_identity(SocketEntry *e, int version) 432process_add_identity(SocketEntry *e, int version)
403{ 433{
404 Idtab *tab = idtab_lookup(version); 434 Idtab *tab = idtab_lookup(version);
405 int type, success = 0, death = 0; 435 int type, success = 0, death = 0, confirm = 0;
406 char *type_name, *comment; 436 char *type_name, *comment;
407 Key *k = NULL; 437 Key *k = NULL;
408 438
@@ -453,6 +483,17 @@ process_add_identity(SocketEntry *e, int version)
453 } 483 }
454 break; 484 break;
455 } 485 }
486 /* enable blinding */
487 switch (k->type) {
488 case KEY_RSA:
489 case KEY_RSA1:
490 if (RSA_blinding_on(k->rsa, NULL) != 1) {
491 error("process_add_identity: RSA_blinding_on failed");
492 key_free(k);
493 goto send;
494 }
495 break;
496 }
456 comment = buffer_get_string(&e->request, NULL); 497 comment = buffer_get_string(&e->request, NULL);
457 if (k == NULL) { 498 if (k == NULL) {
458 xfree(comment); 499 xfree(comment);
@@ -464,15 +505,21 @@ process_add_identity(SocketEntry *e, int version)
464 case SSH_AGENT_CONSTRAIN_LIFETIME: 505 case SSH_AGENT_CONSTRAIN_LIFETIME:
465 death = time(NULL) + buffer_get_int(&e->request); 506 death = time(NULL) + buffer_get_int(&e->request);
466 break; 507 break;
508 case SSH_AGENT_CONSTRAIN_CONFIRM:
509 confirm = 1;
510 break;
467 default: 511 default:
468 break; 512 break;
469 } 513 }
470 } 514 }
515 if (lifetime && !death)
516 death = time(NULL) + lifetime;
471 if (lookup_identity(k, version) == NULL) { 517 if (lookup_identity(k, version) == NULL) {
472 Identity *id = xmalloc(sizeof(Identity)); 518 Identity *id = xmalloc(sizeof(Identity));
473 id->key = k; 519 id->key = k;
474 id->comment = comment; 520 id->comment = comment;
475 id->death = death; 521 id->death = death;
522 id->confirm = confirm;
476 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 523 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
477 /* Increment the number of identities. */ 524 /* Increment the number of identities. */
478 tab->nentries++; 525 tab->nentries++;
@@ -557,6 +604,7 @@ process_add_smartcard_key (SocketEntry *e)
557 id->key = k; 604 id->key = k;
558 id->comment = xstrdup("smartcard key"); 605 id->comment = xstrdup("smartcard key");
559 id->death = 0; 606 id->death = 0;
607 id->confirm = 0;
560 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 608 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
561 tab->nentries++; 609 tab->nentries++;
562 success = 1; 610 success = 1;
@@ -930,13 +978,15 @@ usage(void)
930 fprintf(stderr, " -k Kill the current agent.\n"); 978 fprintf(stderr, " -k Kill the current agent.\n");
931 fprintf(stderr, " -d Debug mode.\n"); 979 fprintf(stderr, " -d Debug mode.\n");
932 fprintf(stderr, " -a socket Bind agent socket to given name.\n"); 980 fprintf(stderr, " -a socket Bind agent socket to given name.\n");
981 fprintf(stderr, " -t life Default identity lifetime (seconds).\n");
933 exit(1); 982 exit(1);
934} 983}
935 984
936int 985int
937main(int ac, char **av) 986main(int ac, char **av)
938{ 987{
939 int sock, c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, ch, nalloc; 988 int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
989 int sock, fd, ch, nalloc;
940 char *shell, *format, *pidstr, *agentsocket = NULL; 990 char *shell, *format, *pidstr, *agentsocket = NULL;
941 fd_set *readsetp = NULL, *writesetp = NULL; 991 fd_set *readsetp = NULL, *writesetp = NULL;
942 struct sockaddr_un sunaddr; 992 struct sockaddr_un sunaddr;
@@ -961,7 +1011,7 @@ main(int ac, char **av)
961 init_rng(); 1011 init_rng();
962 seed_rng(); 1012 seed_rng();
963 1013
964 while ((ch = getopt(ac, av, "cdksa:")) != -1) { 1014 while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
965 switch (ch) { 1015 switch (ch) {
966 case 'c': 1016 case 'c':
967 if (s_flag) 1017 if (s_flag)
@@ -984,6 +1034,12 @@ main(int ac, char **av)
984 case 'a': 1034 case 'a':
985 agentsocket = optarg; 1035 agentsocket = optarg;
986 break; 1036 break;
1037 case 't':
1038 if ((lifetime = convtime(optarg)) == -1) {
1039 fprintf(stderr, "Invalid lifetime\n");
1040 usage();
1041 }
1042 break;
987 default: 1043 default:
988 usage(); 1044 usage();
989 } 1045 }
@@ -1116,9 +1172,14 @@ main(int ac, char **av)
1116 } 1172 }
1117 1173
1118 (void)chdir("/"); 1174 (void)chdir("/");
1119 close(0); 1175 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
1120 close(1); 1176 /* XXX might close listen socket */
1121 close(2); 1177 (void)dup2(fd, STDIN_FILENO);
1178 (void)dup2(fd, STDOUT_FILENO);
1179 (void)dup2(fd, STDERR_FILENO);
1180 if (fd > 2)
1181 close(fd);
1182 }
1122 1183
1123#ifdef HAVE_SETRLIMIT 1184#ifdef HAVE_SETRLIMIT
1124 /* deny core dumps, since memory contains unencrypted private keys */ 1185 /* deny core dumps, since memory contains unencrypted private keys */