diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-04-30 23:29:10 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-05-01 10:05:07 +1000 |
commit | f4a6a88ddb6dba6d2f7bfb9e2c9879fcc9633043 (patch) | |
tree | 1829ba41c2272c7e2fc7cb89de68d47dae9e90ee /ssh-agent.c | |
parent | 930e8d2827853bc2e196c20c3e000263cc87fb75 (diff) |
upstream commit
flense SSHv1 support from ssh-agent, considerably
simplifying it
ok markus
Upstream-ID: 71d772cdcefcb29f76e01252e8361e6fc2dfc365
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 252 |
1 files changed, 90 insertions, 162 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index cc3bffad8..2ef8367b9 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.220 2017/04/30 23:18:44 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.221 2017/04/30 23:29:10 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -118,13 +118,13 @@ typedef struct identity { | |||
118 | u_int confirm; | 118 | u_int confirm; |
119 | } Identity; | 119 | } Identity; |
120 | 120 | ||
121 | typedef struct { | 121 | struct idtable { |
122 | int nentries; | 122 | int nentries; |
123 | TAILQ_HEAD(idqueue, identity) idlist; | 123 | TAILQ_HEAD(idqueue, identity) idlist; |
124 | } Idtab; | 124 | }; |
125 | 125 | ||
126 | /* private key table, one per protocol version */ | 126 | /* private key table */ |
127 | Idtab idtable[3]; | 127 | struct idtable *idtab; |
128 | 128 | ||
129 | int max_fd = 0; | 129 | int max_fd = 0; |
130 | 130 | ||
@@ -171,21 +171,9 @@ close_socket(SocketEntry *e) | |||
171 | static void | 171 | static void |
172 | idtab_init(void) | 172 | idtab_init(void) |
173 | { | 173 | { |
174 | int i; | 174 | idtab = xcalloc(1, sizeof(*idtab)); |
175 | 175 | TAILQ_INIT(&idtab->idlist); | |
176 | for (i = 0; i <=2; i++) { | 176 | idtab->nentries = 0; |
177 | TAILQ_INIT(&idtable[i].idlist); | ||
178 | idtable[i].nentries = 0; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /* return private key table for requested protocol version */ | ||
183 | static Idtab * | ||
184 | idtab_lookup(int version) | ||
185 | { | ||
186 | if (version < 1 || version > 2) | ||
187 | fatal("internal error, bad protocol version %d", version); | ||
188 | return &idtable[version]; | ||
189 | } | 177 | } |
190 | 178 | ||
191 | static void | 179 | static void |
@@ -199,12 +187,11 @@ free_identity(Identity *id) | |||
199 | 187 | ||
200 | /* return matching private key for given public key */ | 188 | /* return matching private key for given public key */ |
201 | static Identity * | 189 | static Identity * |
202 | lookup_identity(struct sshkey *key, int version) | 190 | lookup_identity(struct sshkey *key) |
203 | { | 191 | { |
204 | Identity *id; | 192 | Identity *id; |
205 | 193 | ||
206 | Idtab *tab = idtab_lookup(version); | 194 | TAILQ_FOREACH(id, &idtab->idlist, next) { |
207 | TAILQ_FOREACH(id, &tab->idlist, next) { | ||
208 | if (sshkey_equal(key, id->key)) | 195 | if (sshkey_equal(key, id->key)) |
209 | return (id); | 196 | return (id); |
210 | } | 197 | } |
@@ -241,34 +228,24 @@ send_status(SocketEntry *e, int success) | |||
241 | 228 | ||
242 | /* send list of supported public keys to 'client' */ | 229 | /* send list of supported public keys to 'client' */ |
243 | static void | 230 | static void |
244 | process_request_identities(SocketEntry *e, int version) | 231 | process_request_identities(SocketEntry *e) |
245 | { | 232 | { |
246 | Idtab *tab = idtab_lookup(version); | ||
247 | Identity *id; | 233 | Identity *id; |
248 | struct sshbuf *msg; | 234 | struct sshbuf *msg; |
249 | int r; | 235 | int r; |
250 | u_char *blob; | ||
251 | size_t blen; | ||
252 | 236 | ||
253 | if ((msg = sshbuf_new()) == NULL) | 237 | if ((msg = sshbuf_new()) == NULL) |
254 | fatal("%s: sshbuf_new failed", __func__); | 238 | fatal("%s: sshbuf_new failed", __func__); |
255 | if ((r = sshbuf_put_u8(msg, (version == 1) ? | 239 | if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || |
256 | SSH_AGENT_RSA_IDENTITIES_ANSWER : | 240 | (r = sshbuf_put_u32(msg, idtab->nentries)) != 0) |
257 | SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || | ||
258 | (r = sshbuf_put_u32(msg, tab->nentries)) != 0) | ||
259 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 241 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
260 | TAILQ_FOREACH(id, &tab->idlist, next) { | 242 | TAILQ_FOREACH(id, &idtab->idlist, next) { |
261 | if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) { | 243 | if ((r = sshkey_puts(id->key, msg)) != 0 || |
262 | error("%s: sshkey_to_blob: %s", __func__, | 244 | (r = sshbuf_put_cstring(msg, id->comment)) != 0) { |
245 | error("%s: put key/comment: %s", __func__, | ||
263 | ssh_err(r)); | 246 | ssh_err(r)); |
264 | continue; | 247 | continue; |
265 | } | 248 | } |
266 | if ((r = sshbuf_put_string(msg, blob, blen)) != 0) | ||
267 | fatal("%s: buffer error: %s", | ||
268 | __func__, ssh_err(r)); | ||
269 | free(blob); | ||
270 | if ((r = sshbuf_put_cstring(msg, id->comment)) != 0) | ||
271 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
272 | } | 249 | } |
273 | if ((r = sshbuf_put_stringb(e->output, msg)) != 0) | 250 | if ((r = sshbuf_put_stringb(e->output, msg)) != 0) |
274 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 251 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -292,27 +269,24 @@ agent_decode_alg(struct sshkey *key, u_int flags) | |||
292 | static void | 269 | static void |
293 | process_sign_request2(SocketEntry *e) | 270 | process_sign_request2(SocketEntry *e) |
294 | { | 271 | { |
295 | u_char *blob, *data, *signature = NULL; | 272 | const u_char *data; |
296 | size_t blen, dlen, slen = 0; | 273 | u_char *signature = NULL; |
274 | size_t dlen, slen = 0; | ||
297 | u_int compat = 0, flags; | 275 | u_int compat = 0, flags; |
298 | int r, ok = -1; | 276 | int r, ok = -1; |
299 | struct sshbuf *msg; | 277 | struct sshbuf *msg; |
300 | struct sshkey *key; | 278 | struct sshkey *key = NULL; |
301 | struct identity *id; | 279 | struct identity *id; |
302 | 280 | ||
303 | if ((msg = sshbuf_new()) == NULL) | 281 | if ((msg = sshbuf_new()) == NULL) |
304 | fatal("%s: sshbuf_new failed", __func__); | 282 | fatal("%s: sshbuf_new failed", __func__); |
305 | if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 || | 283 | if ((r = sshkey_froms(e->request, &key)) != 0 || |
306 | (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 || | 284 | (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 || |
307 | (r = sshbuf_get_u32(e->request, &flags)) != 0) | 285 | (r = sshbuf_get_u32(e->request, &flags)) != 0) |
308 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 286 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
309 | if (flags & SSH_AGENT_OLD_SIGNATURE) | 287 | if (flags & SSH_AGENT_OLD_SIGNATURE) |
310 | compat = SSH_BUG_SIGBLOB; | 288 | compat = SSH_BUG_SIGBLOB; |
311 | if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { | 289 | if ((id = lookup_identity(key)) == NULL) { |
312 | error("%s: cannot parse key blob: %s", __func__, ssh_err(r)); | ||
313 | goto send; | ||
314 | } | ||
315 | if ((id = lookup_identity(key, 2)) == NULL) { | ||
316 | verbose("%s: %s key not found", __func__, sshkey_type(key)); | 290 | verbose("%s: %s key not found", __func__, sshkey_type(key)); |
317 | goto send; | 291 | goto send; |
318 | } | 292 | } |
@@ -340,70 +314,52 @@ process_sign_request2(SocketEntry *e) | |||
340 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 314 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
341 | 315 | ||
342 | sshbuf_free(msg); | 316 | sshbuf_free(msg); |
343 | free(data); | ||
344 | free(blob); | ||
345 | free(signature); | 317 | free(signature); |
346 | } | 318 | } |
347 | 319 | ||
348 | /* shared */ | 320 | /* shared */ |
349 | static void | 321 | static void |
350 | process_remove_identity(SocketEntry *e, int version) | 322 | process_remove_identity(SocketEntry *e) |
351 | { | 323 | { |
352 | size_t blen; | ||
353 | int r, success = 0; | 324 | int r, success = 0; |
354 | struct sshkey *key = NULL; | 325 | struct sshkey *key = NULL; |
355 | u_char *blob; | 326 | Identity *id; |
356 | 327 | ||
357 | switch (version) { | 328 | if ((r = sshkey_froms(e->request, &key)) != 0) { |
358 | case 2: | 329 | error("%s: get key: %s", __func__, ssh_err(r)); |
359 | if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0) | 330 | goto done; |
360 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
361 | if ((r = sshkey_from_blob(blob, blen, &key)) != 0) | ||
362 | error("%s: sshkey_from_blob failed: %s", | ||
363 | __func__, ssh_err(r)); | ||
364 | free(blob); | ||
365 | break; | ||
366 | } | 331 | } |
367 | if (key != NULL) { | 332 | if ((id = lookup_identity(key)) == NULL) { |
368 | Identity *id = lookup_identity(key, version); | 333 | debug("%s: key not found", __func__); |
369 | if (id != NULL) { | 334 | goto done; |
370 | /* | ||
371 | * We have this key. Free the old key. Since we | ||
372 | * don't want to leave empty slots in the middle of | ||
373 | * the array, we actually free the key there and move | ||
374 | * all the entries between the empty slot and the end | ||
375 | * of the array. | ||
376 | */ | ||
377 | Idtab *tab = idtab_lookup(version); | ||
378 | if (tab->nentries < 1) | ||
379 | fatal("process_remove_identity: " | ||
380 | "internal error: tab->nentries %d", | ||
381 | tab->nentries); | ||
382 | TAILQ_REMOVE(&tab->idlist, id, next); | ||
383 | free_identity(id); | ||
384 | tab->nentries--; | ||
385 | success = 1; | ||
386 | } | ||
387 | sshkey_free(key); | ||
388 | } | 335 | } |
336 | /* We have this key, free it. */ | ||
337 | if (idtab->nentries < 1) | ||
338 | fatal("%s: internal error: nentries %d", | ||
339 | __func__, idtab->nentries); | ||
340 | TAILQ_REMOVE(&idtab->idlist, id, next); | ||
341 | free_identity(id); | ||
342 | idtab->nentries--; | ||
343 | sshkey_free(key); | ||
344 | success = 1; | ||
345 | done: | ||
389 | send_status(e, success); | 346 | send_status(e, success); |
390 | } | 347 | } |
391 | 348 | ||
392 | static void | 349 | static void |
393 | process_remove_all_identities(SocketEntry *e, int version) | 350 | process_remove_all_identities(SocketEntry *e) |
394 | { | 351 | { |
395 | Idtab *tab = idtab_lookup(version); | ||
396 | Identity *id; | 352 | Identity *id; |
397 | 353 | ||
398 | /* Loop over all identities and clear the keys. */ | 354 | /* Loop over all identities and clear the keys. */ |
399 | for (id = TAILQ_FIRST(&tab->idlist); id; | 355 | for (id = TAILQ_FIRST(&idtab->idlist); id; |
400 | id = TAILQ_FIRST(&tab->idlist)) { | 356 | id = TAILQ_FIRST(&idtab->idlist)) { |
401 | TAILQ_REMOVE(&tab->idlist, id, next); | 357 | TAILQ_REMOVE(&idtab->idlist, id, next); |
402 | free_identity(id); | 358 | free_identity(id); |
403 | } | 359 | } |
404 | 360 | ||
405 | /* Mark that there are no identities. */ | 361 | /* Mark that there are no identities. */ |
406 | tab->nentries = 0; | 362 | idtab->nentries = 0; |
407 | 363 | ||
408 | /* Send success. */ | 364 | /* Send success. */ |
409 | send_status(e, 1); | 365 | send_status(e, 1); |
@@ -415,24 +371,19 @@ reaper(void) | |||
415 | { | 371 | { |
416 | time_t deadline = 0, now = monotime(); | 372 | time_t deadline = 0, now = monotime(); |
417 | Identity *id, *nxt; | 373 | Identity *id, *nxt; |
418 | int version; | 374 | |
419 | Idtab *tab; | 375 | for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { |
420 | 376 | nxt = TAILQ_NEXT(id, next); | |
421 | for (version = 1; version < 3; version++) { | 377 | if (id->death == 0) |
422 | tab = idtab_lookup(version); | 378 | continue; |
423 | for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { | 379 | if (now >= id->death) { |
424 | nxt = TAILQ_NEXT(id, next); | 380 | debug("expiring key '%s'", id->comment); |
425 | if (id->death == 0) | 381 | TAILQ_REMOVE(&idtab->idlist, id, next); |
426 | continue; | 382 | free_identity(id); |
427 | if (now >= id->death) { | 383 | idtab->nentries--; |
428 | debug("expiring key '%s'", id->comment); | 384 | } else |
429 | TAILQ_REMOVE(&tab->idlist, id, next); | 385 | deadline = (deadline == 0) ? id->death : |
430 | free_identity(id); | 386 | MINIMUM(deadline, id->death); |
431 | tab->nentries--; | ||
432 | } else | ||
433 | deadline = (deadline == 0) ? id->death : | ||
434 | MINIMUM(deadline, id->death); | ||
435 | } | ||
436 | } | 387 | } |
437 | if (deadline == 0 || deadline <= now) | 388 | if (deadline == 0 || deadline <= now) |
438 | return 0; | 389 | return 0; |
@@ -440,15 +391,9 @@ reaper(void) | |||
440 | return (deadline - now); | 391 | return (deadline - now); |
441 | } | 392 | } |
442 | 393 | ||
443 | /* | ||
444 | * XXX this and the corresponding serialisation function probably belongs | ||
445 | * in key.c | ||
446 | */ | ||
447 | |||
448 | static void | 394 | static void |
449 | process_add_identity(SocketEntry *e, int version) | 395 | process_add_identity(SocketEntry *e) |
450 | { | 396 | { |
451 | Idtab *tab = idtab_lookup(version); | ||
452 | Identity *id; | 397 | Identity *id; |
453 | int success = 0, confirm = 0; | 398 | int success = 0, confirm = 0; |
454 | u_int seconds; | 399 | u_int seconds; |
@@ -458,12 +403,8 @@ process_add_identity(SocketEntry *e, int version) | |||
458 | u_char ctype; | 403 | u_char ctype; |
459 | int r = SSH_ERR_INTERNAL_ERROR; | 404 | int r = SSH_ERR_INTERNAL_ERROR; |
460 | 405 | ||
461 | switch (version) { | 406 | if ((r = sshkey_private_deserialize(e->request, &k)) != 0 || |
462 | case 2: | 407 | k == NULL || |
463 | r = sshkey_private_deserialize(e->request, &k); | ||
464 | break; | ||
465 | } | ||
466 | if (r != 0 || k == NULL || | ||
467 | (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { | 408 | (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { |
468 | error("%s: decode private key: %s", __func__, ssh_err(r)); | 409 | error("%s: decode private key: %s", __func__, ssh_err(r)); |
469 | goto err; | 410 | goto err; |
@@ -499,12 +440,12 @@ process_add_identity(SocketEntry *e, int version) | |||
499 | success = 1; | 440 | success = 1; |
500 | if (lifetime && !death) | 441 | if (lifetime && !death) |
501 | death = monotime() + lifetime; | 442 | death = monotime() + lifetime; |
502 | if ((id = lookup_identity(k, version)) == NULL) { | 443 | if ((id = lookup_identity(k)) == NULL) { |
503 | id = xcalloc(1, sizeof(Identity)); | 444 | id = xcalloc(1, sizeof(Identity)); |
504 | id->key = k; | 445 | id->key = k; |
505 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); | 446 | TAILQ_INSERT_TAIL(&idtab->idlist, id, next); |
506 | /* Increment the number of identities. */ | 447 | /* Increment the number of identities. */ |
507 | tab->nentries++; | 448 | idtab->nentries++; |
508 | } else { | 449 | } else { |
509 | sshkey_free(k); | 450 | sshkey_free(k); |
510 | free(id->comment); | 451 | free(id->comment); |
@@ -565,17 +506,14 @@ process_lock_agent(SocketEntry *e, int lock) | |||
565 | } | 506 | } |
566 | 507 | ||
567 | static void | 508 | static void |
568 | no_identities(SocketEntry *e, u_int type) | 509 | no_identities(SocketEntry *e) |
569 | { | 510 | { |
570 | struct sshbuf *msg; | 511 | struct sshbuf *msg; |
571 | int r; | 512 | int r; |
572 | 513 | ||
573 | if ((msg = sshbuf_new()) == NULL) | 514 | if ((msg = sshbuf_new()) == NULL) |
574 | fatal("%s: sshbuf_new failed", __func__); | 515 | fatal("%s: sshbuf_new failed", __func__); |
575 | if ((r = sshbuf_put_u8(msg, | 516 | if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || |
576 | (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? | ||
577 | SSH_AGENT_RSA_IDENTITIES_ANSWER : | ||
578 | SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || | ||
579 | (r = sshbuf_put_u32(msg, 0)) != 0 || | 517 | (r = sshbuf_put_u32(msg, 0)) != 0 || |
580 | (r = sshbuf_put_stringb(e->output, msg)) != 0) | 518 | (r = sshbuf_put_stringb(e->output, msg)) != 0) |
581 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 519 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -587,13 +525,12 @@ static void | |||
587 | process_add_smartcard_key(SocketEntry *e) | 525 | process_add_smartcard_key(SocketEntry *e) |
588 | { | 526 | { |
589 | char *provider = NULL, *pin, canonical_provider[PATH_MAX]; | 527 | char *provider = NULL, *pin, canonical_provider[PATH_MAX]; |
590 | int r, i, version, count = 0, success = 0, confirm = 0; | 528 | int r, i, count = 0, success = 0, confirm = 0; |
591 | u_int seconds; | 529 | u_int seconds; |
592 | time_t death = 0; | 530 | time_t death = 0; |
593 | u_char type; | 531 | u_char type; |
594 | struct sshkey **keys = NULL, *k; | 532 | struct sshkey **keys = NULL, *k; |
595 | Identity *id; | 533 | Identity *id; |
596 | Idtab *tab; | ||
597 | 534 | ||
598 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || | 535 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
599 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) | 536 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) |
@@ -613,8 +550,7 @@ process_add_smartcard_key(SocketEntry *e) | |||
613 | confirm = 1; | 550 | confirm = 1; |
614 | break; | 551 | break; |
615 | default: | 552 | default: |
616 | error("process_add_smartcard_key: " | 553 | error("%s: Unknown constraint type %d", __func__, type); |
617 | "Unknown constraint type %d", type); | ||
618 | goto send; | 554 | goto send; |
619 | } | 555 | } |
620 | } | 556 | } |
@@ -635,17 +571,15 @@ process_add_smartcard_key(SocketEntry *e) | |||
635 | count = pkcs11_add_provider(canonical_provider, pin, &keys); | 571 | count = pkcs11_add_provider(canonical_provider, pin, &keys); |
636 | for (i = 0; i < count; i++) { | 572 | for (i = 0; i < count; i++) { |
637 | k = keys[i]; | 573 | k = keys[i]; |
638 | version = 2; | 574 | if (lookup_identity(k) == NULL) { |
639 | tab = idtab_lookup(version); | ||
640 | if (lookup_identity(k, version) == NULL) { | ||
641 | id = xcalloc(1, sizeof(Identity)); | 575 | id = xcalloc(1, sizeof(Identity)); |
642 | id->key = k; | 576 | id->key = k; |
643 | id->provider = xstrdup(canonical_provider); | 577 | id->provider = xstrdup(canonical_provider); |
644 | id->comment = xstrdup(canonical_provider); /* XXX */ | 578 | id->comment = xstrdup(canonical_provider); /* XXX */ |
645 | id->death = death; | 579 | id->death = death; |
646 | id->confirm = confirm; | 580 | id->confirm = confirm; |
647 | TAILQ_INSERT_TAIL(&tab->idlist, id, next); | 581 | TAILQ_INSERT_TAIL(&idtab->idlist, id, next); |
648 | tab->nentries++; | 582 | idtab->nentries++; |
649 | success = 1; | 583 | success = 1; |
650 | } else { | 584 | } else { |
651 | sshkey_free(k); | 585 | sshkey_free(k); |
@@ -663,9 +597,8 @@ static void | |||
663 | process_remove_smartcard_key(SocketEntry *e) | 597 | process_remove_smartcard_key(SocketEntry *e) |
664 | { | 598 | { |
665 | char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; | 599 | char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; |
666 | int r, version, success = 0; | 600 | int r, success = 0; |
667 | Identity *id, *nxt; | 601 | Identity *id, *nxt; |
668 | Idtab *tab; | ||
669 | 602 | ||
670 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || | 603 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
671 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) | 604 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) |
@@ -679,25 +612,21 @@ process_remove_smartcard_key(SocketEntry *e) | |||
679 | } | 612 | } |
680 | 613 | ||
681 | debug("%s: remove %.100s", __func__, canonical_provider); | 614 | debug("%s: remove %.100s", __func__, canonical_provider); |
682 | for (version = 1; version < 3; version++) { | 615 | for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { |
683 | tab = idtab_lookup(version); | 616 | nxt = TAILQ_NEXT(id, next); |
684 | for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { | 617 | /* Skip file--based keys */ |
685 | nxt = TAILQ_NEXT(id, next); | 618 | if (id->provider == NULL) |
686 | /* Skip file--based keys */ | 619 | continue; |
687 | if (id->provider == NULL) | 620 | if (!strcmp(canonical_provider, id->provider)) { |
688 | continue; | 621 | TAILQ_REMOVE(&idtab->idlist, id, next); |
689 | if (!strcmp(canonical_provider, id->provider)) { | 622 | free_identity(id); |
690 | TAILQ_REMOVE(&tab->idlist, id, next); | 623 | idtab->nentries--; |
691 | free_identity(id); | ||
692 | tab->nentries--; | ||
693 | } | ||
694 | } | 624 | } |
695 | } | 625 | } |
696 | if (pkcs11_del_provider(canonical_provider) == 0) | 626 | if (pkcs11_del_provider(canonical_provider) == 0) |
697 | success = 1; | 627 | success = 1; |
698 | else | 628 | else |
699 | error("process_remove_smartcard_key:" | 629 | error("%s: pkcs11_del_provider failed", __func__); |
700 | " pkcs11_del_provider failed"); | ||
701 | send: | 630 | send: |
702 | free(provider); | 631 | free(provider); |
703 | send_status(e, success); | 632 | send_status(e, success); |
@@ -735,10 +664,9 @@ process_message(SocketEntry *e) | |||
735 | if (locked && type != SSH_AGENTC_UNLOCK) { | 664 | if (locked && type != SSH_AGENTC_UNLOCK) { |
736 | sshbuf_reset(e->request); | 665 | sshbuf_reset(e->request); |
737 | switch (type) { | 666 | switch (type) { |
738 | case SSH_AGENTC_REQUEST_RSA_IDENTITIES: | ||
739 | case SSH2_AGENTC_REQUEST_IDENTITIES: | 667 | case SSH2_AGENTC_REQUEST_IDENTITIES: |
740 | /* send empty lists */ | 668 | /* send empty lists */ |
741 | no_identities(e, type); | 669 | no_identities(e); |
742 | break; | 670 | break; |
743 | default: | 671 | default: |
744 | /* send a fail message for all other request types */ | 672 | /* send a fail message for all other request types */ |
@@ -754,24 +682,24 @@ process_message(SocketEntry *e) | |||
754 | process_lock_agent(e, type == SSH_AGENTC_LOCK); | 682 | process_lock_agent(e, type == SSH_AGENTC_LOCK); |
755 | break; | 683 | break; |
756 | case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: | 684 | case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: |
757 | process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */ | 685 | process_remove_all_identities(e); /* safe for !WITH_SSH1 */ |
758 | break; | 686 | break; |
759 | /* ssh2 */ | 687 | /* ssh2 */ |
760 | case SSH2_AGENTC_SIGN_REQUEST: | 688 | case SSH2_AGENTC_SIGN_REQUEST: |
761 | process_sign_request2(e); | 689 | process_sign_request2(e); |
762 | break; | 690 | break; |
763 | case SSH2_AGENTC_REQUEST_IDENTITIES: | 691 | case SSH2_AGENTC_REQUEST_IDENTITIES: |
764 | process_request_identities(e, 2); | 692 | process_request_identities(e); |
765 | break; | 693 | break; |
766 | case SSH2_AGENTC_ADD_IDENTITY: | 694 | case SSH2_AGENTC_ADD_IDENTITY: |
767 | case SSH2_AGENTC_ADD_ID_CONSTRAINED: | 695 | case SSH2_AGENTC_ADD_ID_CONSTRAINED: |
768 | process_add_identity(e, 2); | 696 | process_add_identity(e); |
769 | break; | 697 | break; |
770 | case SSH2_AGENTC_REMOVE_IDENTITY: | 698 | case SSH2_AGENTC_REMOVE_IDENTITY: |
771 | process_remove_identity(e, 2); | 699 | process_remove_identity(e); |
772 | break; | 700 | break; |
773 | case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: | 701 | case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: |
774 | process_remove_all_identities(e, 2); | 702 | process_remove_all_identities(e); |
775 | break; | 703 | break; |
776 | #ifdef ENABLE_PKCS11 | 704 | #ifdef ENABLE_PKCS11 |
777 | case SSH_AGENTC_ADD_SMARTCARD_KEY: | 705 | case SSH_AGENTC_ADD_SMARTCARD_KEY: |