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 10e4f0a08..1675f3935 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. |
@@ -581,6 +581,30 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | /* | ||
585 | * Format an identity for logging including filename, key type, fingerprint | ||
586 | * and location (agent, etc.). Caller must free. | ||
587 | */ | ||
588 | static char * | ||
589 | format_identity(Identity *id) | ||
590 | { | ||
591 | char *fp = NULL, *ret = NULL; | ||
592 | |||
593 | if (id->key != NULL) { | ||
594 | fp = sshkey_fingerprint(id->key, options.fingerprint_hash, | ||
595 | SSH_FP_DEFAULT); | ||
596 | } | ||
597 | xasprintf(&ret, "%s %s%s%s%s%s%s", | ||
598 | id->filename, | ||
599 | id->key ? sshkey_type(id->key) : "", id->key ? " " : "", | ||
600 | fp ? fp : "", | ||
601 | id->userprovided ? " explicit" : "", | ||
602 | (id->key && (id->key->flags & SSHKEY_FLAG_EXT)) ? " token" : "", | ||
603 | id->agent_fd != -1 ? " agent" : ""); | ||
604 | free(fp); | ||
605 | return ret; | ||
606 | } | ||
607 | |||
584 | /* ARGSUSED */ | 608 | /* ARGSUSED */ |
585 | int | 609 | int |
586 | input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | 610 | input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) |
@@ -588,9 +612,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
588 | Authctxt *authctxt = ssh->authctxt; | 612 | Authctxt *authctxt = ssh->authctxt; |
589 | struct sshkey *key = NULL; | 613 | struct sshkey *key = NULL; |
590 | Identity *id = NULL; | 614 | Identity *id = NULL; |
591 | int pktype, sent = 0; | 615 | int pktype, found = 0, sent = 0; |
592 | size_t blen; | 616 | size_t blen; |
593 | char *pkalg = NULL, *fp; | 617 | char *pkalg = NULL, *fp = NULL, *ident = NULL; |
594 | u_char *pkblob = NULL; | 618 | u_char *pkblob = NULL; |
595 | int r; | 619 | int r; |
596 | 620 | ||
@@ -602,10 +626,8 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
602 | (r = sshpkt_get_end(ssh)) != 0) | 626 | (r = sshpkt_get_end(ssh)) != 0) |
603 | goto done; | 627 | goto done; |
604 | 628 | ||
605 | debug("Server accepts key: pkalg %s blen %zu", pkalg, blen); | ||
606 | |||
607 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { | 629 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { |
608 | debug("unknown pkalg %s", pkalg); | 630 | debug("%s: server sent unknown pkalg %s", __func__, pkalg); |
609 | goto done; | 631 | goto done; |
610 | } | 632 | } |
611 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { | 633 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |
@@ -618,11 +640,6 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
618 | key->type, pktype); | 640 | key->type, pktype); |
619 | goto done; | 641 | goto done; |
620 | } | 642 | } |
621 | if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
622 | SSH_FP_DEFAULT)) == NULL) | ||
623 | goto done; | ||
624 | debug2("input_userauth_pk_ok: fp %s", fp); | ||
625 | free(fp); | ||
626 | 643 | ||
627 | /* | 644 | /* |
628 | * search keys in the reverse order, because last candidate has been | 645 | * search keys in the reverse order, because last candidate has been |
@@ -631,13 +648,25 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
631 | */ | 648 | */ |
632 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { | 649 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { |
633 | if (sshkey_equal(key, id->key)) { | 650 | if (sshkey_equal(key, id->key)) { |
634 | sent = sign_and_send_pubkey(ssh, authctxt, id); | 651 | found = 1; |
635 | break; | 652 | break; |
636 | } | 653 | } |
637 | } | 654 | } |
655 | if (!found || id == NULL) { | ||
656 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
657 | SSH_FP_DEFAULT); | ||
658 | error("%s: server replied with unknown key: %s %s", __func__, | ||
659 | sshkey_type(key), fp == NULL ? "<ERROR>" : fp); | ||
660 | goto done; | ||
661 | } | ||
662 | ident = format_identity(id); | ||
663 | debug("Server accepts key: %s", ident); | ||
664 | sent = sign_and_send_pubkey(ssh, authctxt, id); | ||
638 | r = 0; | 665 | r = 0; |
639 | done: | 666 | done: |
640 | sshkey_free(key); | 667 | sshkey_free(key); |
668 | free(ident); | ||
669 | free(fp); | ||
641 | free(pkalg); | 670 | free(pkalg); |
642 | free(pkblob); | 671 | free(pkblob); |
643 | 672 | ||
@@ -1059,7 +1088,8 @@ key_sig_algorithm(struct ssh *ssh, const struct sshkey *key) | |||
1059 | * newer (SHA2) algorithms. | 1088 | * newer (SHA2) algorithms. |
1060 | */ | 1089 | */ |
1061 | if (ssh == NULL || ssh->kex->server_sig_algs == NULL || | 1090 | if (ssh == NULL || ssh->kex->server_sig_algs == NULL || |
1062 | (key->type != KEY_RSA && key->type != KEY_RSA_CERT)) { | 1091 | (key->type != KEY_RSA && key->type != KEY_RSA_CERT) || |
1092 | (key->type == KEY_RSA_CERT && (datafellows & SSH_BUG_SIGTYPE))) { | ||
1063 | /* Filter base key signature alg against our configuration */ | 1093 | /* Filter base key signature alg against our configuration */ |
1064 | return match_list(sshkey_ssh_name(key), | 1094 | return match_list(sshkey_ssh_name(key), |
1065 | options.pubkey_key_types, NULL); | 1095 | options.pubkey_key_types, NULL); |
@@ -1458,6 +1488,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1458 | int agent_fd = -1, i, r, found; | 1488 | int agent_fd = -1, i, r, found; |
1459 | size_t j; | 1489 | size_t j; |
1460 | struct ssh_identitylist *idlist; | 1490 | struct ssh_identitylist *idlist; |
1491 | char *ident; | ||
1461 | 1492 | ||
1462 | TAILQ_INIT(&agent); /* keys from the agent */ | 1493 | TAILQ_INIT(&agent); /* keys from the agent */ |
1463 | TAILQ_INIT(&files); /* keys from the config file */ | 1494 | TAILQ_INIT(&files); /* keys from the config file */ |
@@ -1574,10 +1605,14 @@ pubkey_prepare(Authctxt *authctxt) | |||
1574 | memset(id, 0, sizeof(*id)); | 1605 | memset(id, 0, sizeof(*id)); |
1575 | continue; | 1606 | continue; |
1576 | } | 1607 | } |
1577 | debug2("key: %s (%p)%s%s", id->filename, id->key, | ||
1578 | id->userprovided ? ", explicit" : "", | ||
1579 | id->agent_fd != -1 ? ", agent" : ""); | ||
1580 | } | 1608 | } |
1609 | /* List the keys we plan on using */ | ||
1610 | TAILQ_FOREACH_SAFE(id, preferred, next, id2) { | ||
1611 | ident = format_identity(id); | ||
1612 | debug("Will attempt key: %s", ident); | ||
1613 | free(ident); | ||
1614 | } | ||
1615 | debug2("%s: done", __func__); | ||
1581 | } | 1616 | } |
1582 | 1617 | ||
1583 | static void | 1618 | static void |
@@ -1625,7 +1660,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1625 | struct ssh *ssh = active_state; /* XXX */ | 1660 | struct ssh *ssh = active_state; /* XXX */ |
1626 | Identity *id; | 1661 | Identity *id; |
1627 | int sent = 0; | 1662 | int sent = 0; |
1628 | char *fp; | 1663 | char *ident; |
1629 | 1664 | ||
1630 | while ((id = TAILQ_FIRST(&authctxt->keys))) { | 1665 | while ((id = TAILQ_FIRST(&authctxt->keys))) { |
1631 | if (id->tried++) | 1666 | if (id->tried++) |
@@ -1640,16 +1675,9 @@ userauth_pubkey(Authctxt *authctxt) | |||
1640 | */ | 1675 | */ |
1641 | if (id->key != NULL) { | 1676 | if (id->key != NULL) { |
1642 | if (try_identity(id)) { | 1677 | if (try_identity(id)) { |
1643 | if ((fp = sshkey_fingerprint(id->key, | 1678 | ident = format_identity(id); |
1644 | options.fingerprint_hash, | 1679 | debug("Offering public key: %s", ident); |
1645 | SSH_FP_DEFAULT)) == NULL) { | 1680 | free(ident); |
1646 | error("%s: sshkey_fingerprint failed", | ||
1647 | __func__); | ||
1648 | return 0; | ||
1649 | } | ||
1650 | debug("Offering public key: %s %s %s", | ||
1651 | sshkey_type(id->key), fp, id->filename); | ||
1652 | free(fp); | ||
1653 | sent = send_pubkey_test(ssh, authctxt, id); | 1681 | sent = send_pubkey_test(ssh, authctxt, id); |
1654 | } | 1682 | } |
1655 | } else { | 1683 | } else { |