#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 <openssl/evp.h>
#include <openssl/md5.h>
TAILQ_ENTRY(identity) next;
Key *key;
char *comment;
+ u_int death;
} Identity;
typedef struct {
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)
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)
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)
{
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++;
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)
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;
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);
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);
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);