diff options
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 89 |
1 files changed, 80 insertions, 9 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index d9567af5c..56db292ba 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/fake-queue.h" | 37 | #include "openbsd-compat/fake-queue.h" |
38 | RCSID("$OpenBSD: ssh-agent.c,v 1.88 2002/06/05 19:57:12 markus Exp $"); | 38 | RCSID("$OpenBSD: ssh-agent.c,v 1.89 2002/06/05 21:55:44 markus Exp $"); |
39 | 39 | ||
40 | #include <openssl/evp.h> | 40 | #include <openssl/evp.h> |
41 | #include <openssl/md5.h> | 41 | #include <openssl/md5.h> |
@@ -76,6 +76,7 @@ typedef struct identity { | |||
76 | TAILQ_ENTRY(identity) next; | 76 | TAILQ_ENTRY(identity) next; |
77 | Key *key; | 77 | Key *key; |
78 | char *comment; | 78 | char *comment; |
79 | u_int death; | ||
79 | } Identity; | 80 | } Identity; |
80 | 81 | ||
81 | typedef struct { | 82 | typedef struct { |
@@ -124,6 +125,14 @@ idtab_lookup(int version) | |||
124 | return &idtable[version]; | 125 | return &idtable[version]; |
125 | } | 126 | } |
126 | 127 | ||
128 | static void | ||
129 | free_identity(Identity *id) | ||
130 | { | ||
131 | key_free(id->key); | ||
132 | xfree(id->comment); | ||
133 | xfree(id); | ||
134 | } | ||
135 | |||
127 | /* return matching private key for given public key */ | 136 | /* return matching private key for given public key */ |
128 | static Identity * | 137 | static Identity * |
129 | lookup_identity(Key *key, int version) | 138 | lookup_identity(Key *key, int version) |
@@ -138,14 +147,6 @@ lookup_identity(Key *key, int version) | |||
138 | return (NULL); | 147 | return (NULL); |
139 | } | 148 | } |
140 | 149 | ||
141 | static void | ||
142 | free_identity(Identity *id) | ||
143 | { | ||
144 | key_free(id->key); | ||
145 | xfree(id->comment); | ||
146 | xfree(id); | ||
147 | } | ||
148 | |||
149 | /* send list of supported public keys to 'client' */ | 150 | /* send list of supported public keys to 'client' */ |
150 | static void | 151 | static void |
151 | process_request_identities(SocketEntry *e, int version) | 152 | process_request_identities(SocketEntry *e, int version) |
@@ -368,6 +369,27 @@ process_remove_all_identities(SocketEntry *e, int version) | |||
368 | } | 369 | } |
369 | 370 | ||
370 | static void | 371 | static void |
372 | reaper(void) | ||
373 | { | ||
374 | Idtab *tab; | ||
375 | Identity *id, *nxt; | ||
376 | int version; | ||
377 | u_int now = time(NULL); | ||
378 | |||
379 | for (version = 1; version < 3; version++) { | ||
380 | tab = idtab_lookup(version); | ||
381 | for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { | ||
382 | nxt = TAILQ_NEXT(id, next); | ||
383 | if (id->death != 0 && now >= id->death) { | ||
384 | TAILQ_REMOVE(&tab->idlist, id, next); | ||
385 | free_identity(id); | ||
386 | tab->nentries--; | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
392 | static void | ||
371 | process_add_identity(SocketEntry *e, int version) | 393 | process_add_identity(SocketEntry *e, int version) |
372 | { | 394 | { |
373 | Key *k = NULL; | 395 | Key *k = NULL; |
@@ -433,6 +455,7 @@ process_add_identity(SocketEntry *e, int version) | |||
433 | Identity *id = xmalloc(sizeof(Identity)); | 455 | Identity *id = xmalloc(sizeof(Identity)); |
434 | id->key = k; | 456 | id->key = k; |
435 | id->comment = comment; | 457 | id->comment = comment; |
458 | id->death = 0; | ||
436 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); | 459 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
437 | /* Increment the number of identities. */ | 460 | /* Increment the number of identities. */ |
438 | tab->nentries++; | 461 | tab->nentries++; |
@@ -446,6 +469,43 @@ send: | |||
446 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | 469 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
447 | } | 470 | } |
448 | 471 | ||
472 | static void | ||
473 | process_lifetime_identity(SocketEntry *e, int version) | ||
474 | { | ||
475 | Key *key = NULL; | ||
476 | u_char *blob; | ||
477 | u_int blen, bits, death; | ||
478 | int success = 0; | ||
479 | |||
480 | death = time(NULL) + buffer_get_int(&e->request); | ||
481 | |||
482 | switch (version) { | ||
483 | case 1: | ||
484 | key = key_new(KEY_RSA1); | ||
485 | bits = buffer_get_int(&e->request); | ||
486 | buffer_get_bignum(&e->request, key->rsa->e); | ||
487 | buffer_get_bignum(&e->request, key->rsa->n); | ||
488 | |||
489 | break; | ||
490 | case 2: | ||
491 | blob = buffer_get_string(&e->request, &blen); | ||
492 | key = key_from_blob(blob, blen); | ||
493 | xfree(blob); | ||
494 | break; | ||
495 | } | ||
496 | if (key != NULL) { | ||
497 | Identity *id = lookup_identity(key, version); | ||
498 | if (id != NULL && id->death == 0) { | ||
499 | id->death = death; | ||
500 | success = 1; | ||
501 | } | ||
502 | key_free(key); | ||
503 | } | ||
504 | buffer_put_int(&e->output, 1); | ||
505 | buffer_put_char(&e->output, | ||
506 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
507 | } | ||
508 | |||
449 | /* XXX todo: encrypt sensitive data with passphrase */ | 509 | /* XXX todo: encrypt sensitive data with passphrase */ |
450 | static void | 510 | static void |
451 | process_lock_agent(SocketEntry *e, int lock) | 511 | process_lock_agent(SocketEntry *e, int lock) |
@@ -517,6 +577,7 @@ process_add_smartcard_key (SocketEntry *e) | |||
517 | id = xmalloc(sizeof(Identity)); | 577 | id = xmalloc(sizeof(Identity)); |
518 | id->key = k; | 578 | id->key = k; |
519 | id->comment = xstrdup("smartcard key"); | 579 | id->comment = xstrdup("smartcard key"); |
580 | id->death = 0; | ||
520 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); | 581 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
521 | tab->nentries++; | 582 | tab->nentries++; |
522 | success = 1; | 583 | success = 1; |
@@ -580,6 +641,10 @@ process_message(SocketEntry *e) | |||
580 | u_int msg_len; | 641 | u_int msg_len; |
581 | u_int type; | 642 | u_int type; |
582 | u_char *cp; | 643 | u_char *cp; |
644 | |||
645 | /* kill dead keys */ | ||
646 | reaper(); | ||
647 | |||
583 | if (buffer_len(&e->input) < 5) | 648 | if (buffer_len(&e->input) < 5) |
584 | return; /* Incomplete message. */ | 649 | return; /* Incomplete message. */ |
585 | cp = buffer_ptr(&e->input); | 650 | cp = buffer_ptr(&e->input); |
@@ -642,6 +707,9 @@ process_message(SocketEntry *e) | |||
642 | case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: | 707 | case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: |
643 | process_remove_all_identities(e, 1); | 708 | process_remove_all_identities(e, 1); |
644 | break; | 709 | break; |
710 | case SSH_AGENTC_LIFETIME_IDENTITY1: | ||
711 | process_lifetime_identity(e, 1); | ||
712 | break; | ||
645 | /* ssh2 */ | 713 | /* ssh2 */ |
646 | case SSH2_AGENTC_SIGN_REQUEST: | 714 | case SSH2_AGENTC_SIGN_REQUEST: |
647 | process_sign_request2(e); | 715 | process_sign_request2(e); |
@@ -658,6 +726,9 @@ process_message(SocketEntry *e) | |||
658 | case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: | 726 | case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: |
659 | process_remove_all_identities(e, 2); | 727 | process_remove_all_identities(e, 2); |
660 | break; | 728 | break; |
729 | case SSH_AGENTC_LIFETIME_IDENTITY: | ||
730 | process_lifetime_identity(e, 2); | ||
731 | break; | ||
661 | #ifdef SMARTCARD | 732 | #ifdef SMARTCARD |
662 | case SSH_AGENTC_ADD_SMARTCARD_KEY: | 733 | case SSH_AGENTC_ADD_SMARTCARD_KEY: |
663 | process_add_smartcard_key(e); | 734 | process_add_smartcard_key(e); |