mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-21 04:55:02 -05:00
Add another bug workaround, this one for old OpenSSH (<2.3) servers
which have a strange idea of what data should be signed in a PK auth request. This actually got in my way while doing serious things at work! :-) [originally from svn r2800]
This commit is contained in:
parent
b83b9fad77
commit
be9718cb13
@ -1,4 +1,4 @@
|
|||||||
\versionid $Id: config.but,v 1.53 2003/02/01 02:09:02 jacob Exp $
|
\versionid $Id: config.but,v 1.54 2003/02/04 13:02:51 simon Exp $
|
||||||
|
|
||||||
\C{config} Configuring PuTTY
|
\C{config} Configuring PuTTY
|
||||||
|
|
||||||
@ -2172,6 +2172,24 @@ workaround, you need to enable it manually.
|
|||||||
|
|
||||||
This is an SSH2-specific bug.
|
This is an SSH2-specific bug.
|
||||||
|
|
||||||
|
\S{config-ssh-bug-pksessid2} \q{Misuses the session ID in PK auth}
|
||||||
|
|
||||||
|
\cfg{winhelp-topic}{ssh.bugs.rsapad2}
|
||||||
|
|
||||||
|
Versions below 2.3 of OpenSSH require SSH2 public-key authentication
|
||||||
|
to be done slightly differently: the data to be signed by the client
|
||||||
|
contains the session ID formatted in a different way. If public-key
|
||||||
|
authentication mysteriously does not work but the Event Log (see
|
||||||
|
\k{using-eventlog}) thinks it has successfully sent a signature, it
|
||||||
|
might be worth enabling the workaround for this bug to see if it
|
||||||
|
helps.
|
||||||
|
|
||||||
|
If this bug is detected, PuTTY will sign data in the way OpenSSH
|
||||||
|
expects. If this bug is enabled when talking to a correct server,
|
||||||
|
SSH2 public-key authentication will fail.
|
||||||
|
|
||||||
|
This is an SSH2-specific bug.
|
||||||
|
|
||||||
\H{config-file} Storing configuration in a file
|
\H{config-file} Storing configuration in a file
|
||||||
|
|
||||||
PuTTY does not currently support storing its configuration in a file
|
PuTTY does not currently support storing its configuration in a file
|
||||||
|
2
putty.h
2
putty.h
@ -439,7 +439,7 @@ struct config_tag {
|
|||||||
/* SSH bug compatibility modes */
|
/* SSH bug compatibility modes */
|
||||||
int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
|
int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
|
||||||
sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
|
sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
|
||||||
sshbug_dhgex2;
|
sshbug_dhgex2, sshbug_pksessid2;
|
||||||
/* Options for pterm. Should split out into platform-dependent part. */
|
/* Options for pterm. Should split out into platform-dependent part. */
|
||||||
int stamp_utmp;
|
int stamp_utmp;
|
||||||
int login_shell;
|
int login_shell;
|
||||||
|
@ -343,6 +343,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
|
|||||||
write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2);
|
write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2);
|
||||||
write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
|
write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
|
||||||
write_setting_i(sesskey, "BugDHGEx2", 2-cfg->sshbug_dhgex2);
|
write_setting_i(sesskey, "BugDHGEx2", 2-cfg->sshbug_dhgex2);
|
||||||
|
write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2);
|
||||||
write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp);
|
write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp);
|
||||||
write_setting_i(sesskey, "LoginShell", cfg->login_shell);
|
write_setting_i(sesskey, "LoginShell", cfg->login_shell);
|
||||||
write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left);
|
write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left);
|
||||||
@ -616,6 +617,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
|
|||||||
gppi(sesskey, "BugDeriveKey2", 0, &i); cfg->sshbug_derivekey2 = 2-i;
|
gppi(sesskey, "BugDeriveKey2", 0, &i); cfg->sshbug_derivekey2 = 2-i;
|
||||||
gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i;
|
gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i;
|
||||||
gppi(sesskey, "BugDHGEx2", 0, &i); cfg->sshbug_dhgex2 = 2-i;
|
gppi(sesskey, "BugDHGEx2", 0, &i); cfg->sshbug_dhgex2 = 2-i;
|
||||||
|
gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i;
|
||||||
gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp);
|
gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp);
|
||||||
gppi(sesskey, "LoginShell", 1, &cfg->login_shell);
|
gppi(sesskey, "LoginShell", 1, &cfg->login_shell);
|
||||||
gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left);
|
gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left);
|
||||||
|
31
ssh.c
31
ssh.c
@ -163,6 +163,7 @@ static const char *const ssh2_disconnect_reasons[] = {
|
|||||||
#define BUG_SSH2_RSA_PADDING 16
|
#define BUG_SSH2_RSA_PADDING 16
|
||||||
#define BUG_SSH2_DERIVEKEY 32
|
#define BUG_SSH2_DERIVEKEY 32
|
||||||
#define BUG_SSH2_DH_GEX 64
|
#define BUG_SSH2_DH_GEX 64
|
||||||
|
#define BUG_SSH2_PK_SESSIONID 128
|
||||||
|
|
||||||
#define translate(x) if (type == x) return #x
|
#define translate(x) if (type == x) return #x
|
||||||
#define translatec(x,ctx) if (type == x && (pkt_ctx & ctx)) return #x
|
#define translatec(x,ctx) if (type == x && (pkt_ctx & ctx)) return #x
|
||||||
@ -1792,6 +1793,17 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
|
|||||||
logevent("We believe remote version has SSH2 RSA padding bug");
|
logevent("We believe remote version has SSH2 RSA padding bug");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssh->cfg.sshbug_pksessid2 == FORCE_ON ||
|
||||||
|
(ssh->cfg.sshbug_pksessid2 == AUTO &&
|
||||||
|
wc_match("OpenSSH_2.[0-2]*", imp))) {
|
||||||
|
/*
|
||||||
|
* These versions have the SSH2 session-ID bug in
|
||||||
|
* public-key authentication.
|
||||||
|
*/
|
||||||
|
ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID;
|
||||||
|
logevent("We believe remote version has SSH2 public-key-session-ID bug");
|
||||||
|
}
|
||||||
|
|
||||||
if (ssh->cfg.sshbug_dhgex2 == FORCE_ON) {
|
if (ssh->cfg.sshbug_dhgex2 == FORCE_ON) {
|
||||||
/*
|
/*
|
||||||
* User specified the SSH2 DH GEX bug.
|
* User specified the SSH2 DH GEX bug.
|
||||||
@ -4629,6 +4641,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
ssh2_pkt_addstring_data(ssh, s->pkblob, s->pklen);
|
ssh2_pkt_addstring_data(ssh, s->pkblob, s->pklen);
|
||||||
|
|
||||||
s->siglen = ssh->pktout.length - 5 + 4 + 20;
|
s->siglen = ssh->pktout.length - 5 + 4 + 20;
|
||||||
|
if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
|
||||||
|
s->siglen -= 4;
|
||||||
s->len = 1; /* message type */
|
s->len = 1; /* message type */
|
||||||
s->len += 4 + s->pklen; /* key blob */
|
s->len += 4 + s->pklen; /* key blob */
|
||||||
s->len += 4 + s->siglen; /* data to sign */
|
s->len += 4 + s->siglen; /* data to sign */
|
||||||
@ -4644,8 +4658,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
PUT_32BIT(s->q, s->siglen);
|
PUT_32BIT(s->q, s->siglen);
|
||||||
s->q += 4;
|
s->q += 4;
|
||||||
/* Now the data to be signed... */
|
/* Now the data to be signed... */
|
||||||
|
if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
|
||||||
PUT_32BIT(s->q, 20);
|
PUT_32BIT(s->q, 20);
|
||||||
s->q += 4;
|
s->q += 4;
|
||||||
|
}
|
||||||
memcpy(s->q, ssh->v2_session_id, 20);
|
memcpy(s->q, ssh->v2_session_id, 20);
|
||||||
s->q += 20;
|
s->q += 20;
|
||||||
memcpy(s->q, ssh->pktout.data + 5,
|
memcpy(s->q, ssh->pktout.data + 5,
|
||||||
@ -4894,6 +4910,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
} else {
|
} else {
|
||||||
unsigned char *pkblob, *sigblob, *sigdata;
|
unsigned char *pkblob, *sigblob, *sigdata;
|
||||||
int pkblob_len, sigblob_len, sigdata_len;
|
int pkblob_len, sigblob_len, sigdata_len;
|
||||||
|
int p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have loaded the private key and the server
|
* We have loaded the private key and the server
|
||||||
@ -4919,11 +4936,19 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
* outgoing packet.
|
* outgoing packet.
|
||||||
*/
|
*/
|
||||||
sigdata_len = ssh->pktout.length - 5 + 4 + 20;
|
sigdata_len = ssh->pktout.length - 5 + 4 + 20;
|
||||||
|
if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
|
||||||
|
sigdata_len -= 4;
|
||||||
sigdata = smalloc(sigdata_len);
|
sigdata = smalloc(sigdata_len);
|
||||||
PUT_32BIT(sigdata, 20);
|
p = 0;
|
||||||
memcpy(sigdata + 4, ssh->v2_session_id, 20);
|
if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
|
||||||
memcpy(sigdata + 24, ssh->pktout.data + 5,
|
PUT_32BIT(sigdata+p, 20);
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
memcpy(sigdata+p, ssh->v2_session_id, 20); p += 20;
|
||||||
|
memcpy(sigdata+p, ssh->pktout.data + 5,
|
||||||
ssh->pktout.length - 5);
|
ssh->pktout.length - 5);
|
||||||
|
p += ssh->pktout.length - 5;
|
||||||
|
assert(p == sigdata_len);
|
||||||
sigblob = key->alg->sign(key->data, (char *)sigdata,
|
sigblob = key->alg->sign(key->data, (char *)sigdata,
|
||||||
sigdata_len, &sigblob_len);
|
sigdata_len, &sigblob_len);
|
||||||
ssh2_add_sigblob(ssh, pkblob, pkblob_len,
|
ssh2_add_sigblob(ssh, pkblob, pkblob_len,
|
||||||
|
22
windlg.c
22
windlg.c
@ -559,6 +559,8 @@ enum { IDCX_ABOUT =
|
|||||||
IDC_BUGD_RSAPAD2,
|
IDC_BUGD_RSAPAD2,
|
||||||
IDC_BUGS_DHGEX2,
|
IDC_BUGS_DHGEX2,
|
||||||
IDC_BUGD_DHGEX2,
|
IDC_BUGD_DHGEX2,
|
||||||
|
IDC_BUGS_PKSESSID2,
|
||||||
|
IDC_BUGD_PKSESSID2,
|
||||||
sshbugspanelend,
|
sshbugspanelend,
|
||||||
|
|
||||||
selectionpanelstart,
|
selectionpanelstart,
|
||||||
@ -1066,6 +1068,9 @@ char *help_context_cmd(int id)
|
|||||||
case IDC_BUGS_DHGEX2:
|
case IDC_BUGS_DHGEX2:
|
||||||
case IDC_BUGD_DHGEX2:
|
case IDC_BUGD_DHGEX2:
|
||||||
return "JI(`',`ssh.bugs.dhgex2')";
|
return "JI(`',`ssh.bugs.dhgex2')";
|
||||||
|
case IDC_BUGS_PKSESSID2:
|
||||||
|
case IDC_BUGD_PKSESSID2:
|
||||||
|
return "JI(`',`ssh.bugs.pksessid2')";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1426,6 +1431,13 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
|
|||||||
SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL,
|
SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL,
|
||||||
cfg.sshbug_dhgex2 == FORCE_ON ? 2 :
|
cfg.sshbug_dhgex2 == FORCE_ON ? 2 :
|
||||||
cfg.sshbug_dhgex2 == FORCE_OFF ? 1 : 0, 0);
|
cfg.sshbug_dhgex2 == FORCE_OFF ? 1 : 0, 0);
|
||||||
|
SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_RESETCONTENT, 0, 0);
|
||||||
|
SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Auto");
|
||||||
|
SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Off");
|
||||||
|
SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"On");
|
||||||
|
SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_SETCURSEL,
|
||||||
|
cfg.sshbug_pksessid2 == FORCE_ON ? 2 :
|
||||||
|
cfg.sshbug_pksessid2 == FORCE_OFF ? 1 : 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct treeview_faff {
|
struct treeview_faff {
|
||||||
@ -2039,6 +2051,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
|||||||
IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
|
IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
|
||||||
staticddl(&cp, "Chokes on &Diffie-Hellman group exchange",
|
staticddl(&cp, "Chokes on &Diffie-Hellman group exchange",
|
||||||
IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, 20);
|
IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, 20);
|
||||||
|
staticddl(&cp, "Misuses the sessio&n ID in PK auth",
|
||||||
|
IDC_BUGS_PKSESSID2, IDC_BUGD_PKSESSID2, 20);
|
||||||
endbox(&cp);
|
endbox(&cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3678,6 +3692,14 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
|
|||||||
index == 1 ? FORCE_OFF : FORCE_ON);
|
index == 1 ? FORCE_OFF : FORCE_ON);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDC_BUGD_PKSESSID2:
|
||||||
|
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||||
|
int index = SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2,
|
||||||
|
CB_GETCURSEL, 0, 0);
|
||||||
|
cfg.sshbug_pksessid2 = (index == 0 ? AUTO :
|
||||||
|
index == 1 ? FORCE_OFF : FORCE_ON);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case WM_HELP:
|
case WM_HELP:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user