From 264572ccb27ddf64ed8a0fa3c3783364933e931a Mon Sep 17 00:00:00 2001 From: mouring Date: Thu, 6 Jun 2002 21:54:57 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2002/06/05 21:55:44 [authfd.c authfd.h ssh-add.1 ssh-add.c ssh-agent.c] ssh-add -t life, Set lifetime (in seconds) when adding identities; ok provos@ --- ChangeLog | 4 +++ authfd.c | 37 +++++++++++++++++++++- authfd.h | 7 ++++- ssh-add.1 | 6 +++- ssh-add.c | 22 +++++++++++-- ssh-agent.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 151 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index c61e8d14..2014276d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -117,6 +117,10 @@ - markus@cvs.openbsd.org 2002/06/05 20:56:39 [ssh-add.c] add -x/-X to usage + - markus@cvs.openbsd.org 2002/06/05 21:55:44 + [authfd.c authfd.h ssh-add.1 ssh-add.c ssh-agent.c] + ssh-add -t life, Set lifetime (in seconds) when adding identities; + ok provos@ 20020604 - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed diff --git a/authfd.c b/authfd.c index c9c22d46..0f84e321 100644 --- a/authfd.c +++ b/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 @@ -551,6 +551,41 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) return decode_reply(type); } +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) { diff --git a/authfd.h b/authfd.h index b075cfa1..263e4b97 100644 --- a/authfd.h +++ b/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 @@ -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/ssh-add.1 b/ssh-add.1 index 3f462773..350d1031 100644 --- a/ssh-add.1 +++ b/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/ssh-add.c b/ssh-add.c index 315d9401..e4aa8a52 100644 --- a/ssh-add.c +++ b/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 @@ -66,6 +66,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; @@ -167,6 +169,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); @@ -280,6 +294,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"); @@ -307,7 +322,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': @@ -336,6 +351,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/ssh-agent.c b/ssh-agent.c index d9567af5..56db292b 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/fake-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 #include @@ -76,6 +76,7 @@ typedef struct identity { TAILQ_ENTRY(identity) next; Key *key; char *comment; + u_int death; } Identity; typedef struct { @@ -124,6 +125,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) @@ -138,14 +147,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) @@ -367,6 +368,27 @@ process_remove_all_identities(SocketEntry *e, int version) return; } +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) { @@ -433,6 +455,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++; @@ -446,6 +469,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) @@ -517,6 +577,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; @@ -580,6 +641,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); @@ -642,6 +707,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); @@ -658,6 +726,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); -- 2.45.1