summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ssh-agent.c151
2 files changed, 73 insertions, 83 deletions
diff --git a/ChangeLog b/ChangeLog
index 9931a8a41..a07bd21c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -152,6 +152,9 @@
152 - markus@cvs.openbsd.org 2002/01/12 13:10:29 152 - markus@cvs.openbsd.org 2002/01/12 13:10:29
153 [auth-skey.c] 153 [auth-skey.c]
154 undo local change 154 undo local change
155 - provos@cvs.openbsd.org 2002/01/13 17:27:07
156 [ssh-agent.c]
157 change to use queue.h macros; okay markus@
155 158
156 159
15720020121 16020020121
@@ -7300,4 +7303,4 @@
7300 - Wrote replacements for strlcpy and mkdtemp 7303 - Wrote replacements for strlcpy and mkdtemp
7301 - Released 1.0pre1 7304 - Released 1.0pre1
7302 7305
7303$Id: ChangeLog,v 1.1766 2002/01/22 12:25:46 djm Exp $ 7306$Id: ChangeLog,v 1.1767 2002/01/22 12:26:13 djm Exp $
diff --git a/ssh-agent.c b/ssh-agent.c
index f5849cee4..84cff1282 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.77 2001/12/29 21:56:01 stevesk Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.78 2002/01/13 17:27:07 provos Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,7 +36,8 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: ssh-agent.c,v 1.77 2001/12/29 21:56:01 stevesk Exp $"); 39#include <sys/queue.h>
40RCSID("$OpenBSD: ssh-agent.c,v 1.78 2002/01/13 17:27:07 provos Exp $");
40 41
41#include <openssl/evp.h> 42#include <openssl/evp.h>
42#include <openssl/md5.h> 43#include <openssl/md5.h>
@@ -77,14 +78,15 @@ typedef struct {
77u_int sockets_alloc = 0; 78u_int sockets_alloc = 0;
78SocketEntry *sockets = NULL; 79SocketEntry *sockets = NULL;
79 80
80typedef struct { 81typedef struct identity {
82 TAILQ_ENTRY(identity) next;
81 Key *key; 83 Key *key;
82 char *comment; 84 char *comment;
83} Identity; 85} Identity;
84 86
85typedef struct { 87typedef struct {
86 int nentries; 88 int nentries;
87 Identity *identities; 89 TAILQ_HEAD(idqueue, identity) idlist;
88} Idtab; 90} Idtab;
89 91
90/* private key table, one per protocol version */ 92/* private key table, one per protocol version */
@@ -110,7 +112,7 @@ idtab_init(void)
110{ 112{
111 int i; 113 int i;
112 for (i = 0; i <=2; i++) { 114 for (i = 0; i <=2; i++) {
113 idtable[i].identities = NULL; 115 TAILQ_INIT(&idtable[i].idlist);
114 idtable[i].nentries = 0; 116 idtable[i].nentries = 0;
115 } 117 }
116} 118}
@@ -125,19 +127,25 @@ idtab_lookup(int version)
125} 127}
126 128
127/* return matching private key for given public key */ 129/* return matching private key for given public key */
128static Key * 130static Identity *
129lookup_private_key(Key *key, int *idx, int version) 131lookup_identity(Key *key, int version)
130{ 132{
131 int i; 133 Identity *id;
134
132 Idtab *tab = idtab_lookup(version); 135 Idtab *tab = idtab_lookup(version);
133 for (i = 0; i < tab->nentries; i++) { 136 TAILQ_FOREACH(id, &tab->idlist, next) {
134 if (key_equal(key, tab->identities[i].key)) { 137 if (key_equal(key, id->key))
135 if (idx != NULL) 138 return (id);
136 *idx = i;
137 return tab->identities[i].key;
138 }
139 } 139 }
140 return NULL; 140 return (NULL);
141}
142
143static void
144free_identity(Identity *id)
145{
146 key_free(id->key);
147 xfree(id->comment);
148 xfree(id);
141} 149}
142 150
143/* send list of supported public keys to 'client' */ 151/* send list of supported public keys to 'client' */
@@ -146,14 +154,13 @@ process_request_identities(SocketEntry *e, int version)
146{ 154{
147 Idtab *tab = idtab_lookup(version); 155 Idtab *tab = idtab_lookup(version);
148 Buffer msg; 156 Buffer msg;
149 int i; 157 Identity *id;
150 158
151 buffer_init(&msg); 159 buffer_init(&msg);
152 buffer_put_char(&msg, (version == 1) ? 160 buffer_put_char(&msg, (version == 1) ?
153 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 161 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
154 buffer_put_int(&msg, tab->nentries); 162 buffer_put_int(&msg, tab->nentries);
155 for (i = 0; i < tab->nentries; i++) { 163 TAILQ_FOREACH(id, &tab->idlist, next) {
156 Identity *id = &tab->identities[i];
157 if (id->key->type == KEY_RSA1) { 164 if (id->key->type == KEY_RSA1) {
158 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 165 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
159 buffer_put_bignum(&msg, id->key->rsa->e); 166 buffer_put_bignum(&msg, id->key->rsa->e);
@@ -176,7 +183,8 @@ process_request_identities(SocketEntry *e, int version)
176static void 183static void
177process_authentication_challenge1(SocketEntry *e) 184process_authentication_challenge1(SocketEntry *e)
178{ 185{
179 Key *key, *private; 186 Identity *id;
187 Key *key;
180 BIGNUM *challenge; 188 BIGNUM *challenge;
181 int i, len; 189 int i, len;
182 Buffer msg; 190 Buffer msg;
@@ -202,8 +210,9 @@ process_authentication_challenge1(SocketEntry *e)
202 if (response_type != 1) 210 if (response_type != 1)
203 goto failure; 211 goto failure;
204 212
205 private = lookup_private_key(key, NULL, 1); 213 id = lookup_identity(key, 1);
206 if (private != NULL) { 214 if (id != NULL) {
215 Key *private = id->key;
207 /* Decrypt the challenge using the private key. */ 216 /* Decrypt the challenge using the private key. */
208 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 217 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
209 goto failure; 218 goto failure;
@@ -244,7 +253,7 @@ static void
244process_sign_request2(SocketEntry *e) 253process_sign_request2(SocketEntry *e)
245{ 254{
246 extern int datafellows; 255 extern int datafellows;
247 Key *key, *private; 256 Key *key;
248 u_char *blob, *data, *signature = NULL; 257 u_char *blob, *data, *signature = NULL;
249 u_int blen, dlen, slen = 0; 258 u_int blen, dlen, slen = 0;
250 int flags; 259 int flags;
@@ -262,9 +271,9 @@ process_sign_request2(SocketEntry *e)
262 271
263 key = key_from_blob(blob, blen); 272 key = key_from_blob(blob, blen);
264 if (key != NULL) { 273 if (key != NULL) {
265 private = lookup_private_key(key, NULL, 2); 274 Identity *id = lookup_identity(key, 2);
266 if (private != NULL) 275 if (id != NULL)
267 ok = key_sign(private, &signature, &slen, data, dlen); 276 ok = key_sign(id->key, &signature, &slen, data, dlen);
268 } 277 }
269 key_free(key); 278 key_free(key);
270 buffer_init(&msg); 279 buffer_init(&msg);
@@ -288,7 +297,7 @@ process_sign_request2(SocketEntry *e)
288static void 297static void
289process_remove_identity(SocketEntry *e, int version) 298process_remove_identity(SocketEntry *e, int version)
290{ 299{
291 Key *key = NULL, *private; 300 Key *key = NULL;
292 u_char *blob; 301 u_char *blob;
293 u_int blen; 302 u_int blen;
294 u_int bits; 303 u_int bits;
@@ -312,9 +321,8 @@ process_remove_identity(SocketEntry *e, int version)
312 break; 321 break;
313 } 322 }
314 if (key != NULL) { 323 if (key != NULL) {
315 int idx; 324 Identity *id = lookup_identity(key, version);
316 private = lookup_private_key(key, &idx, version); 325 if (id != NULL) {
317 if (private != NULL) {
318 /* 326 /*
319 * We have this key. Free the old key. Since we 327 * We have this key. Free the old key. Since we
320 * don\'t want to leave empty slots in the middle of 328 * don\'t want to leave empty slots in the middle of
@@ -323,19 +331,12 @@ process_remove_identity(SocketEntry *e, int version)
323 * of the array. 331 * of the array.
324 */ 332 */
325 Idtab *tab = idtab_lookup(version); 333 Idtab *tab = idtab_lookup(version);
326 key_free(tab->identities[idx].key);
327 xfree(tab->identities[idx].comment);
328 if (tab->nentries < 1) 334 if (tab->nentries < 1)
329 fatal("process_remove_identity: " 335 fatal("process_remove_identity: "
330 "internal error: tab->nentries %d", 336 "internal error: tab->nentries %d",
331 tab->nentries); 337 tab->nentries);
332 if (idx != tab->nentries - 1) { 338 TAILQ_REMOVE(&tab->idlist, id, next);
333 int i; 339 free_identity(id);
334 for (i = idx; i < tab->nentries - 1; i++)
335 tab->identities[i] = tab->identities[i+1];
336 }
337 tab->identities[tab->nentries - 1].key = NULL;
338 tab->identities[tab->nentries - 1].comment = NULL;
339 tab->nentries--; 340 tab->nentries--;
340 success = 1; 341 success = 1;
341 } 342 }
@@ -349,13 +350,14 @@ process_remove_identity(SocketEntry *e, int version)
349static void 350static void
350process_remove_all_identities(SocketEntry *e, int version) 351process_remove_all_identities(SocketEntry *e, int version)
351{ 352{
352 u_int i;
353 Idtab *tab = idtab_lookup(version); 353 Idtab *tab = idtab_lookup(version);
354 Identity *id;
354 355
355 /* Loop over all identities and clear the keys. */ 356 /* Loop over all identities and clear the keys. */
356 for (i = 0; i < tab->nentries; i++) { 357 for (id = TAILQ_FIRST(&tab->idlist); id;
357 key_free(tab->identities[i].key); 358 id = TAILQ_FIRST(&tab->idlist)) {
358 xfree(tab->identities[i].comment); 359 TAILQ_REMOVE(&tab->idlist, id, next);
360 free_identity(id);
359 } 361 }
360 362
361 /* Mark that there are no identities. */ 363 /* Mark that there are no identities. */
@@ -429,14 +431,11 @@ process_add_identity(SocketEntry *e, int version)
429 goto send; 431 goto send;
430 } 432 }
431 success = 1; 433 success = 1;
432 if (lookup_private_key(k, NULL, version) == NULL) { 434 if (lookup_identity(k, version) == NULL) {
433 if (tab->nentries == 0) 435 Identity *id = xmalloc(sizeof(Identity));
434 tab->identities = xmalloc(sizeof(Identity)); 436 id->key = k;
435 else 437 id->comment = comment;
436 tab->identities = xrealloc(tab->identities, 438 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
437 (tab->nentries + 1) * sizeof(Identity));
438 tab->identities[tab->nentries].key = k;
439 tab->identities[tab->nentries].comment = comment;
440 /* Increment the number of identities. */ 439 /* Increment the number of identities. */
441 tab->nentries++; 440 tab->nentries++;
442 } else { 441 } else {
@@ -471,36 +470,28 @@ process_add_smartcard_key (SocketEntry *e)
471 470
472 tab = idtab_lookup(1); 471 tab = idtab_lookup(1);
473 k->type = KEY_RSA1; 472 k->type = KEY_RSA1;
474 if (lookup_private_key(k, NULL, 1) == NULL) { 473 if (lookup_identity(k, 1) == NULL) {
475 if (tab->nentries == 0) 474 Identity *id = xmalloc(sizeof(Identity));
476 tab->identities = xmalloc(sizeof(Identity));
477 else
478 tab->identities = xrealloc(tab->identities,
479 (tab->nentries + 1) * sizeof(Identity));
480 n = key_new(KEY_RSA1); 475 n = key_new(KEY_RSA1);
481 BN_copy(n->rsa->n, k->rsa->n); 476 BN_copy(n->rsa->n, k->rsa->n);
482 BN_copy(n->rsa->e, k->rsa->e); 477 BN_copy(n->rsa->e, k->rsa->e);
483 RSA_set_method(n->rsa, sc_get_engine()); 478 RSA_set_method(n->rsa, sc_get_engine());
484 tab->identities[tab->nentries].key = n; 479 id->key = n;
485 tab->identities[tab->nentries].comment = 480 id->comment = xstrdup("rsa1 smartcard");
486 xstrdup("rsa1 smartcard"); 481 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
487 tab->nentries++; 482 tab->nentries++;
488 } 483 }
489 k->type = KEY_RSA; 484 k->type = KEY_RSA;
490 tab = idtab_lookup(2); 485 tab = idtab_lookup(2);
491 if (lookup_private_key(k, NULL, 2) == NULL) { 486 if (lookup_identity(k, 2) == NULL) {
492 if (tab->nentries == 0) 487 Identity *id = xmalloc(sizeof(Identity));
493 tab->identities = xmalloc(sizeof(Identity));
494 else
495 tab->identities = xrealloc(tab->identities,
496 (tab->nentries + 1) * sizeof(Identity));
497 n = key_new(KEY_RSA); 488 n = key_new(KEY_RSA);
498 BN_copy(n->rsa->n, k->rsa->n); 489 BN_copy(n->rsa->n, k->rsa->n);
499 BN_copy(n->rsa->e, k->rsa->e); 490 BN_copy(n->rsa->e, k->rsa->e);
500 RSA_set_method(n->rsa, sc_get_engine()); 491 RSA_set_method(n->rsa, sc_get_engine());
501 tab->identities[tab->nentries].key = n; 492 id->key = n;
502 tab->identities[tab->nentries].comment = 493 id->comment = xstrdup("rsa smartcard");
503 xstrdup("rsa smartcard"); 494 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
504 tab->nentries++; 495 tab->nentries++;
505 } 496 }
506 key_free(k); 497 key_free(k);
@@ -513,8 +504,7 @@ send:
513static void 504static void
514process_remove_smartcard_key(SocketEntry *e) 505process_remove_smartcard_key(SocketEntry *e)
515{ 506{
516 Key *k = NULL, *private; 507 Key *k = NULL;
517 int idx;
518 int success = 0; 508 int success = 0;
519 char *sc_reader_id = NULL; 509 char *sc_reader_id = NULL;
520 510
@@ -525,25 +515,22 @@ process_remove_smartcard_key(SocketEntry *e)
525 if (k == NULL) { 515 if (k == NULL) {
526 error("sc_get_pubkey failed"); 516 error("sc_get_pubkey failed");
527 } else { 517 } else {
518 Identity *id;
528 k->type = KEY_RSA1; 519 k->type = KEY_RSA1;
529 private = lookup_private_key(k, &idx, 1); 520 id = lookup_identity(k, 1);
530 if (private != NULL) { 521 if (id != NULL) {
531 Idtab *tab = idtab_lookup(1); 522 Idtab *tab = idtab_lookup(1);
532 key_free(tab->identities[idx].key); 523 TAILQ_REMOVE(&tab->idlist, id, next);
533 xfree(tab->identities[idx].comment); 524 free_identity(id);
534 if (idx != tab->nentries)
535 tab->identities[idx] = tab->identities[tab->nentries];
536 tab->nentries--; 525 tab->nentries--;
537 success = 1; 526 success = 1;
538 } 527 }
539 k->type = KEY_RSA; 528 k->type = KEY_RSA;
540 private = lookup_private_key(k, &idx, 2); 529 id = lookup_identity(k, 2);
541 if (private != NULL) { 530 if (id != NULL) {
542 Idtab *tab = idtab_lookup(2); 531 Idtab *tab = idtab_lookup(2);
543 key_free(tab->identities[idx].key); 532 TAILQ_REMOVE(&tab->idlist, id, next);
544 xfree(tab->identities[idx].comment); 533 free_identity(id);
545 if (idx != tab->nentries)
546 tab->identities[idx] = tab->identities[tab->nentries];
547 tab->nentries--; 534 tab->nentries--;
548 success = 1; 535 success = 1;
549 } 536 }