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:
Simon Tatham 2003-02-04 13:02:51 +00:00
Родитель b83b9fad77
Коммит be9718cb13
5 изменённых файлов: 74 добавлений и 7 удалений

Просмотреть файл

@ -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
@ -2172,6 +2172,24 @@ workaround, you need to enable it manually.
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
PuTTY does not currently support storing its configuration in a file

Просмотреть файл

@ -439,7 +439,7 @@ struct config_tag {
/* SSH bug compatibility modes */
int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
sshbug_dhgex2;
sshbug_dhgex2, sshbug_pksessid2;
/* Options for pterm. Should split out into platform-dependent part. */
int stamp_utmp;
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, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
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, "LoginShell", cfg->login_shell);
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, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 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, "LoginShell", 1, &cfg->login_shell);
gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left);

35
ssh.c
Просмотреть файл

@ -163,6 +163,7 @@ static const char *const ssh2_disconnect_reasons[] = {
#define BUG_SSH2_RSA_PADDING 16
#define BUG_SSH2_DERIVEKEY 32
#define BUG_SSH2_DH_GEX 64
#define BUG_SSH2_PK_SESSIONID 128
#define translate(x) if (type == x) 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");
}
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) {
/*
* 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);
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 += 4 + s->pklen; /* key blob */
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);
s->q += 4;
/* Now the data to be signed... */
PUT_32BIT(s->q, 20);
s->q += 4;
if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
PUT_32BIT(s->q, 20);
s->q += 4;
}
memcpy(s->q, ssh->v2_session_id, 20);
s->q += 20;
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 {
unsigned char *pkblob, *sigblob, *sigdata;
int pkblob_len, sigblob_len, sigdata_len;
int p;
/*
* 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.
*/
sigdata_len = ssh->pktout.length - 5 + 4 + 20;
if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
sigdata_len -= 4;
sigdata = smalloc(sigdata_len);
PUT_32BIT(sigdata, 20);
memcpy(sigdata + 4, ssh->v2_session_id, 20);
memcpy(sigdata + 24, ssh->pktout.data + 5,
p = 0;
if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
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);
p += ssh->pktout.length - 5;
assert(p == sigdata_len);
sigblob = key->alg->sign(key->data, (char *)sigdata,
sigdata_len, &sigblob_len);
ssh2_add_sigblob(ssh, pkblob, pkblob_len,

Просмотреть файл

@ -559,6 +559,8 @@ enum { IDCX_ABOUT =
IDC_BUGD_RSAPAD2,
IDC_BUGS_DHGEX2,
IDC_BUGD_DHGEX2,
IDC_BUGS_PKSESSID2,
IDC_BUGD_PKSESSID2,
sshbugspanelend,
selectionpanelstart,
@ -1066,6 +1068,9 @@ char *help_context_cmd(int id)
case IDC_BUGS_DHGEX2:
case IDC_BUGD_DHGEX2:
return "JI(`',`ssh.bugs.dhgex2')";
case IDC_BUGS_PKSESSID2:
case IDC_BUGD_PKSESSID2:
return "JI(`',`ssh.bugs.pksessid2')";
default:
return NULL;
@ -1426,6 +1431,13 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL,
cfg.sshbug_dhgex2 == FORCE_ON ? 2 :
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 {
@ -2039,6 +2051,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
staticddl(&cp, "Chokes on &Diffie-Hellman group exchange",
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);
}
}
@ -3678,6 +3692,14 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
index == 1 ? FORCE_OFF : FORCE_ON);
}
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;
case WM_HELP: