diff options
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index 0c6c36592..2a4578b03 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.224 2017/07/24 04:34:28 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.228 2018/02/23 15:58:37 markus 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 |
@@ -245,7 +245,8 @@ process_request_identities(SocketEntry *e) | |||
245 | (r = sshbuf_put_u32(msg, idtab->nentries)) != 0) | 245 | (r = sshbuf_put_u32(msg, idtab->nentries)) != 0) |
246 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 246 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
247 | TAILQ_FOREACH(id, &idtab->idlist, next) { | 247 | TAILQ_FOREACH(id, &idtab->idlist, next) { |
248 | if ((r = sshkey_puts(id->key, msg)) != 0 || | 248 | if ((r = sshkey_puts_opts(id->key, msg, SSHKEY_SERIALIZE_INFO)) |
249 | != 0 || | ||
249 | (r = sshbuf_put_cstring(msg, id->comment)) != 0) { | 250 | (r = sshbuf_put_cstring(msg, id->comment)) != 0) { |
250 | error("%s: put key/comment: %s", __func__, | 251 | error("%s: put key/comment: %s", __func__, |
251 | ssh_err(r)); | 252 | ssh_err(r)); |
@@ -287,10 +288,11 @@ process_sign_request2(SocketEntry *e) | |||
287 | fatal("%s: sshbuf_new failed", __func__); | 288 | fatal("%s: sshbuf_new failed", __func__); |
288 | if ((r = sshkey_froms(e->request, &key)) != 0 || | 289 | if ((r = sshkey_froms(e->request, &key)) != 0 || |
289 | (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 || | 290 | (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 || |
290 | (r = sshbuf_get_u32(e->request, &flags)) != 0) | 291 | (r = sshbuf_get_u32(e->request, &flags)) != 0) { |
291 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 292 | error("%s: couldn't parse request: %s", __func__, ssh_err(r)); |
292 | if (flags & SSH_AGENT_OLD_SIGNATURE) | 293 | goto send; |
293 | compat = SSH_BUG_SIGBLOB; | 294 | } |
295 | |||
294 | if ((id = lookup_identity(key)) == NULL) { | 296 | if ((id = lookup_identity(key)) == NULL) { |
295 | verbose("%s: %s key not found", __func__, sshkey_type(key)); | 297 | verbose("%s: %s key not found", __func__, sshkey_type(key)); |
296 | goto send; | 298 | goto send; |
@@ -401,7 +403,7 @@ process_add_identity(SocketEntry *e) | |||
401 | { | 403 | { |
402 | Identity *id; | 404 | Identity *id; |
403 | int success = 0, confirm = 0; | 405 | int success = 0, confirm = 0; |
404 | u_int seconds; | 406 | u_int seconds, maxsign; |
405 | char *comment = NULL; | 407 | char *comment = NULL; |
406 | time_t death = 0; | 408 | time_t death = 0; |
407 | struct sshkey *k = NULL; | 409 | struct sshkey *k = NULL; |
@@ -432,6 +434,18 @@ process_add_identity(SocketEntry *e) | |||
432 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 434 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
433 | confirm = 1; | 435 | confirm = 1; |
434 | break; | 436 | break; |
437 | case SSH_AGENT_CONSTRAIN_MAXSIGN: | ||
438 | if ((r = sshbuf_get_u32(e->request, &maxsign)) != 0) { | ||
439 | error("%s: bad maxsign constraint: %s", | ||
440 | __func__, ssh_err(r)); | ||
441 | goto err; | ||
442 | } | ||
443 | if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) { | ||
444 | error("%s: cannot enable maxsign: %s", | ||
445 | __func__, ssh_err(r)); | ||
446 | goto err; | ||
447 | } | ||
448 | break; | ||
435 | default: | 449 | default: |
436 | error("%s: Unknown constraint %d", __func__, ctype); | 450 | error("%s: Unknown constraint %d", __func__, ctype); |
437 | err: | 451 | err: |
@@ -447,14 +461,15 @@ process_add_identity(SocketEntry *e) | |||
447 | death = monotime() + lifetime; | 461 | death = monotime() + lifetime; |
448 | if ((id = lookup_identity(k)) == NULL) { | 462 | if ((id = lookup_identity(k)) == NULL) { |
449 | id = xcalloc(1, sizeof(Identity)); | 463 | id = xcalloc(1, sizeof(Identity)); |
450 | id->key = k; | ||
451 | TAILQ_INSERT_TAIL(&idtab->idlist, id, next); | 464 | TAILQ_INSERT_TAIL(&idtab->idlist, id, next); |
452 | /* Increment the number of identities. */ | 465 | /* Increment the number of identities. */ |
453 | idtab->nentries++; | 466 | idtab->nentries++; |
454 | } else { | 467 | } else { |
455 | sshkey_free(k); | 468 | /* key state might have been updated */ |
469 | sshkey_free(id->key); | ||
456 | free(id->comment); | 470 | free(id->comment); |
457 | } | 471 | } |
472 | id->key = k; | ||
458 | id->comment = comment; | 473 | id->comment = comment; |
459 | id->death = death; | 474 | id->death = death; |
460 | id->confirm = confirm; | 475 | id->confirm = confirm; |
@@ -472,6 +487,11 @@ process_lock_agent(SocketEntry *e, int lock) | |||
472 | static u_int fail_count = 0; | 487 | static u_int fail_count = 0; |
473 | size_t pwlen; | 488 | size_t pwlen; |
474 | 489 | ||
490 | /* | ||
491 | * This is deliberately fatal: the user has requested that we lock, | ||
492 | * but we can't parse their request properly. The only safe thing to | ||
493 | * do is abort. | ||
494 | */ | ||
475 | if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0) | 495 | if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0) |
476 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 496 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
477 | if (pwlen == 0) { | 497 | if (pwlen == 0) { |
@@ -529,7 +549,7 @@ no_identities(SocketEntry *e) | |||
529 | static void | 549 | static void |
530 | process_add_smartcard_key(SocketEntry *e) | 550 | process_add_smartcard_key(SocketEntry *e) |
531 | { | 551 | { |
532 | char *provider = NULL, *pin, canonical_provider[PATH_MAX]; | 552 | char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; |
533 | int r, i, count = 0, success = 0, confirm = 0; | 553 | int r, i, count = 0, success = 0, confirm = 0; |
534 | u_int seconds; | 554 | u_int seconds; |
535 | time_t death = 0; | 555 | time_t death = 0; |
@@ -538,17 +558,23 @@ process_add_smartcard_key(SocketEntry *e) | |||
538 | Identity *id; | 558 | Identity *id; |
539 | 559 | ||
540 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || | 560 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
541 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) | 561 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { |
542 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 562 | error("%s: buffer error: %s", __func__, ssh_err(r)); |
563 | goto send; | ||
564 | } | ||
543 | 565 | ||
544 | while (sshbuf_len(e->request)) { | 566 | while (sshbuf_len(e->request)) { |
545 | if ((r = sshbuf_get_u8(e->request, &type)) != 0) | 567 | if ((r = sshbuf_get_u8(e->request, &type)) != 0) { |
546 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 568 | error("%s: buffer error: %s", __func__, ssh_err(r)); |
569 | goto send; | ||
570 | } | ||
547 | switch (type) { | 571 | switch (type) { |
548 | case SSH_AGENT_CONSTRAIN_LIFETIME: | 572 | case SSH_AGENT_CONSTRAIN_LIFETIME: |
549 | if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) | 573 | if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) { |
550 | fatal("%s: buffer error: %s", | 574 | error("%s: buffer error: %s", |
551 | __func__, ssh_err(r)); | 575 | __func__, ssh_err(r)); |
576 | goto send; | ||
577 | } | ||
552 | death = monotime() + seconds; | 578 | death = monotime() + seconds; |
553 | break; | 579 | break; |
554 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 580 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
@@ -606,8 +632,10 @@ process_remove_smartcard_key(SocketEntry *e) | |||
606 | Identity *id, *nxt; | 632 | Identity *id, *nxt; |
607 | 633 | ||
608 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || | 634 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
609 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) | 635 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { |
610 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 636 | error("%s: buffer error: %s", __func__, ssh_err(r)); |
637 | goto send; | ||
638 | } | ||
611 | free(pin); | 639 | free(pin); |
612 | 640 | ||
613 | if (realpath(provider, canonical_provider) == NULL) { | 641 | if (realpath(provider, canonical_provider) == NULL) { |