diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 23:42:11 +0100 |
commit | 327155e6824b3ee13837bdde04e4eb47e147ff46 (patch) | |
tree | 8f8743122403c7a2e6ed919156711fb1520c657f /ssh-agent.c | |
parent | 0334ce32304e9ba2a10ee5ca49ca6e8ff3ba6cf4 (diff) | |
parent | 74e339b8f8936bc0d985e053a076d0c9b5e9ea51 (diff) |
* New upstream release (http://www.openssh.com/txt/release-6.3).
- sftp(1): add support for resuming partial downloads using the "reget"
command and on the sftp commandline or on the "get" commandline using
the "-a" (append) option (closes: #158590).
- ssh(1): add an "IgnoreUnknown" configuration option to selectively
suppress errors arising from unknown configuration directives (closes:
#436052).
- sftp(1): update progressmeter when data is acknowledged, not when it's
sent (partially addresses #708372).
- ssh(1): do not fatally exit when attempting to cleanup multiplexing-
created channels that are incompletely opened (closes: #651357).
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 95 |
1 files changed, 45 insertions, 50 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index b9498e6ef..c3b11729c 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.172 2011/06/03 01:37:40 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.177 2013/07/20 01:50:20 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 |
@@ -106,7 +106,7 @@ typedef struct identity { | |||
106 | Key *key; | 106 | Key *key; |
107 | char *comment; | 107 | char *comment; |
108 | char *provider; | 108 | char *provider; |
109 | u_int death; | 109 | time_t death; |
110 | u_int confirm; | 110 | u_int confirm; |
111 | } Identity; | 111 | } Identity; |
112 | 112 | ||
@@ -122,7 +122,7 @@ int max_fd = 0; | |||
122 | 122 | ||
123 | /* pid of shell == parent of agent */ | 123 | /* pid of shell == parent of agent */ |
124 | pid_t parent_pid = -1; | 124 | pid_t parent_pid = -1; |
125 | u_int parent_alive_interval = 0; | 125 | time_t parent_alive_interval = 0; |
126 | 126 | ||
127 | /* pathname and directory for AUTH_SOCKET */ | 127 | /* pathname and directory for AUTH_SOCKET */ |
128 | char socket_name[MAXPATHLEN]; | 128 | char socket_name[MAXPATHLEN]; |
@@ -134,8 +134,8 @@ char *lock_passwd = NULL; | |||
134 | 134 | ||
135 | extern char *__progname; | 135 | extern char *__progname; |
136 | 136 | ||
137 | /* Default lifetime (0 == forever) */ | 137 | /* Default lifetime in seconds (0 == forever) */ |
138 | static int lifetime = 0; | 138 | static long lifetime = 0; |
139 | 139 | ||
140 | static void | 140 | static void |
141 | close_socket(SocketEntry *e) | 141 | close_socket(SocketEntry *e) |
@@ -172,10 +172,9 @@ static void | |||
172 | free_identity(Identity *id) | 172 | free_identity(Identity *id) |
173 | { | 173 | { |
174 | key_free(id->key); | 174 | key_free(id->key); |
175 | if (id->provider != NULL) | 175 | free(id->provider); |
176 | xfree(id->provider); | 176 | free(id->comment); |
177 | xfree(id->comment); | 177 | free(id); |
178 | xfree(id); | ||
179 | } | 178 | } |
180 | 179 | ||
181 | /* return matching private key for given public key */ | 180 | /* return matching private key for given public key */ |
@@ -203,7 +202,7 @@ confirm_key(Identity *id) | |||
203 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", | 202 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", |
204 | id->comment, p)) | 203 | id->comment, p)) |
205 | ret = 0; | 204 | ret = 0; |
206 | xfree(p); | 205 | free(p); |
207 | 206 | ||
208 | return (ret); | 207 | return (ret); |
209 | } | 208 | } |
@@ -230,7 +229,7 @@ process_request_identities(SocketEntry *e, int version) | |||
230 | u_int blen; | 229 | u_int blen; |
231 | key_to_blob(id->key, &blob, &blen); | 230 | key_to_blob(id->key, &blob, &blen); |
232 | buffer_put_string(&msg, blob, blen); | 231 | buffer_put_string(&msg, blob, blen); |
233 | xfree(blob); | 232 | free(blob); |
234 | } | 233 | } |
235 | buffer_put_cstring(&msg, id->comment); | 234 | buffer_put_cstring(&msg, id->comment); |
236 | } | 235 | } |
@@ -348,10 +347,9 @@ process_sign_request2(SocketEntry *e) | |||
348 | buffer_append(&e->output, buffer_ptr(&msg), | 347 | buffer_append(&e->output, buffer_ptr(&msg), |
349 | buffer_len(&msg)); | 348 | buffer_len(&msg)); |
350 | buffer_free(&msg); | 349 | buffer_free(&msg); |
351 | xfree(data); | 350 | free(data); |
352 | xfree(blob); | 351 | free(blob); |
353 | if (signature != NULL) | 352 | free(signature); |
354 | xfree(signature); | ||
355 | datafellows = odatafellows; | 353 | datafellows = odatafellows; |
356 | } | 354 | } |
357 | 355 | ||
@@ -378,7 +376,7 @@ process_remove_identity(SocketEntry *e, int version) | |||
378 | case 2: | 376 | case 2: |
379 | blob = buffer_get_string(&e->request, &blen); | 377 | blob = buffer_get_string(&e->request, &blen); |
380 | key = key_from_blob(blob, blen); | 378 | key = key_from_blob(blob, blen); |
381 | xfree(blob); | 379 | free(blob); |
382 | break; | 380 | break; |
383 | } | 381 | } |
384 | if (key != NULL) { | 382 | if (key != NULL) { |
@@ -430,10 +428,10 @@ process_remove_all_identities(SocketEntry *e, int version) | |||
430 | } | 428 | } |
431 | 429 | ||
432 | /* removes expired keys and returns number of seconds until the next expiry */ | 430 | /* removes expired keys and returns number of seconds until the next expiry */ |
433 | static u_int | 431 | static time_t |
434 | reaper(void) | 432 | reaper(void) |
435 | { | 433 | { |
436 | u_int deadline = 0, now = time(NULL); | 434 | time_t deadline = 0, now = monotime(); |
437 | Identity *id, *nxt; | 435 | Identity *id, *nxt; |
438 | int version; | 436 | int version; |
439 | Idtab *tab; | 437 | Idtab *tab; |
@@ -465,8 +463,9 @@ process_add_identity(SocketEntry *e, int version) | |||
465 | { | 463 | { |
466 | Idtab *tab = idtab_lookup(version); | 464 | Idtab *tab = idtab_lookup(version); |
467 | Identity *id; | 465 | Identity *id; |
468 | int type, success = 0, death = 0, confirm = 0; | 466 | int type, success = 0, confirm = 0; |
469 | char *type_name, *comment; | 467 | char *type_name, *comment; |
468 | time_t death = 0; | ||
470 | Key *k = NULL; | 469 | Key *k = NULL; |
471 | #ifdef OPENSSL_HAS_ECC | 470 | #ifdef OPENSSL_HAS_ECC |
472 | BIGNUM *exponent; | 471 | BIGNUM *exponent; |
@@ -509,7 +508,7 @@ process_add_identity(SocketEntry *e, int version) | |||
509 | cert = buffer_get_string(&e->request, &len); | 508 | cert = buffer_get_string(&e->request, &len); |
510 | if ((k = key_from_blob(cert, len)) == NULL) | 509 | if ((k = key_from_blob(cert, len)) == NULL) |
511 | fatal("Certificate parse failed"); | 510 | fatal("Certificate parse failed"); |
512 | xfree(cert); | 511 | free(cert); |
513 | key_add_private(k); | 512 | key_add_private(k); |
514 | buffer_get_bignum2(&e->request, k->dsa->priv_key); | 513 | buffer_get_bignum2(&e->request, k->dsa->priv_key); |
515 | break; | 514 | break; |
@@ -520,7 +519,7 @@ process_add_identity(SocketEntry *e, int version) | |||
520 | curve = buffer_get_string(&e->request, NULL); | 519 | curve = buffer_get_string(&e->request, NULL); |
521 | if (k->ecdsa_nid != key_curve_name_to_nid(curve)) | 520 | if (k->ecdsa_nid != key_curve_name_to_nid(curve)) |
522 | fatal("%s: curve names mismatch", __func__); | 521 | fatal("%s: curve names mismatch", __func__); |
523 | xfree(curve); | 522 | free(curve); |
524 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | 523 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); |
525 | if (k->ecdsa == NULL) | 524 | if (k->ecdsa == NULL) |
526 | fatal("%s: EC_KEY_new_by_curve_name failed", | 525 | fatal("%s: EC_KEY_new_by_curve_name failed", |
@@ -551,7 +550,7 @@ process_add_identity(SocketEntry *e, int version) | |||
551 | cert = buffer_get_string(&e->request, &len); | 550 | cert = buffer_get_string(&e->request, &len); |
552 | if ((k = key_from_blob(cert, len)) == NULL) | 551 | if ((k = key_from_blob(cert, len)) == NULL) |
553 | fatal("Certificate parse failed"); | 552 | fatal("Certificate parse failed"); |
554 | xfree(cert); | 553 | free(cert); |
555 | key_add_private(k); | 554 | key_add_private(k); |
556 | if ((exponent = BN_new()) == NULL) | 555 | if ((exponent = BN_new()) == NULL) |
557 | fatal("%s: BN_new failed", __func__); | 556 | fatal("%s: BN_new failed", __func__); |
@@ -583,7 +582,7 @@ process_add_identity(SocketEntry *e, int version) | |||
583 | cert = buffer_get_string(&e->request, &len); | 582 | cert = buffer_get_string(&e->request, &len); |
584 | if ((k = key_from_blob(cert, len)) == NULL) | 583 | if ((k = key_from_blob(cert, len)) == NULL) |
585 | fatal("Certificate parse failed"); | 584 | fatal("Certificate parse failed"); |
586 | xfree(cert); | 585 | free(cert); |
587 | key_add_private(k); | 586 | key_add_private(k); |
588 | buffer_get_bignum2(&e->request, k->rsa->d); | 587 | buffer_get_bignum2(&e->request, k->rsa->d); |
589 | buffer_get_bignum2(&e->request, k->rsa->iqmp); | 588 | buffer_get_bignum2(&e->request, k->rsa->iqmp); |
@@ -591,11 +590,11 @@ process_add_identity(SocketEntry *e, int version) | |||
591 | buffer_get_bignum2(&e->request, k->rsa->q); | 590 | buffer_get_bignum2(&e->request, k->rsa->q); |
592 | break; | 591 | break; |
593 | default: | 592 | default: |
594 | xfree(type_name); | 593 | free(type_name); |
595 | buffer_clear(&e->request); | 594 | buffer_clear(&e->request); |
596 | goto send; | 595 | goto send; |
597 | } | 596 | } |
598 | xfree(type_name); | 597 | free(type_name); |
599 | break; | 598 | break; |
600 | } | 599 | } |
601 | /* enable blinding */ | 600 | /* enable blinding */ |
@@ -613,13 +612,13 @@ process_add_identity(SocketEntry *e, int version) | |||
613 | } | 612 | } |
614 | comment = buffer_get_string(&e->request, NULL); | 613 | comment = buffer_get_string(&e->request, NULL); |
615 | if (k == NULL) { | 614 | if (k == NULL) { |
616 | xfree(comment); | 615 | free(comment); |
617 | goto send; | 616 | goto send; |
618 | } | 617 | } |
619 | while (buffer_len(&e->request)) { | 618 | while (buffer_len(&e->request)) { |
620 | switch ((type = buffer_get_char(&e->request))) { | 619 | switch ((type = buffer_get_char(&e->request))) { |
621 | case SSH_AGENT_CONSTRAIN_LIFETIME: | 620 | case SSH_AGENT_CONSTRAIN_LIFETIME: |
622 | death = time(NULL) + buffer_get_int(&e->request); | 621 | death = monotime() + buffer_get_int(&e->request); |
623 | break; | 622 | break; |
624 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 623 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
625 | confirm = 1; | 624 | confirm = 1; |
@@ -627,14 +626,14 @@ process_add_identity(SocketEntry *e, int version) | |||
627 | default: | 626 | default: |
628 | error("process_add_identity: " | 627 | error("process_add_identity: " |
629 | "Unknown constraint type %d", type); | 628 | "Unknown constraint type %d", type); |
630 | xfree(comment); | 629 | free(comment); |
631 | key_free(k); | 630 | key_free(k); |
632 | goto send; | 631 | goto send; |
633 | } | 632 | } |
634 | } | 633 | } |
635 | success = 1; | 634 | success = 1; |
636 | if (lifetime && !death) | 635 | if (lifetime && !death) |
637 | death = time(NULL) + lifetime; | 636 | death = monotime() + lifetime; |
638 | if ((id = lookup_identity(k, version)) == NULL) { | 637 | if ((id = lookup_identity(k, version)) == NULL) { |
639 | id = xcalloc(1, sizeof(Identity)); | 638 | id = xcalloc(1, sizeof(Identity)); |
640 | id->key = k; | 639 | id->key = k; |
@@ -643,7 +642,7 @@ process_add_identity(SocketEntry *e, int version) | |||
643 | tab->nentries++; | 642 | tab->nentries++; |
644 | } else { | 643 | } else { |
645 | key_free(k); | 644 | key_free(k); |
646 | xfree(id->comment); | 645 | free(id->comment); |
647 | } | 646 | } |
648 | id->comment = comment; | 647 | id->comment = comment; |
649 | id->death = death; | 648 | id->death = death; |
@@ -665,7 +664,7 @@ process_lock_agent(SocketEntry *e, int lock) | |||
665 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { | 664 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { |
666 | locked = 0; | 665 | locked = 0; |
667 | memset(lock_passwd, 0, strlen(lock_passwd)); | 666 | memset(lock_passwd, 0, strlen(lock_passwd)); |
668 | xfree(lock_passwd); | 667 | free(lock_passwd); |
669 | lock_passwd = NULL; | 668 | lock_passwd = NULL; |
670 | success = 1; | 669 | success = 1; |
671 | } else if (!locked && lock) { | 670 | } else if (!locked && lock) { |
@@ -674,7 +673,7 @@ process_lock_agent(SocketEntry *e, int lock) | |||
674 | success = 1; | 673 | success = 1; |
675 | } | 674 | } |
676 | memset(passwd, 0, strlen(passwd)); | 675 | memset(passwd, 0, strlen(passwd)); |
677 | xfree(passwd); | 676 | free(passwd); |
678 | 677 | ||
679 | buffer_put_int(&e->output, 1); | 678 | buffer_put_int(&e->output, 1); |
680 | buffer_put_char(&e->output, | 679 | buffer_put_char(&e->output, |
@@ -701,7 +700,8 @@ static void | |||
701 | process_add_smartcard_key(SocketEntry *e) | 700 | process_add_smartcard_key(SocketEntry *e) |
702 | { | 701 | { |
703 | char *provider = NULL, *pin; | 702 | char *provider = NULL, *pin; |
704 | int i, type, version, count = 0, success = 0, death = 0, confirm = 0; | 703 | int i, type, version, count = 0, success = 0, confirm = 0; |
704 | time_t death = 0; | ||
705 | Key **keys = NULL, *k; | 705 | Key **keys = NULL, *k; |
706 | Identity *id; | 706 | Identity *id; |
707 | Idtab *tab; | 707 | Idtab *tab; |
@@ -712,7 +712,7 @@ process_add_smartcard_key(SocketEntry *e) | |||
712 | while (buffer_len(&e->request)) { | 712 | while (buffer_len(&e->request)) { |
713 | switch ((type = buffer_get_char(&e->request))) { | 713 | switch ((type = buffer_get_char(&e->request))) { |
714 | case SSH_AGENT_CONSTRAIN_LIFETIME: | 714 | case SSH_AGENT_CONSTRAIN_LIFETIME: |
715 | death = time(NULL) + buffer_get_int(&e->request); | 715 | death = monotime() + buffer_get_int(&e->request); |
716 | break; | 716 | break; |
717 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 717 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
718 | confirm = 1; | 718 | confirm = 1; |
@@ -724,7 +724,7 @@ process_add_smartcard_key(SocketEntry *e) | |||
724 | } | 724 | } |
725 | } | 725 | } |
726 | if (lifetime && !death) | 726 | if (lifetime && !death) |
727 | death = time(NULL) + lifetime; | 727 | death = monotime() + lifetime; |
728 | 728 | ||
729 | count = pkcs11_add_provider(provider, pin, &keys); | 729 | count = pkcs11_add_provider(provider, pin, &keys); |
730 | for (i = 0; i < count; i++) { | 730 | for (i = 0; i < count; i++) { |
@@ -747,12 +747,9 @@ process_add_smartcard_key(SocketEntry *e) | |||
747 | keys[i] = NULL; | 747 | keys[i] = NULL; |
748 | } | 748 | } |
749 | send: | 749 | send: |
750 | if (pin) | 750 | free(pin); |
751 | xfree(pin); | 751 | free(provider); |
752 | if (provider) | 752 | free(keys); |
753 | xfree(provider); | ||
754 | if (keys) | ||
755 | xfree(keys); | ||
756 | buffer_put_int(&e->output, 1); | 753 | buffer_put_int(&e->output, 1); |
757 | buffer_put_char(&e->output, | 754 | buffer_put_char(&e->output, |
758 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | 755 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
@@ -768,7 +765,7 @@ process_remove_smartcard_key(SocketEntry *e) | |||
768 | 765 | ||
769 | provider = buffer_get_string(&e->request, NULL); | 766 | provider = buffer_get_string(&e->request, NULL); |
770 | pin = buffer_get_string(&e->request, NULL); | 767 | pin = buffer_get_string(&e->request, NULL); |
771 | xfree(pin); | 768 | free(pin); |
772 | 769 | ||
773 | for (version = 1; version < 3; version++) { | 770 | for (version = 1; version < 3; version++) { |
774 | tab = idtab_lookup(version); | 771 | tab = idtab_lookup(version); |
@@ -786,7 +783,7 @@ process_remove_smartcard_key(SocketEntry *e) | |||
786 | else | 783 | else |
787 | error("process_remove_smartcard_key:" | 784 | error("process_remove_smartcard_key:" |
788 | " pkcs11_del_provider failed"); | 785 | " pkcs11_del_provider failed"); |
789 | xfree(provider); | 786 | free(provider); |
790 | buffer_put_int(&e->output, 1); | 787 | buffer_put_int(&e->output, 1); |
791 | buffer_put_char(&e->output, | 788 | buffer_put_char(&e->output, |
792 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | 789 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
@@ -931,9 +928,10 @@ static int | |||
931 | prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, | 928 | prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, |
932 | struct timeval **tvpp) | 929 | struct timeval **tvpp) |
933 | { | 930 | { |
934 | u_int i, sz, deadline; | 931 | u_int i, sz; |
935 | int n = 0; | 932 | int n = 0; |
936 | static struct timeval tv; | 933 | static struct timeval tv; |
934 | time_t deadline; | ||
937 | 935 | ||
938 | for (i = 0; i < sockets_alloc; i++) { | 936 | for (i = 0; i < sockets_alloc; i++) { |
939 | switch (sockets[i].type) { | 937 | switch (sockets[i].type) { |
@@ -951,10 +949,8 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, | |||
951 | 949 | ||
952 | sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); | 950 | sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); |
953 | if (*fdrp == NULL || sz > *nallocp) { | 951 | if (*fdrp == NULL || sz > *nallocp) { |
954 | if (*fdrp) | 952 | free(*fdrp); |
955 | xfree(*fdrp); | 953 | free(*fdwp); |
956 | if (*fdwp) | ||
957 | xfree(*fdwp); | ||
958 | *fdrp = xmalloc(sz); | 954 | *fdrp = xmalloc(sz); |
959 | *fdwp = xmalloc(sz); | 955 | *fdwp = xmalloc(sz); |
960 | *nallocp = sz; | 956 | *nallocp = sz; |
@@ -1348,9 +1344,8 @@ skip: | |||
1348 | if (ac > 0) | 1344 | if (ac > 0) |
1349 | parent_alive_interval = 10; | 1345 | parent_alive_interval = 10; |
1350 | idtab_init(); | 1346 | idtab_init(); |
1351 | if (!d_flag) | ||
1352 | signal(SIGINT, SIG_IGN); | ||
1353 | signal(SIGPIPE, SIG_IGN); | 1347 | signal(SIGPIPE, SIG_IGN); |
1348 | signal(SIGINT, d_flag ? cleanup_handler : SIG_IGN); | ||
1354 | signal(SIGHUP, cleanup_handler); | 1349 | signal(SIGHUP, cleanup_handler); |
1355 | signal(SIGTERM, cleanup_handler); | 1350 | signal(SIGTERM, cleanup_handler); |
1356 | nalloc = 0; | 1351 | nalloc = 0; |