1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-03-22 06:38:37 -05:00

Stop supporting fallback between SSH versions.

The UI now only has "1" and "2" options for SSH protocol version, which
behave like the old "1 only" and "2 only" options; old
SSH-N-with-fallback settings are interpreted as SSH-N-only.

This prevents any attempt at a protocol downgrade attack.
Most users should see no difference; those poor souls who still have to
work with SSH-1 equipment now have to explicitly opt in.
This commit is contained in:
Jacob Nevins 2016-03-28 20:23:57 +01:00
parent 43f1aa01cd
commit 16dfefcbde
9 changed files with 90 additions and 43 deletions

View File

@ -2248,14 +2248,12 @@ void setup_config_box(struct controlbox *b, int midsession,
if (!midsession) { if (!midsession) {
s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options"); s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
ctrl_radiobuttons(s, "Preferred SSH protocol version:", NO_SHORTCUT, 4, ctrl_radiobuttons(s, "SSH protocol version:", NO_SHORTCUT, 2,
HELPCTX(ssh_protocol), HELPCTX(ssh_protocol),
conf_radiobutton_handler, conf_radiobutton_handler,
I(CONF_sshprot), I(CONF_sshprot),
"1 only", 'l', I(0), "2", '2', I(3),
"1", '1', I(1), "1 (INSECURE)", '1', I(0), NULL);
"2", '2', I(2),
"2 only", 'y', I(3), NULL);
} }
/* /*

View File

@ -1667,7 +1667,7 @@ Keepalives are only supported in Telnet and SSH; the Rlogin and Raw
protocols offer no way of implementing them. (For an alternative, see protocols offer no way of implementing them. (For an alternative, see
\k{config-tcp-keepalives}.) \k{config-tcp-keepalives}.)
Note that if you are using \i{SSH-1} and the server has a bug that makes Note that if you are using SSH-1 and the server has a bug that makes
it unable to deal with SSH-1 ignore messages (see it unable to deal with SSH-1 ignore messages (see
\k{config-ssh-bug-ignore1}), enabling keepalives will have no effect. \k{config-ssh-bug-ignore1}), enabling keepalives will have no effect.
@ -2267,30 +2267,28 @@ client end. Likewise, data sent by PuTTY to the server is compressed
first and the server decompresses it at the other end. This can help first and the server decompresses it at the other end. This can help
make the most of a low-\i{bandwidth} connection. make the most of a low-\i{bandwidth} connection.
\S{config-ssh-prot} \q{Preferred \i{SSH protocol version}} \S{config-ssh-prot} \q{\i{SSH protocol version}}
\cfg{winhelp-topic}{ssh.protocol} \cfg{winhelp-topic}{ssh.protocol}
This allows you to select whether you would prefer to use \i{SSH protocol This allows you to select whether to use \i{SSH protocol version 2}
version 1} or \I{SSH-2}version 2, and whether to permit falling back or the older \I{SSH-1}version 1.
to the other version.
With the settings \q{1} and \q{2}, PuTTY will attempt to use protocol 1 You should normally leave this at the default of \q{2}. As well as
if the server you connect to does not offer protocol 2, and vice versa. having fewer features, the older SSH-1 protocol is no longer
developed, has many known cryptographic weaknesses, and is generally
not considered to be secure. PuTTY's protocol 1 implementation is
provided mainly for compatibility, and is no longer being enhanced.
If you select \q{1 only} or \q{2 only} here, PuTTY will only connect If a server offers both versions, prefer \q{2}. If you have some
if the server you connect to offers the SSH protocol version you server or piece of equipment that only talks SSH-1, select \q{1}
have specified. here, and do not treat the resulting connection as secure.
You should normally leave this at the default, \q{2 only}. The older PuTTY will not automatically fall back to the other version of the
SSH-1 protocol is no longer developed, has many known cryptographic protocol if the server turns out not to match your selection here;
weaknesses, and is generally not considered to be secure. If you instead, it will put up an error message and abort the connection.
permit use of SSH-1 by selecting \q{2} instead of \q{2 only}, an This prevents an active attacker downgrading an intended SSH-2
active attacker can force downgrade to SSH-1 even if the server connection to SSH-1.
you're connecting to supports SSH-2.
PuTTY's protocol 1 implementation is provided mainly for
compatibility, and is no longer being enhanced.
\S{config-ssh-sharing} Sharing an SSH connection between PuTTY tools \S{config-ssh-sharing} Sharing an SSH connection between PuTTY tools

View File

@ -56,6 +56,25 @@ in the same way as you would if it was new.
See \k{gs-hostkey} for more information on host keys. See \k{gs-hostkey} for more information on host keys.
\H{errors-ssh-protocol} \q{SSH protocol version 2 required by our
configuration but server only provides (old, insecure) SSH-1}
By default, PuTTY only supports connecting to SSH servers that
implement \i{SSH protocol version 2}. If you see this message, the
server you're trying to connect to only supports the older SSH-1
protocol.
If the server genuinely only supports SSH-1, then you need to either
change the \q{SSH protocol version} setting (see \k{config-ssh-prot}),
or use the \c{-1} command-line option; in any case, you should not
treat the resulting connection as secure.
You might start seeing this message with new versions of PuTTY
\#{XXX-REVIEW-BEFORE-RELEASE: (from 0.XX onwards)}
where you didn't before, because it used to be possible to configure
PuTTY to automatically fall back from SSH-2 to SSH-1. This is no
longer supported, to prevent the possibility of a downgrade attack.
\H{errors-cipher-warning} \q{The first cipher supported by the server is \H{errors-cipher-warning} \q{The first cipher supported by the server is
... below the configured warning threshold} ... below the configured warning threshold}

View File

@ -64,7 +64,11 @@ files into PuTTY's format.
Yes. SSH-1 support has always been available in PuTTY. Yes. SSH-1 support has always been available in PuTTY.
However, the SSH-1 protocol has many weaknesses and is no longer However, the SSH-1 protocol has many weaknesses and is no longer
considered secure; it should be avoided if at all possible. considered secure; you should use SSH-2 instead if at all possible.
\#{XXX-REVIEW-BEFORE-RELEASE:
As of 0.68, PuTTY will no longer fall back to SSH-1 if the server
doesn't appear to support SSH-2; you must explicitly ask for SSH-1. }
\S{faq-localecho}{Question} Does PuTTY support \i{local echo}? \S{faq-localecho}{Question} Does PuTTY support \i{local echo}?

View File

@ -59,7 +59,6 @@ from SSH and Telnet
\IM{security hazard}{security risk} security hazard \IM{security hazard}{security risk} security hazard
\IM{SSH-1}{SSH protocol version 1} SSH-1
\IM{SSH-2}{SSH protocol version 2} SSH-2 \IM{SSH-2}{SSH protocol version 2} SSH-2
\IM{terminal window}{PuTTY window} terminal window \IM{terminal window}{PuTTY window} terminal window

View File

@ -900,9 +900,8 @@ The \c{-1} and \c{-2} options force PuTTY to use version \I{SSH-1}1
or version \I{SSH-2}2 of the SSH protocol. These options are only or version \I{SSH-2}2 of the SSH protocol. These options are only
meaningful if you are using SSH. meaningful if you are using SSH.
These options are equivalent to selecting your preferred SSH These options are equivalent to selecting the SSH protocol version in
protocol version as \q{1 only} or \q{2 only} in the SSH panel of the the SSH panel of the PuTTY configuration box (see \k{config-ssh-prot}).
PuTTY configuration box (see \k{config-ssh-prot}).
\S2{using-cmdline-ipversion} \i\c{-4} and \i\c{-6}: specify an \S2{using-cmdline-ipversion} \i\c{-4} and \i\c{-6}: specify an
\i{Internet protocol version} \i{Internet protocol version}

15
putty.h
View File

@ -715,7 +715,20 @@ void cleanup_exit(int);
X(INT, NONE, change_username) /* allow username switching in SSH-2 */ \ X(INT, NONE, change_username) /* allow username switching in SSH-2 */ \
X(INT, INT, ssh_cipherlist) \ X(INT, INT, ssh_cipherlist) \
X(FILENAME, NONE, keyfile) \ X(FILENAME, NONE, keyfile) \
X(INT, NONE, sshprot) /* use v1 or v2 when both available */ \ /* \
* Which SSH protocol to use. \
* For historical reasons, the current legal values for CONF_sshprot \
* are: \
* 0 = SSH-1 only \
* 3 = SSH-2 only \
* We used to also support \
* 1 = SSH-1 with fallback to SSH-2 \
* 2 = SSH-2 with fallback to SSH-1 \
* and we continue to use 0/3 in storage formats rather than the more \
* obvious 1/2 to avoid surprises if someone saves a session and later \
* downgrades PuTTY. So it's easier to use these numbers internally too. \
*/ \
X(INT, NONE, sshprot) \
X(INT, NONE, ssh2_des_cbc) /* "des-cbc" unrecommended SSH-2 cipher */ \ X(INT, NONE, ssh2_des_cbc) /* "des-cbc" unrecommended SSH-2 cipher */ \
X(INT, NONE, ssh_no_userauth) /* bypass "ssh-userauth" (SSH-2 only) */ \ X(INT, NONE, ssh_no_userauth) /* bypass "ssh-userauth" (SSH-2 only) */ \
X(INT, NONE, ssh_show_banner) /* show USERAUTH_BANNERs (SSH-2 only) */ \ X(INT, NONE, ssh_show_banner) /* show USERAUTH_BANNERs (SSH-2 only) */ \

View File

@ -803,8 +803,15 @@ void load_open_settings(void *sesskey, Conf *conf)
hknames, HK_MAX, conf, CONF_ssh_hklist); hknames, HK_MAX, conf, CONF_ssh_hklist);
gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time); gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time);
gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data); gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data);
{
/* SSH-2 only by default */ /* SSH-2 only by default */
gppi(sesskey, "SshProt", 3, conf, CONF_sshprot); int sshprot = gppi_raw(sesskey, "SshProt", 3);
/* Old sessions may contain the values correponding to the fallbacks
* we used to allow; migrate them */
if (sshprot == 1) sshprot = 0; /* => "SSH-1 only" */
else if (sshprot == 2) sshprot = 3; /* => "SSH-2 only" */
conf_set_int(conf, CONF_sshprot, sshprot);
}
gpps(sesskey, "LogHost", "", conf, CONF_loghost); gpps(sesskey, "LogHost", "", conf, CONF_loghost);
gppi(sesskey, "SSH2DES", 0, conf, CONF_ssh2_des_cbc); gppi(sesskey, "SSH2DES", 0, conf, CONF_ssh2_des_cbc);
gppi(sesskey, "SshNoAuth", 0, conf, CONF_ssh_no_userauth); gppi(sesskey, "SshNoAuth", 0, conf, CONF_ssh_no_userauth);

26
ssh.c
View File

@ -3138,16 +3138,22 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
/* Anything greater or equal to "1.99" means protocol 2 is supported. */ /* Anything greater or equal to "1.99" means protocol 2 is supported. */
s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0; s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
if (conf_get_int(ssh->conf, CONF_sshprot) == 0 && !s->proto1) { if (conf_get_int(ssh->conf, CONF_sshprot) == 0) {
bombout(("SSH protocol version 1 required by configuration but " if (!s->proto1) {
"not provided by server")); bombout(("SSH protocol version 1 required by our configuration "
"but not provided by server"));
crStop(0); crStop(0);
} }
if (conf_get_int(ssh->conf, CONF_sshprot) == 3 && !s->proto2) { } else if (conf_get_int(ssh->conf, CONF_sshprot) == 3) {
bombout(("SSH protocol version 2 required by configuration but " if (!s->proto2) {
"not provided by server")); bombout(("SSH protocol version 2 required by our configuration "
"but server only provides (old, insecure) SSH-1"));
crStop(0); crStop(0);
} }
} else {
/* No longer support values 1 or 2 for CONF_sshprot */
assert(!"Unexpected value for CONF_sshprot");
}
if (s->proto2 && (conf_get_int(ssh->conf, CONF_sshprot) >= 2 || !s->proto1)) if (s->proto2 && (conf_get_int(ssh->conf, CONF_sshprot) >= 2 || !s->proto1))
ssh->version = 2; ssh->version = 2;
@ -3708,13 +3714,17 @@ static const char *connect_to_host(Ssh ssh, const char *host, int port,
} }
/* /*
* If the SSH version number's fixed, set it now, and if it's SSH-2, * The SSH version number is always fixed (since we no longer support
* send the version string too. * fallback between versions), so set it now, and if it's SSH-2,
* send the version string now too.
*/ */
sshprot = conf_get_int(ssh->conf, CONF_sshprot); sshprot = conf_get_int(ssh->conf, CONF_sshprot);
assert(sshprot == 0 || sshprot == 3);
if (sshprot == 0) if (sshprot == 0)
/* SSH-1 only */
ssh->version = 1; ssh->version = 1;
if (sshprot == 3 && !ssh->bare_connection) { if (sshprot == 3 && !ssh->bare_connection) {
/* SSH-2 only */
ssh->version = 2; ssh->version = 2;
ssh_send_verstring(ssh, "SSH-", NULL); ssh_send_verstring(ssh, "SSH-", NULL);
} }