-\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
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
/* 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;
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);
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);
#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
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.
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 */
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,
} else {
unsigned char *pkblob, *sigblob, *sigdata;
int pkblob_len, sigblob_len, sigdata_len;
+ int p;
/*
* We have loaded the private key and the server
* 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,
IDC_BUGD_RSAPAD2,
IDC_BUGS_DHGEX2,
IDC_BUGD_DHGEX2,
+ IDC_BUGS_PKSESSID2,
+ IDC_BUGD_PKSESSID2,
sshbugspanelend,
selectionpanelstart,
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;
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 {
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);
}
}
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: