]> andersk Git - openssh.git/blobdiff - ssh-agent.c
- markus@cvs.openbsd.org 2002/01/25 22:07:40
[openssh.git] / ssh-agent.c
index 3e8eb06017030c2cbc7b456f9235c5c4d8e1c175..ce283c8ccdb69cca3e5e529c082f0ffd97a6d082 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-agent.c,v 1.71 2001/08/02 16:14:05 jakob Exp $    */
+/*     $OpenBSD: ssh-agent.c,v 1.79 2002/01/18 18:14:17 stevesk Exp $  */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.71 2001/08/02 16:14:05 jakob Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.79 2002/01/18 18:14:17 stevesk Exp $");
+
+#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
+#include <sys/queue.h>
+#else
+#include "openbsd-compat/fake-queue.h"
+#endif
+
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -61,11 +68,15 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.71 2001/08/02 16:14:05 jakob Exp $");
 #include "scard.h"
 #endif
 
+typedef enum {
+       AUTH_UNUSED,
+       AUTH_SOCKET,
+       AUTH_CONNECTION
+} sock_type;
+
 typedef struct {
        int fd;
-       enum {
-               AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION
-       } type;
+       sock_type type;
        Buffer input;
        Buffer output;
 } SocketEntry;
@@ -73,14 +84,15 @@ typedef struct {
 u_int sockets_alloc = 0;
 SocketEntry *sockets = NULL;
 
-typedef struct {
+typedef struct identity {
+       TAILQ_ENTRY(identity) next;
        Key *key;
        char *comment;
 } Identity;
 
 typedef struct {
        int nentries;
-       Identity *identities;
+       TAILQ_HEAD(idqueue, identity) idlist;
 } Idtab;
 
 /* private key table, one per protocol version */
@@ -105,8 +117,8 @@ static void
 idtab_init(void)
 {
        int i;
-       for (i = 0; i <=2; i++){
-               idtable[i].identities = NULL;
+       for (i = 0; i <=2; i++) {
+               TAILQ_INIT(&idtable[i].idlist);
                idtable[i].nentries = 0;
        }
 }
@@ -121,19 +133,25 @@ idtab_lookup(int version)
 }
 
 /* return matching private key for given public key */
-static Key *
-lookup_private_key(Key *key, int *idx, int version)
+static Identity *
+lookup_identity(Key *key, int version)
 {
-       int i;
+       Identity *id;
+
        Idtab *tab = idtab_lookup(version);
-       for (i = 0; i < tab->nentries; i++) {
-               if (key_equal(key, tab->identities[i].key)) {
-                       if (idx != NULL)
-                               *idx = i;
-                       return tab->identities[i].key;
-               }
+       TAILQ_FOREACH(id, &tab->idlist, next) {
+               if (key_equal(key, id->key))
+                       return (id);
        }
-       return NULL;
+       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' */
@@ -142,14 +160,13 @@ process_request_identities(SocketEntry *e, int version)
 {
        Idtab *tab = idtab_lookup(version);
        Buffer msg;
-       int i;
+       Identity *id;
 
        buffer_init(&msg);
        buffer_put_char(&msg, (version == 1) ?
            SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
        buffer_put_int(&msg, tab->nentries);
-       for (i = 0; i < tab->nentries; i++) {
-               Identity *id = &tab->identities[i];
+       TAILQ_FOREACH(id, &tab->idlist, next) {
                if (id->key->type == KEY_RSA1) {
                        buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
                        buffer_put_bignum(&msg, id->key->rsa->e);
@@ -172,7 +189,8 @@ process_request_identities(SocketEntry *e, int version)
 static void
 process_authentication_challenge1(SocketEntry *e)
 {
-       Key *key, *private;
+       Identity *id;
+       Key *key;
        BIGNUM *challenge;
        int i, len;
        Buffer msg;
@@ -182,7 +200,8 @@ process_authentication_challenge1(SocketEntry *e)
 
        buffer_init(&msg);
        key = key_new(KEY_RSA1);
-       challenge = BN_new();
+       if ((challenge = BN_new()) == NULL)
+               fatal("process_authentication_challenge1: BN_new failed");
 
        buffer_get_int(&e->input);                              /* ignored */
        buffer_get_bignum(&e->input, key->rsa->e);
@@ -192,13 +211,14 @@ process_authentication_challenge1(SocketEntry *e)
        /* Only protocol 1.1 is supported */
        if (buffer_len(&e->input) == 0)
                goto failure;
-       buffer_get(&e->input, (char *) session_id, 16);
+       buffer_get(&e->input, session_id, 16);
        response_type = buffer_get_int(&e->input);
        if (response_type != 1)
                goto failure;
 
-       private = lookup_private_key(key, NULL, 1);
-       if (private != NULL) {
+       id = lookup_identity(key, 1);
+       if (id != NULL) {
+               Key *private = id->key;
                /* Decrypt the challenge using the private key. */
                if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
                        goto failure;
@@ -239,7 +259,7 @@ static void
 process_sign_request2(SocketEntry *e)
 {
        extern int datafellows;
-       Key *key, *private;
+       Key *key;
        u_char *blob, *data, *signature = NULL;
        u_int blen, dlen, slen = 0;
        int flags;
@@ -257,9 +277,9 @@ process_sign_request2(SocketEntry *e)
 
        key = key_from_blob(blob, blen);
        if (key != NULL) {
-               private = lookup_private_key(key, NULL, 2);
-               if (private != NULL)
-                       ok = key_sign(private, &signature, &slen, data, dlen);
+               Identity *id = lookup_identity(key, 2);
+               if (id != NULL)
+                       ok = key_sign(id->key, &signature, &slen, data, dlen);
        }
        key_free(key);
        buffer_init(&msg);
@@ -283,13 +303,13 @@ process_sign_request2(SocketEntry *e)
 static void
 process_remove_identity(SocketEntry *e, int version)
 {
-       Key *key = NULL, *private;
+       Key *key = NULL;
        u_char *blob;
        u_int blen;
        u_int bits;
        int success = 0;
 
-       switch(version){
+       switch (version) {
        case 1:
                key = key_new(KEY_RSA1);
                bits = buffer_get_int(&e->input);
@@ -307,9 +327,8 @@ process_remove_identity(SocketEntry *e, int version)
                break;
        }
        if (key != NULL) {
-               int idx;
-               private = lookup_private_key(key, &idx, version);
-               if (private != NULL) {
+               Identity *id = lookup_identity(key, version);
+               if (id != NULL) {
                        /*
                         * We have this key.  Free the old key.  Since we
                         * don\'t want to leave empty slots in the middle of
@@ -318,19 +337,12 @@ process_remove_identity(SocketEntry *e, int version)
                         * of the array.
                         */
                        Idtab *tab = idtab_lookup(version);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
                        if (tab->nentries < 1)
                                fatal("process_remove_identity: "
                                    "internal error: tab->nentries %d",
                                    tab->nentries);
-                       if (idx != tab->nentries - 1) {
-                               int i;
-                               for (i = idx; i < tab->nentries - 1; i++)
-                                       tab->identities[i] = tab->identities[i+1];
-                       }
-                       tab->identities[tab->nentries - 1].key = NULL;
-                       tab->identities[tab->nentries - 1].comment = NULL;
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
@@ -344,13 +356,14 @@ process_remove_identity(SocketEntry *e, int version)
 static void
 process_remove_all_identities(SocketEntry *e, int version)
 {
-       u_int i;
        Idtab *tab = idtab_lookup(version);
+       Identity *id;
 
        /* Loop over all identities and clear the keys. */
-       for (i = 0; i < tab->nentries; i++) {
-               key_free(tab->identities[i].key);
-               xfree(tab->identities[i].comment);
+       for (id = TAILQ_FIRST(&tab->idlist); id;
+           id = TAILQ_FIRST(&tab->idlist)) {
+               TAILQ_REMOVE(&tab->idlist, id, next);
+               free_identity(id);
        }
 
        /* Mark that there are no identities. */
@@ -391,7 +404,7 @@ process_add_identity(SocketEntry *e, int version)
                type_name = buffer_get_string(&e->input, NULL);
                type = key_type_from_name(type_name);
                xfree(type_name);
-               switch(type) {
+               switch (type) {
                case KEY_DSA:
                        k = key_new_private(type);
                        buffer_get_bignum2(&e->input, k->dsa->p);
@@ -424,14 +437,11 @@ process_add_identity(SocketEntry *e, int version)
                goto send;
        }
        success = 1;
-       if (lookup_private_key(k, NULL, version) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
-               tab->identities[tab->nentries].key = k;
-               tab->identities[tab->nentries].comment = comment;
+       if (lookup_identity(k, version) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
+               id->key = k;
+               id->comment = comment;
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                /* Increment the number of identities. */
                tab->nentries++;
        } else {
@@ -453,7 +463,7 @@ process_add_smartcard_key (SocketEntry *e)
        Key *n = NULL, *k = NULL;
        char *sc_reader_id = NULL;
        int success = 0;
-       
+
        sc_reader_id = buffer_get_string(&e->input, NULL);
        k = sc_get_key(sc_reader_id);
        xfree(sc_reader_id);
@@ -466,36 +476,28 @@ process_add_smartcard_key (SocketEntry *e)
 
        tab = idtab_lookup(1);
        k->type = KEY_RSA1;
-       if (lookup_private_key(k, NULL, 1) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
+       if (lookup_identity(k, 1) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
                n = key_new(KEY_RSA1);
                BN_copy(n->rsa->n, k->rsa->n);
                BN_copy(n->rsa->e, k->rsa->e);
                RSA_set_method(n->rsa, sc_get_engine());
-               tab->identities[tab->nentries].key = n;
-               tab->identities[tab->nentries].comment =
-                   xstrdup("rsa1 smartcard");
+               id->key = n;
+               id->comment = xstrdup("rsa1 smartcard");
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                tab->nentries++;
        }
        k->type = KEY_RSA;
        tab = idtab_lookup(2);
-       if (lookup_private_key(k, NULL, 2) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
+       if (lookup_identity(k, 2) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
                n = key_new(KEY_RSA);
                BN_copy(n->rsa->n, k->rsa->n);
                BN_copy(n->rsa->e, k->rsa->e);
                RSA_set_method(n->rsa, sc_get_engine());
-               tab->identities[tab->nentries].key = n;
-               tab->identities[tab->nentries].comment =
-                   xstrdup("rsa smartcard");
+               id->key = n;
+               id->comment = xstrdup("rsa smartcard");
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                tab->nentries++;
        }
        key_free(k);
@@ -508,8 +510,7 @@ send:
 static void
 process_remove_smartcard_key(SocketEntry *e)
 {
-       Key *k = NULL, *private;
-       int idx;
+       Key *k = NULL;
        int success = 0;
        char *sc_reader_id = NULL;
 
@@ -520,25 +521,22 @@ process_remove_smartcard_key(SocketEntry *e)
        if (k == NULL) {
                error("sc_get_pubkey failed");
        } else {
+               Identity *id;
                k->type = KEY_RSA1;
-               private = lookup_private_key(k, &idx, 1);
-               if (private != NULL) {
+               id = lookup_identity(k, 1);
+               if (id != NULL) {
                        Idtab *tab = idtab_lookup(1);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
-                       if (idx != tab->nentries)
-                               tab->identities[idx] = tab->identities[tab->nentries];
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
                k->type = KEY_RSA;
-               private = lookup_private_key(k, &idx, 2);
-               if (private != NULL) {
+               id = lookup_identity(k, 2);
+               if (id != NULL) {
                        Idtab *tab = idtab_lookup(2);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
-                       if (idx != tab->nentries)
-                               tab->identities[idx] = tab->identities[tab->nentries];
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
@@ -561,7 +559,7 @@ process_message(SocketEntry *e)
        u_char *cp;
        if (buffer_len(&e->input) < 5)
                return;         /* Incomplete message. */
-       cp = (u_char *) buffer_ptr(&e->input);
+       cp = buffer_ptr(&e->input);
        msg_len = GET_32BIT(cp);
        if (msg_len > 256 * 1024) {
                shutdown(e->fd, SHUT_RDWR);
@@ -611,10 +609,10 @@ process_message(SocketEntry *e)
 #ifdef SMARTCARD
        case SSH_AGENTC_ADD_SMARTCARD_KEY:
                process_add_smartcard_key(e);
-               break; 
+               break;
        case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
                process_remove_smartcard_key(e);
-               break; 
+               break;
 #endif /* SMARTCARD */
        default:
                /* Unknown message.  Respond with failure. */
@@ -627,7 +625,7 @@ process_message(SocketEntry *e)
 }
 
 static void
-new_socket(int type, int fd)
+new_socket(sock_type type, int fd)
 {
        u_int i, old_alloc;
        if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
@@ -821,9 +819,13 @@ check_parent_exists(int sig)
 static void
 usage(void)
 {
-       fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);
-       fprintf(stderr, "Usage: %s [-c | -s] [-k] [-d] [command [args...]]\n",
+       fprintf(stderr, "Usage: %s [options] [command [args ...]]\n",
            __progname);
+       fprintf(stderr, "Options:\n");
+       fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
+       fprintf(stderr, "  -s          Generate Bourne shell commands on stdout.\n");
+       fprintf(stderr, "  -k          Kill the current agent.\n");
+       fprintf(stderr, "  -d          Debug mode.\n");
        exit(1);
 }
 
This page took 0.052101 seconds and 4 git commands to generate.