mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
New SSH bug flag, for 'can't handle SSH2_MSG_IGNORE'. Another user
today reported an SSH2_MSG_UNIMPLEMENTED from a Cisco router which looks as if it was triggered by SSH2_MSG_IGNORE, so I'm experimentally putting this flag in. Currently must be manually enabled, though if it turns out to solve the user's problem then I'll probably add at least one version string... [Edited commit message: actually, I also committed in error a piece of experimental code as part of this checkin. Serve me right for not running 'svn diff' first.] [originally from svn r8926]
This commit is contained in:
parent
97ca111e29
commit
d5aa23c116
3
config.c
3
config.c
@ -2284,6 +2284,9 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
ctrl_droplist(s, "Chokes on SSH-1 RSA authentication", 'r', 20,
|
||||
HELPCTX(ssh_bugs_rsa1),
|
||||
sshbug_handler, I(offsetof(Config,sshbug_rsa1)));
|
||||
ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20,
|
||||
HELPCTX(ssh_bugs_ignore2),
|
||||
sshbug_handler, I(offsetof(Config,sshbug_ignore2)));
|
||||
ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20,
|
||||
HELPCTX(ssh_bugs_hmac2),
|
||||
sshbug_handler, I(offsetof(Config,sshbug_hmac2)));
|
||||
|
@ -2948,9 +2948,6 @@ enabled when talking to a correct server, the session will succeed,
|
||||
but keepalives will not work and the session might be more
|
||||
vulnerable to eavesdroppers than it could be.
|
||||
|
||||
This is an SSH-1-specific bug. No known SSH-2 server fails to deal
|
||||
with SSH-2 ignore messages.
|
||||
|
||||
\S{config-ssh-bug-plainpw1} \q{Refuses all SSH-1 \i{password camouflage}}
|
||||
|
||||
\cfg{winhelp-topic}{ssh.bugs.plainpw1}
|
||||
@ -2992,6 +2989,23 @@ will be impossible.
|
||||
|
||||
This is an SSH-1-specific bug.
|
||||
|
||||
\S{config-ssh-bug-ignore2} \q{Chokes on SSH-2 \i{ignore message}s}
|
||||
|
||||
\cfg{winhelp-topic}{ssh.bugs.ignore2}
|
||||
|
||||
An ignore message (SSH_MSG_IGNORE) is a message in the SSH protocol
|
||||
which can be sent from the client to the server, or from the server
|
||||
to the client, at any time. Either side is required to ignore the
|
||||
message whenever it receives it. PuTTY uses ignore messages in SSH-2
|
||||
to confuse the encrypted data stream and make it harder to
|
||||
cryptanalyse. It also uses ignore messages for connection
|
||||
\i{keepalives} (see \k{config-keepalive}).
|
||||
|
||||
If it believes the server to have this bug, PuTTY will stop using
|
||||
ignore messages. If this bug is enabled when talking to a correct
|
||||
server, the session will succeed, but keepalives will not work and
|
||||
the session might be less cryptographically secure than it could be.
|
||||
|
||||
\S{config-ssh-bug-hmac2} \q{Miscomputes SSH-2 HMAC keys}
|
||||
|
||||
\cfg{winhelp-topic}{ssh.bugs.hmac2}
|
||||
|
4
putty.h
4
putty.h
@ -592,7 +592,8 @@ struct config_tag {
|
||||
/* SSH bug compatibility modes */
|
||||
int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
|
||||
sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
|
||||
sshbug_pksessid2, sshbug_rekey2, sshbug_maxpkt2;
|
||||
sshbug_pksessid2, sshbug_rekey2, sshbug_maxpkt2,
|
||||
sshbug_ignore2;
|
||||
/*
|
||||
* ssh_simple means that we promise never to open any channel other
|
||||
* than the main one, which means it can safely use a very large
|
||||
@ -825,6 +826,7 @@ void term_free(Terminal *);
|
||||
void term_size(Terminal *, int, int, int);
|
||||
void term_paint(Terminal *, Context, int, int, int, int, int);
|
||||
void term_scroll(Terminal *, int, int);
|
||||
void term_scroll_to_selection(Terminal *, int);
|
||||
void term_pwron(Terminal *, int);
|
||||
void term_clrsb(Terminal *);
|
||||
void term_mouse(Terminal *, Mouse_Button, Mouse_Button, Mouse_Action,
|
||||
|
@ -477,6 +477,7 @@ void save_open_settings(void *sesskey, Config *cfg)
|
||||
write_setting_i(sesskey, "BugIgnore1", 2-cfg->sshbug_ignore1);
|
||||
write_setting_i(sesskey, "BugPlainPW1", 2-cfg->sshbug_plainpw1);
|
||||
write_setting_i(sesskey, "BugRSA1", 2-cfg->sshbug_rsa1);
|
||||
write_setting_i(sesskey, "BugIgnore2", 2-cfg->sshbug_ignore2);
|
||||
write_setting_i(sesskey, "BugHMAC2", 2-cfg->sshbug_hmac2);
|
||||
write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2);
|
||||
write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
|
||||
@ -817,6 +818,7 @@ void load_open_settings(void *sesskey, Config *cfg)
|
||||
gppi(sesskey, "BugIgnore1", 0, &i); cfg->sshbug_ignore1 = 2-i;
|
||||
gppi(sesskey, "BugPlainPW1", 0, &i); cfg->sshbug_plainpw1 = 2-i;
|
||||
gppi(sesskey, "BugRSA1", 0, &i); cfg->sshbug_rsa1 = 2-i;
|
||||
gppi(sesskey, "BugIgnore2", 0, &i); cfg->sshbug_ignore2 = 2-i;
|
||||
{
|
||||
int i;
|
||||
gppi(sesskey, "BugHMAC2", 0, &i); cfg->sshbug_hmac2 = 2-i;
|
||||
|
36
ssh.c
36
ssh.c
@ -194,6 +194,7 @@ static const char *const ssh2_disconnect_reasons[] = {
|
||||
#define BUG_SSH2_REKEY 64
|
||||
#define BUG_SSH2_PK_SESSIONID 128
|
||||
#define BUG_SSH2_MAXPKT 256
|
||||
#define BUG_CHOKES_ON_SSH2_IGNORE 512
|
||||
|
||||
/*
|
||||
* Codes for terminal modes.
|
||||
@ -2011,7 +2012,8 @@ static void ssh2_pkt_defer_noqueue(Ssh ssh, struct Packet *pkt, int noignore)
|
||||
{
|
||||
int len;
|
||||
if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC) &&
|
||||
ssh->deferred_len == 0 && !noignore) {
|
||||
ssh->deferred_len == 0 && !noignore &&
|
||||
!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
|
||||
/*
|
||||
* Interpose an SSH_MSG_IGNORE to ensure that user data don't
|
||||
* get encrypted with a known IV.
|
||||
@ -2141,7 +2143,8 @@ static void ssh2_pkt_send_with_padding(Ssh ssh, struct Packet *pkt,
|
||||
* unavailable, we don't do this trick at all, because we
|
||||
* gain nothing by it.)
|
||||
*/
|
||||
if (ssh->cscipher) {
|
||||
if (ssh->cscipher &&
|
||||
!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
|
||||
int stringlen, i;
|
||||
|
||||
stringlen = (256 - ssh->deferred_len);
|
||||
@ -2508,6 +2511,15 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
|
||||
ssh->remote_bugs |= BUG_SSH2_MAXPKT;
|
||||
logevent("We believe remote version ignores SSH-2 maximum packet size");
|
||||
}
|
||||
|
||||
if (ssh->cfg.sshbug_ignore2 == FORCE_ON) {
|
||||
/*
|
||||
* Servers that don't support SSH2_MSG_IGNORE. Currently,
|
||||
* none detected automatically.
|
||||
*/
|
||||
ssh->remote_bugs |= BUG_CHOKES_ON_SSH2_IGNORE;
|
||||
logevent("We believe remote version has SSH-2 ignore bug");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -9426,8 +9438,10 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
static const struct telnet_special ssh1_ignore_special[] = {
|
||||
{"IGNORE message", TS_NOP}
|
||||
};
|
||||
static const struct telnet_special ssh2_transport_specials[] = {
|
||||
static const struct telnet_special ssh2_ignore_special[] = {
|
||||
{"IGNORE message", TS_NOP},
|
||||
};
|
||||
static const struct telnet_special ssh2_rekey_special[] = {
|
||||
{"Repeat key exchange", TS_REKEY},
|
||||
};
|
||||
static const struct telnet_special ssh2_session_specials[] = {
|
||||
@ -9452,7 +9466,8 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
{NULL, TS_EXITMENU}
|
||||
};
|
||||
/* XXX review this length for any changes: */
|
||||
static struct telnet_special ssh_specials[lenof(ssh2_transport_specials) +
|
||||
static struct telnet_special ssh_specials[lenof(ssh2_ignore_special) +
|
||||
lenof(ssh2_rekey_special) +
|
||||
lenof(ssh2_session_specials) +
|
||||
lenof(specials_end)];
|
||||
Ssh ssh = (Ssh) handle;
|
||||
@ -9471,7 +9486,10 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
|
||||
ADD_SPECIALS(ssh1_ignore_special);
|
||||
} else if (ssh->version == 2) {
|
||||
ADD_SPECIALS(ssh2_transport_specials);
|
||||
if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE))
|
||||
ADD_SPECIALS(ssh2_ignore_special);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_REKEY))
|
||||
ADD_SPECIALS(ssh2_rekey_special);
|
||||
if (ssh->mainchan)
|
||||
ADD_SPECIALS(ssh2_session_specials);
|
||||
} /* else we're not ready yet */
|
||||
@ -9521,9 +9539,11 @@ static void ssh_special(void *handle, Telnet_Special code)
|
||||
if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
|
||||
send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
|
||||
} else {
|
||||
pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
|
||||
ssh2_pkt_addstring_start(pktout);
|
||||
ssh2_pkt_send_noqueue(ssh, pktout);
|
||||
if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
|
||||
pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
|
||||
ssh2_pkt_addstring_start(pktout);
|
||||
ssh2_pkt_send_noqueue(ssh, pktout);
|
||||
}
|
||||
}
|
||||
} else if (code == TS_REKEY) {
|
||||
if (!ssh->kex_in_progress && ssh->version == 2) {
|
||||
|
25
terminal.c
25
terminal.c
@ -5136,6 +5136,31 @@ void term_scroll(Terminal *term, int rel, int where)
|
||||
term_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scroll the scrollback to centre it on the beginning or end of the
|
||||
* current selection, if any.
|
||||
*/
|
||||
void term_scroll_to_selection(Terminal *term, int which_end)
|
||||
{
|
||||
pos target;
|
||||
int y;
|
||||
int sbtop = -sblines(term);
|
||||
|
||||
if (term->selstate != SELECTED)
|
||||
return;
|
||||
if (which_end)
|
||||
target = term->selend;
|
||||
else
|
||||
target = term->selstart;
|
||||
|
||||
y = target.y - term->rows/2;
|
||||
if (y < sbtop)
|
||||
y = sbtop;
|
||||
else if (y > 0)
|
||||
y = 0;
|
||||
term_scroll(term, -1, y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper routine for clipme(): growing buffer.
|
||||
*/
|
||||
|
@ -3811,6 +3811,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
||||
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
|
||||
return 0;
|
||||
}
|
||||
if ((wParam == VK_PRIOR || wParam == VK_NEXT) && shift_state == 3) {
|
||||
term_scroll_to_selection(term, (wParam == VK_PRIOR ? 0 : 1));
|
||||
return 0;
|
||||
}
|
||||
if (wParam == VK_INSERT && shift_state == 1) {
|
||||
request_paste(NULL);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user