diff options
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 82 |
1 files changed, 55 insertions, 27 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index c6a1b1271..8c872a4fb 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.284 2018/08/13 02:41:05 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.288 2018/10/11 03:48:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -647,6 +647,30 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
647 | return 0; | 647 | return 0; |
648 | } | 648 | } |
649 | 649 | ||
650 | /* | ||
651 | * Format an identity for logging including filename, key type, fingerprint | ||
652 | * and location (agent, etc.). Caller must free. | ||
653 | */ | ||
654 | static char * | ||
655 | format_identity(Identity *id) | ||
656 | { | ||
657 | char *fp = NULL, *ret = NULL; | ||
658 | |||
659 | if (id->key != NULL) { | ||
660 | fp = sshkey_fingerprint(id->key, options.fingerprint_hash, | ||
661 | SSH_FP_DEFAULT); | ||
662 | } | ||
663 | xasprintf(&ret, "%s %s%s%s%s%s%s", | ||
664 | id->filename, | ||
665 | id->key ? sshkey_type(id->key) : "", id->key ? " " : "", | ||
666 | fp ? fp : "", | ||
667 | id->userprovided ? " explicit" : "", | ||
668 | (id->key && (id->key->flags & SSHKEY_FLAG_EXT)) ? " token" : "", | ||
669 | id->agent_fd != -1 ? " agent" : ""); | ||
670 | free(fp); | ||
671 | return ret; | ||
672 | } | ||
673 | |||
650 | /* ARGSUSED */ | 674 | /* ARGSUSED */ |
651 | int | 675 | int |
652 | input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | 676 | input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) |
@@ -654,9 +678,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
654 | Authctxt *authctxt = ssh->authctxt; | 678 | Authctxt *authctxt = ssh->authctxt; |
655 | struct sshkey *key = NULL; | 679 | struct sshkey *key = NULL; |
656 | Identity *id = NULL; | 680 | Identity *id = NULL; |
657 | int pktype, sent = 0; | 681 | int pktype, found = 0, sent = 0; |
658 | size_t blen; | 682 | size_t blen; |
659 | char *pkalg = NULL, *fp; | 683 | char *pkalg = NULL, *fp = NULL, *ident = NULL; |
660 | u_char *pkblob = NULL; | 684 | u_char *pkblob = NULL; |
661 | int r; | 685 | int r; |
662 | 686 | ||
@@ -668,10 +692,8 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
668 | (r = sshpkt_get_end(ssh)) != 0) | 692 | (r = sshpkt_get_end(ssh)) != 0) |
669 | goto done; | 693 | goto done; |
670 | 694 | ||
671 | debug("Server accepts key: pkalg %s blen %zu", pkalg, blen); | ||
672 | |||
673 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { | 695 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { |
674 | debug("unknown pkalg %s", pkalg); | 696 | debug("%s: server sent unknown pkalg %s", __func__, pkalg); |
675 | goto done; | 697 | goto done; |
676 | } | 698 | } |
677 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { | 699 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |
@@ -684,11 +706,6 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
684 | key->type, pktype); | 706 | key->type, pktype); |
685 | goto done; | 707 | goto done; |
686 | } | 708 | } |
687 | if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
688 | SSH_FP_DEFAULT)) == NULL) | ||
689 | goto done; | ||
690 | debug2("input_userauth_pk_ok: fp %s", fp); | ||
691 | free(fp); | ||
692 | 709 | ||
693 | /* | 710 | /* |
694 | * search keys in the reverse order, because last candidate has been | 711 | * search keys in the reverse order, because last candidate has been |
@@ -697,13 +714,25 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
697 | */ | 714 | */ |
698 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { | 715 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { |
699 | if (sshkey_equal(key, id->key)) { | 716 | if (sshkey_equal(key, id->key)) { |
700 | sent = sign_and_send_pubkey(ssh, authctxt, id); | 717 | found = 1; |
701 | break; | 718 | break; |
702 | } | 719 | } |
703 | } | 720 | } |
721 | if (!found || id == NULL) { | ||
722 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
723 | SSH_FP_DEFAULT); | ||
724 | error("%s: server replied with unknown key: %s %s", __func__, | ||
725 | sshkey_type(key), fp == NULL ? "<ERROR>" : fp); | ||
726 | goto done; | ||
727 | } | ||
728 | ident = format_identity(id); | ||
729 | debug("Server accepts key: %s", ident); | ||
730 | sent = sign_and_send_pubkey(ssh, authctxt, id); | ||
704 | r = 0; | 731 | r = 0; |
705 | done: | 732 | done: |
706 | sshkey_free(key); | 733 | sshkey_free(key); |
734 | free(ident); | ||
735 | free(fp); | ||
707 | free(pkalg); | 736 | free(pkalg); |
708 | free(pkblob); | 737 | free(pkblob); |
709 | 738 | ||
@@ -1188,7 +1217,8 @@ key_sig_algorithm(struct ssh *ssh, const struct sshkey *key) | |||
1188 | * newer (SHA2) algorithms. | 1217 | * newer (SHA2) algorithms. |
1189 | */ | 1218 | */ |
1190 | if (ssh == NULL || ssh->kex->server_sig_algs == NULL || | 1219 | if (ssh == NULL || ssh->kex->server_sig_algs == NULL || |
1191 | (key->type != KEY_RSA && key->type != KEY_RSA_CERT)) { | 1220 | (key->type != KEY_RSA && key->type != KEY_RSA_CERT) || |
1221 | (key->type == KEY_RSA_CERT && (datafellows & SSH_BUG_SIGTYPE))) { | ||
1192 | /* Filter base key signature alg against our configuration */ | 1222 | /* Filter base key signature alg against our configuration */ |
1193 | return match_list(sshkey_ssh_name(key), | 1223 | return match_list(sshkey_ssh_name(key), |
1194 | options.pubkey_key_types, NULL); | 1224 | options.pubkey_key_types, NULL); |
@@ -1587,6 +1617,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1587 | int agent_fd = -1, i, r, found; | 1617 | int agent_fd = -1, i, r, found; |
1588 | size_t j; | 1618 | size_t j; |
1589 | struct ssh_identitylist *idlist; | 1619 | struct ssh_identitylist *idlist; |
1620 | char *ident; | ||
1590 | 1621 | ||
1591 | TAILQ_INIT(&agent); /* keys from the agent */ | 1622 | TAILQ_INIT(&agent); /* keys from the agent */ |
1592 | TAILQ_INIT(&files); /* keys from the config file */ | 1623 | TAILQ_INIT(&files); /* keys from the config file */ |
@@ -1703,10 +1734,14 @@ pubkey_prepare(Authctxt *authctxt) | |||
1703 | memset(id, 0, sizeof(*id)); | 1734 | memset(id, 0, sizeof(*id)); |
1704 | continue; | 1735 | continue; |
1705 | } | 1736 | } |
1706 | debug2("key: %s (%p)%s%s", id->filename, id->key, | ||
1707 | id->userprovided ? ", explicit" : "", | ||
1708 | id->agent_fd != -1 ? ", agent" : ""); | ||
1709 | } | 1737 | } |
1738 | /* List the keys we plan on using */ | ||
1739 | TAILQ_FOREACH_SAFE(id, preferred, next, id2) { | ||
1740 | ident = format_identity(id); | ||
1741 | debug("Will attempt key: %s", ident); | ||
1742 | free(ident); | ||
1743 | } | ||
1744 | debug2("%s: done", __func__); | ||
1710 | } | 1745 | } |
1711 | 1746 | ||
1712 | static void | 1747 | static void |
@@ -1754,7 +1789,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1754 | struct ssh *ssh = active_state; /* XXX */ | 1789 | struct ssh *ssh = active_state; /* XXX */ |
1755 | Identity *id; | 1790 | Identity *id; |
1756 | int sent = 0; | 1791 | int sent = 0; |
1757 | char *fp; | 1792 | char *ident; |
1758 | 1793 | ||
1759 | while ((id = TAILQ_FIRST(&authctxt->keys))) { | 1794 | while ((id = TAILQ_FIRST(&authctxt->keys))) { |
1760 | if (id->tried++) | 1795 | if (id->tried++) |
@@ -1769,16 +1804,9 @@ userauth_pubkey(Authctxt *authctxt) | |||
1769 | */ | 1804 | */ |
1770 | if (id->key != NULL) { | 1805 | if (id->key != NULL) { |
1771 | if (try_identity(id)) { | 1806 | if (try_identity(id)) { |
1772 | if ((fp = sshkey_fingerprint(id->key, | 1807 | ident = format_identity(id); |
1773 | options.fingerprint_hash, | 1808 | debug("Offering public key: %s", ident); |
1774 | SSH_FP_DEFAULT)) == NULL) { | 1809 | free(ident); |
1775 | error("%s: sshkey_fingerprint failed", | ||
1776 | __func__); | ||
1777 | return 0; | ||
1778 | } | ||
1779 | debug("Offering public key: %s %s %s", | ||
1780 | sshkey_type(id->key), fp, id->filename); | ||
1781 | free(fp); | ||
1782 | sent = send_pubkey_test(ssh, authctxt, id); | 1810 | sent = send_pubkey_test(ssh, authctxt, id); |
1783 | } | 1811 | } |
1784 | } else { | 1812 | } else { |