diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2002-06-05 21:55:45 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2002-06-05 21:55:45 +0000 |
commit | 9dbda282d093d20e3a0d6f696dc54d2f5f58552b (patch) | |
tree | 4c6a9e6e13e7e7ab7813adc8182b7c2ea51bfab8 | |
parent | 03fac7a82759204a9949f603d88a89385ee8a8fb (diff) |
ssh-add -t life, Set lifetime (in seconds) when adding identities; ok provos@
-rw-r--r-- | usr.bin/ssh/authfd.c | 37 | ||||
-rw-r--r-- | usr.bin/ssh/authfd.h | 7 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.1 | 6 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-add.c | 22 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-agent.c | 89 |
5 files changed, 147 insertions, 14 deletions
diff --git a/usr.bin/ssh/authfd.c b/usr.bin/ssh/authfd.c index c9c22d46d4a..0f84e321cf9 100644 --- a/usr.bin/ssh/authfd.c +++ b/usr.bin/ssh/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.50 2002/06/05 19:57:12 markus Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.51 2002/06/05 21:55:44 markus Exp $"); #include <openssl/evp.h> @@ -552,6 +552,41 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) } int +ssh_lifetime_identity(AuthenticationConnection *auth, Key *key, u_int life) +{ + Buffer msg; + int type; + u_char *blob; + u_int blen; + + buffer_init(&msg); + + if (key->type == KEY_RSA1) { + buffer_put_char(&msg, SSH_AGENTC_LIFETIME_IDENTITY1); + buffer_put_int(&msg, life); + buffer_put_int(&msg, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&msg, key->rsa->e); + buffer_put_bignum(&msg, key->rsa->n); + } else if (key->type == KEY_DSA || key->type == KEY_RSA) { + key_to_blob(key, &blob, &blen); + buffer_put_char(&msg, SSH_AGENTC_LIFETIME_IDENTITY); + buffer_put_int(&msg, life); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } else { + buffer_free(&msg); + return 0; + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +int ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin) { Buffer msg; diff --git a/usr.bin/ssh/authfd.h b/usr.bin/ssh/authfd.h index b075cfa1019..263e4b97d68 100644 --- a/usr.bin/ssh/authfd.h +++ b/usr.bin/ssh/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.25 2002/06/05 19:57:12 markus Exp $ */ +/* $OpenBSD: authfd.h,v 1.26 2002/06/05 21:55:44 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -46,6 +46,10 @@ #define SSH_AGENTC_LOCK 22 #define SSH_AGENTC_UNLOCK 23 +/* set key lifetime */ +#define SSH_AGENTC_LIFETIME_IDENTITY1 24 +#define SSH_AGENTC_LIFETIME_IDENTITY 25 + /* extended failure messages */ #define SSH2_AGENT_FAILURE 30 @@ -69,6 +73,7 @@ int ssh_get_num_identities(AuthenticationConnection *, int); Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); int ssh_add_identity(AuthenticationConnection *, Key *, const char *); +int ssh_lifetime_identity(AuthenticationConnection *, Key *, u_int); int ssh_remove_identity(AuthenticationConnection *, Key *); int ssh_remove_all_identities(AuthenticationConnection *, int); int ssh_lock_agent(AuthenticationConnection *, int, const char *); diff --git a/usr.bin/ssh/ssh-add.1 b/usr.bin/ssh/ssh-add.1 index 3f462773e0b..350d1031dcd 100644 --- a/usr.bin/ssh/ssh-add.1 +++ b/usr.bin/ssh/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.32 2002/06/05 19:57:12 markus Exp $ +.\" $OpenBSD: ssh-add.1,v 1.33 2002/06/05 21:55:44 markus Exp $ .\" .\" -*- nroff -*- .\" @@ -46,6 +46,7 @@ .Sh SYNOPSIS .Nm ssh-add .Op Fl lLdDxX +.Op Fl t Ar life .Op Ar .Nm ssh-add .Fl s Ar reader @@ -87,6 +88,9 @@ Deletes all identities from the agent. Lock the agent with a password. .It Fl X Unlock the agent. +.It Fl t Ar life +Set a maximum lifetime when adding identities to an agent. +The lifetime is specified in seconds. .It Fl s Ar reader Add key in smartcard .Ar reader . diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c index b7ecb332827..bb1942b7536 100644 --- a/usr.bin/ssh/ssh-add.c +++ b/usr.bin/ssh/ssh-add.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.55 2002/06/05 20:56:39 markus Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.56 2002/06/05 21:55:44 markus Exp $"); #include <openssl/evp.h> @@ -60,6 +60,8 @@ static char *default_files[] = { NULL }; +/* Default lifetime (0 == forever) */ +static u_int lifetime = 0; /* we keep a cache of one passphrases */ static char *pass = NULL; @@ -161,6 +163,18 @@ add_file(AuthenticationConnection *ac, const char *filename) } else fprintf(stderr, "Could not add identity: %s\n", filename); + if (ret == 0 && lifetime != 0) { + if (ssh_lifetime_identity(ac, private, lifetime)) { + fprintf(stderr, + "Lifetime set to %d seconds for: %s (%s)\n", + lifetime, filename, comment); + } else { + fprintf(stderr, + "Could not set lifetime for identity: %s\n", + filename); + } + } + xfree(comment); key_free(private); @@ -274,6 +288,7 @@ usage(void) fprintf(stderr, " -D Delete all identities.\n"); fprintf(stderr, " -x Lock agent.\n"); fprintf(stderr, " -x Unlock agent.\n"); + fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n"); #ifdef SMARTCARD fprintf(stderr, " -s reader Add key in smartcard reader.\n"); fprintf(stderr, " -e reader Remove key in smartcard reader.\n"); @@ -297,7 +312,7 @@ main(int argc, char **argv) fprintf(stderr, "Could not open a connection to your authentication agent.\n"); exit(2); } - while ((ch = getopt(argc, argv, "lLdDxXe:s:")) != -1) { + while ((ch = getopt(argc, argv, "lLdDxXe:s:t:")) != -1) { switch (ch) { case 'l': case 'L': @@ -326,6 +341,9 @@ main(int argc, char **argv) deleting = 1; sc_reader_id = optarg; break; + case 't': + lifetime = atoi(optarg); + break; default: usage(); ret = 1; diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c index 8ebfa4df66d..3e5c7a47c07 100644 --- a/usr.bin/ssh/ssh-agent.c +++ b/usr.bin/ssh/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include <sys/queue.h> -RCSID("$OpenBSD: ssh-agent.c,v 1.88 2002/06/05 19:57:12 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.89 2002/06/05 21:55:44 markus Exp $"); #include <openssl/evp.h> #include <openssl/md5.h> @@ -76,6 +76,7 @@ typedef struct identity { TAILQ_ENTRY(identity) next; Key *key; char *comment; + u_int death; } Identity; typedef struct { @@ -120,6 +121,14 @@ idtab_lookup(int version) return &idtable[version]; } +static void +free_identity(Identity *id) +{ + key_free(id->key); + xfree(id->comment); + xfree(id); +} + /* return matching private key for given public key */ static Identity * lookup_identity(Key *key, int version) @@ -134,14 +143,6 @@ lookup_identity(Key *key, int version) return (NULL); } -static void -free_identity(Identity *id) -{ - key_free(id->key); - xfree(id->comment); - xfree(id); -} - /* send list of supported public keys to 'client' */ static void process_request_identities(SocketEntry *e, int version) @@ -364,6 +365,27 @@ process_remove_all_identities(SocketEntry *e, int version) } static void +reaper(void) +{ + Idtab *tab; + Identity *id, *nxt; + int version; + u_int now = time(NULL); + + for (version = 1; version < 3; version++) { + tab = idtab_lookup(version); + for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { + nxt = TAILQ_NEXT(id, next); + if (id->death != 0 && now >= id->death) { + TAILQ_REMOVE(&tab->idlist, id, next); + free_identity(id); + tab->nentries--; + } + } + } +} + +static void process_add_identity(SocketEntry *e, int version) { Key *k = NULL; @@ -429,6 +451,7 @@ process_add_identity(SocketEntry *e, int version) Identity *id = xmalloc(sizeof(Identity)); id->key = k; id->comment = comment; + id->death = 0; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ tab->nentries++; @@ -442,6 +465,43 @@ send: success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } +static void +process_lifetime_identity(SocketEntry *e, int version) +{ + Key *key = NULL; + u_char *blob; + u_int blen, bits, death; + int success = 0; + + death = time(NULL) + buffer_get_int(&e->request); + + switch (version) { + case 1: + key = key_new(KEY_RSA1); + bits = buffer_get_int(&e->request); + buffer_get_bignum(&e->request, key->rsa->e); + buffer_get_bignum(&e->request, key->rsa->n); + + break; + case 2: + blob = buffer_get_string(&e->request, &blen); + key = key_from_blob(blob, blen); + xfree(blob); + break; + } + if (key != NULL) { + Identity *id = lookup_identity(key, version); + if (id != NULL && id->death == 0) { + id->death = death; + success = 1; + } + key_free(key); + } + buffer_put_int(&e->output, 1); + buffer_put_char(&e->output, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); +} + /* XXX todo: encrypt sensitive data with passphrase */ static void process_lock_agent(SocketEntry *e, int lock) @@ -513,6 +573,7 @@ process_add_smartcard_key (SocketEntry *e) id = xmalloc(sizeof(Identity)); id->key = k; id->comment = xstrdup("smartcard key"); + id->death = 0; TAILQ_INSERT_TAIL(&tab->idlist, id, next); tab->nentries++; success = 1; @@ -576,6 +637,10 @@ process_message(SocketEntry *e) u_int msg_len; u_int type; u_char *cp; + + /* kill dead keys */ + reaper(); + if (buffer_len(&e->input) < 5) return; /* Incomplete message. */ cp = buffer_ptr(&e->input); @@ -638,6 +703,9 @@ process_message(SocketEntry *e) case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: process_remove_all_identities(e, 1); break; + case SSH_AGENTC_LIFETIME_IDENTITY1: + process_lifetime_identity(e, 1); + break; /* ssh2 */ case SSH2_AGENTC_SIGN_REQUEST: process_sign_request2(e); @@ -654,6 +722,9 @@ process_message(SocketEntry *e) case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: process_remove_all_identities(e, 2); break; + case SSH_AGENTC_LIFETIME_IDENTITY: + process_lifetime_identity(e, 2); + break; #ifdef SMARTCARD case SSH_AGENTC_ADD_SMARTCARD_KEY: process_add_smartcard_key(e); |