1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Merge SSH fixes from 'pre-0.79'.

This commit is contained in:
Simon Tatham
2023-05-05 00:06:00 +01:00
9 changed files with 103 additions and 7 deletions

View File

@ -474,7 +474,8 @@ void ssh_remote_error(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
if (ssh->base_layer)
ssh_ppl_final_output(ssh->base_layer);
/* Error messages sent by the remote don't count as clean exits */
ssh->exitcode = 128;
@ -494,7 +495,8 @@ void ssh_remote_eof(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
if (ssh->base_layer)
ssh_ppl_final_output(ssh->base_layer);
/* EOF from the remote, if we were expecting it, does count as
* a clean exit */
@ -519,7 +521,8 @@ void ssh_proto_error(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
if (ssh->base_layer)
ssh_ppl_final_output(ssh->base_layer);
ssh->exitcode = 128;
@ -538,7 +541,8 @@ void ssh_sw_abort(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
if (ssh->base_layer)
ssh_ppl_final_output(ssh->base_layer);
ssh->exitcode = 128;
@ -557,7 +561,8 @@ void ssh_user_close(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
if (ssh->base_layer)
ssh_ppl_final_output(ssh->base_layer);
/* Closing the connection due to user action, even if the
* action is the user aborting during authentication prompts,

View File

@ -135,6 +135,8 @@ static void ssh2_userauth_ki_write_responses(
static void ssh2_userauth_final_output(PacketProtocolLayer *ppl);
static void ssh2_userauth_print_banner(struct ssh2_userauth_state *s);
static ptrlen workaround_rsa_sha2_cert_userauth(
struct ssh2_userauth_state *s, ptrlen id);
static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
.free = ssh2_userauth_free,
@ -2377,7 +2379,28 @@ static void ssh2_userauth_add_alg_and_publickey(
ppl_logevent("Sending public key with certificate from \"%s\"",
filename_to_str(s->detached_cert_file));
}
put_stringz(pkt, ssh_keyalg_related_alg(certalg, pkalg)->ssh_id);
{
/* Strip off any existing certificate-nature from pkalg,
* for the case where we're replacing a cert embedded in
* the key with the detached one. The second argument of
* ssh_keyalg_related_alg is expected to be one of the
* bare key algorithms, or nothing useful will happen. */
const ssh_keyalg *pkalg_base =
pkalg->base_alg ? pkalg->base_alg : pkalg;
/* Construct an algorithm string that includes both the
* signature subtype (e.g. rsa-sha2-512) and the
* certificate-ness. Exception: in earlier versions of
* OpenSSH we don't want to do that, and must send just
* ssh-rsa-cert-... even when we're delivering a non-SHA-1
* signature. */
const ssh_keyalg *output_alg =
ssh_keyalg_related_alg(certalg, pkalg_base);
ptrlen output_id = ptrlen_from_asciz(output_alg->ssh_id);
output_id = workaround_rsa_sha2_cert_userauth(s, output_id);
put_stringpl(pkt, output_id);
}
put_stringpl(pkt, ptrlen_from_strbuf(s->detached_cert_blob));
done = true;
goto out;
@ -2423,11 +2446,30 @@ static void ssh2_userauth_add_alg_and_publickey(
return;
}
/* In all other cases, just put in what we were given. */
/* In all other cases, basically just put in what we were given -
* except for the same bug workaround as above. */
alg = workaround_rsa_sha2_cert_userauth(s, alg);
put_stringpl(pkt, alg);
put_stringpl(pkt, pkblob);
}
static ptrlen workaround_rsa_sha2_cert_userauth(
struct ssh2_userauth_state *s, ptrlen id)
{
if (!(s->ppl.remote_bugs & BUG_RSA_SHA2_CERT_USERAUTH))
return id;
/*
* No need to try to do this in a general way based on the
* relations between ssh_keyalgs; we know there are a limited
* number of affected versions of OpenSSH, so this doesn't have to
* be futureproof against later additions to the family.
*/
if (ptrlen_eq_string(id, "rsa-sha2-256-cert-v01@openssh.com") ||
ptrlen_eq_string(id, "rsa-sha2-512-cert-v01@openssh.com"))
return PTRLEN_LITERAL("ssh-rsa-cert-v01@openssh.com");
return id;
}
/*
* Helper function to add an SSH-2 signature blob to a packet. Expects
* to be shown the public key blob as well as the signature blob.

View File

@ -612,6 +612,28 @@ static void ssh_detect_bugs(struct ssh_verstring_state *s)
bpp_logevent("We believe remote version requires us to "
"filter our KEXINIT");
}
if (conf_get_int(s->conf, CONF_sshbug_rsa_sha2_cert_userauth) == FORCE_ON ||
(conf_get_int(s->conf, CONF_sshbug_rsa_sha2_cert_userauth) == AUTO &&
(wc_match("OpenSSH_7.[2-7]*", imp)))) {
/*
* These versions have the bug in which using RSA/SHA-2
* authentication with a certified key requires the key
* algorithm to be sent as ssh-rsa-cert-... instead of
* rsa-sha2-NNN-cert-...
*
* OpenSSH 7.8 wants rsa-sha2-NNN-cert-...:
* https://github.com/openssh/openssh-portable/commit/4ba0d54794814ec0de1ec87987d0c3b89379b436
* (also labelled "OpenBSD-Commit-ID:
* c6e9f6d45eed8962ad502d315d7eaef32c419dde")
*
* OpenSSH 7.2 was the first release supporting RSA/SHA-2
* at all, so this bug is irrelevant to anything before that.
*/
s->remote_bugs |= BUG_RSA_SHA2_CERT_USERAUTH;
bpp_logevent("We believe remote version has SSH-2 "
"RSA/SHA-2/certificate userauth bug");
}
}
const char *ssh_verstring_get_remote(BinaryPacketProtocol *bpp)