-\versionid $Id: config.but,v 1.36 2002/09/08 13:25:58 jacob Exp $
+\versionid $Id: config.but,v 1.37 2002/09/08 13:28:38 simon Exp $
\C{config} Configuring PuTTY
Keepalives are only supported in Telnet and SSH; the Rlogin and Raw
protocols offer no way of implementing them.
+Note that if you are using SSH1 and the server has a bug that makes
+it unable to deal with SSH1 ignore messages (see
+\k{config-ssh-bug-ignore1}), enabling keepalives will have no effect.
+
\S{config-nodelay} \q{Disable Nagle's algorithm}
\cfg{winhelp-topic}{connection.nodelay}
if the server you connect to offers the SSH protocol version you
have specified.
-\S{config-ssh-macbug} \q{Imitate SSH 2 MAC bug}
-
-\cfg{winhelp-topic}{ssh.buggymac}
-
-This option \e{should} now be unnecessary. It existed in order to
-work around a bug in early versions (2.3.0 and below) of the SSH
-server software from \cw{ssh.com}. The symptom of this problem would
-be that PuTTY would die unexpectedly at the beginning of the
-session, saying \q{Incorrect MAC received on packet}.
-
-Current versions of PuTTY attempt to detect these faulty servers and
-enable the bug compatibility automatically, so you should never need
-to use this option any more.
-
\S{config-ssh-encryption} Encryption algorithm selection
\cfg{winhelp-topic}{ssh.ciphers}
this feature is only available in the SSH 2 protocol, and not all
SSH 2 servers support it (OpenSSH 3.0 does not, for example).
+\H{config-ssh-bugs} The Bugs panel
+
+Not all SSH servers work properly. Various existing servers have
+bugs in them, which can make it impossible for a client to talk to
+them unless it knows about the bug and works around it.
+
+Since most servers announce their software version number at the
+beginning of the SSH connection, PuTTY will attempt to detect which
+bugs it can expect to see in the server and automatically enable
+workarounds. However, sometimes it will make mistakes; if the server
+has been deliberately configured to conceal its version number, or
+if the server is a version which PuTTY's bug database does not know
+about, then PuTTY will not know what bugs to expect.
+
+The Bugs panel allows you to manually configure the bugs PuTTY
+expects to see in the server. Each bug can be configured in three
+states:
+
+\b \q{Off}: PuTTY will assume the server does not have the bug.
+
+\b \q{On}: PuTTY will assume the server \e{does} have the bug.
+
+\b \q{Auto}: PuTTY will use the server's version number announcement
+to try to guess whether or not the server has the bug.
+
+\S{config-ssh-bug-ignore1} \q{Chokes on SSH1 ignore messages}
+
+\cfg{winhelp-topic}{ssh.bugs.ignore1}
+
+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 to hide
+the password packet in SSH1, so that a listener cannot tell the
+length of the user's password; it also uses ignore messages for
+connection keepalives (see \k{config-keepalive}).
+
+If this bug is detected, PuTTY will stop using ignore messages. This
+means that keepalives will stop working, and PuTTY will have to fall
+back to a secondary defence against SSH1 password-length
+eavesdropping. See \k{config-ssh-bug-plainpw1}. 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 more
+vulnerable to eavesdroppers than it could be.
+
+This is an SSH1-specific bug. No known SSH2 server fails to deal
+with SSH2 ignore messages.
+
+\S{config-ssh-bug-plainpw1} \q{Refuses all SSH1 password camouflage}
+
+\cfg{winhelp-topic}{ssh.bugs.plainpw1}
+
+When talking to an SSH1 server which cannot deal with ignore
+messages (see \k{config-ssh-bug-ignore1}), PuTTY will attempt to
+disguise the length of the user's password by sending additional
+padding \e{within} the password packet. This is technically a
+violation of the SSH1 specification, and so PuTTY will only do it
+when it cannot use standards-compliant ignore messages as
+camouflage. In this sense, for a server to refuse to accept a padded
+password packet is not really a bug, but it does make life
+inconvenient if the server can also not handle ignore messages.
+
+If this \q{bug} is detected, PuTTY will have no choice but to send
+the user's password with no form of camouflage, so that an
+eavesdropping user will be easily able to find out the exact length
+of the password. If this bug is enabled when talking to a correct
+server, the session will succeed, but will be more vulnerable to
+eavesdroppers than it could be.
+
+This is an SSH1-specific bug. SSH2 is secure against this type of
+attack.
+
+\S{config-ssh-bug-rsa1} \q{Chokes on SSH1 RSA authentication}
+
+\cfg{winhelp-topic}{ssh.bugs.rsa1}
+
+Some SSH1 servers cannot deal with RSA authentication messages at
+all. If Pageant is running and contains any SSH1 keys, PuTTY will
+normally automatically try RSA authentication before falling back to
+passwords, so these servers will crash when they see the RSA attempt.
+
+If this bug is detected, PuTTY will go straight to password
+authentication. If this bug is enabled when talking to a correct
+server, the session will succeed, but of course RSA authentication
+will be impossible.
+
+This is an SSH1-specific bug.
+
+\S{config-ssh-bug-hmac2} \q{Miscomputes SSH2 HMAC keys}
+
+\cfg{winhelp-topic}{ssh.bugs.hmac2}
+
+Versions 2.3.0 and below of the SSH server software from
+\cw{ssh.com} compute the keys for their HMAC message authentication
+codes incorrectly. A typical symptom of this problem is that PuTTY
+dies unexpectedly at the beginning of the session, saying
+\q{Incorrect MAC received on packet}.
+
+If this bug is detected, PuTTY will compute its HMAC keys in the
+same way as the buggy server, so that communication will still be
+possible. If this bug is enabled when talking to a correct server,
+communication will fail.
+
+This is an SSH2-specific bug.
+
+\S{config-ssh-bug-derivekey2} \q{Miscomputes SSH2 encryption keys}
+
+\cfg{winhelp-topic}{ssh.bugs.derivekey2}
+
+Versions below 2.1.0 of the SSH server software from \cw{ssh.com}
+compute the keys for the session encryption incorrectly. This
+problem can cause various error messages, such as \q{Incoming packet
+was garbled on decryption}, or possibly even \q{Out of memory}.
+
+If this bug is detected, PuTTY will compute its encryption keys in
+the same way as the buggy server, so that communication will still
+be possible. If this bug is enabled when talking to a correct
+server, communication will fail.
+
+This is an SSH2-specific bug.
+
+\S{config-ssh-bug-ssh} \q{Requires padding on SSH2 RSA signatures}
+
+\cfg{winhelp-topic}{ssh.bugs.rsapad2}
+
+Versions below 3.3 of OpenSSH require SSH2 RSA signatures to be
+padded with zero bytes to the same length as the RSA key modulus.
+The SSH2 draft specification says that an unpadded signature MUST be
+accepted, so this is a bug. A typical symptom of this problem is
+that PuTTY mysteriously fails RSA authentication once in every few
+hundred attempts, and falls back to passwords.
+
+If this bug is detected, PuTTY will pad its signatures in the way
+OpenSSH expects. If this bug is enabled when talking to a correct
+server, it is likely that no damage will be done, since correct
+servers usually still accept padded signatures because they're used
+to talking to OpenSSH.
+
+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
int lport_acceptall; /* accept conns from hosts other than localhost */
int rport_acceptall; /* same for remote forwarded ports (SSH2 only) */
char portfwd[1024]; /* [LR]localport\thost:port\000[LR]localport\thost:port\000\000 */
+ /* SSH bug compatibility modes */
+ enum {
+ BUG_AUTO, BUG_OFF, BUG_ON
+ } sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
+ sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2;
} Config;
/*
write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth);
write_setting_i(sesskey, "AuthKI", cfg->try_ki_auth);
write_setting_i(sesskey, "SshProt", cfg->sshprot);
- write_setting_i(sesskey, "BuggyMAC", cfg->buggymac);
write_setting_i(sesskey, "SSH2DES", cfg->ssh2_des_cbc);
write_setting_s(sesskey, "PublicKeyFile", cfg->keyfile);
write_setting_s(sesskey, "RemoteCommand", cfg->remote_cmd);
*p = '\0';
write_setting_s(sesskey, "PortForwardings", buf);
}
-
+ write_setting_i(sesskey, "BugIgnore1", cfg->sshbug_ignore1);
+ write_setting_i(sesskey, "BugPlainPW1", cfg->sshbug_plainpw1);
+ write_setting_i(sesskey, "BugRSA1", cfg->sshbug_rsa1);
+ write_setting_i(sesskey, "BugHMAC2", cfg->sshbug_hmac2);
+ write_setting_i(sesskey, "BugDeriveKey2", cfg->sshbug_derivekey2);
+ write_setting_i(sesskey, "BugRSAPad2", cfg->sshbug_rsapad2);
close_settings_w(sesskey);
}
gprefs(sesskey, "Cipher", "\0",
ciphernames, CIPHER_MAX, cfg->ssh_cipherlist);
gppi(sesskey, "SshProt", 1, &cfg->sshprot);
- gppi(sesskey, "BuggyMAC", 0, &cfg->buggymac);
gppi(sesskey, "SSH2DES", 0, &cfg->ssh2_des_cbc);
gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
gppi(sesskey, "AuthKI", 1, &cfg->try_ki_auth);
}
*q = '\0';
}
+ gppi(sesskey, "BugIgnore1", BUG_AUTO, &cfg->sshbug_ignore1);
+ gppi(sesskey, "BugPlainPW1", BUG_AUTO, &cfg->sshbug_plainpw1);
+ gppi(sesskey, "BugRSA1", BUG_AUTO, &cfg->sshbug_rsa1);
+ {
+ int i;
+ gppi(sesskey, "BugHMAC2", BUG_AUTO, &cfg->sshbug_hmac2);
+ if (cfg->sshbug_hmac2 == BUG_AUTO) {
+ gppi(sesskey, "BuggyMAC", 0, &i);
+ if (i == 1)
+ cfg->sshbug_hmac2 = BUG_ON;
+ }
+ }
+ gppi(sesskey, "BugDeriveKey2", BUG_AUTO, &cfg->sshbug_derivekey2);
+ gppi(sesskey, "BugRSAPad2", BUG_AUTO, &cfg->sshbug_rsapad2);
close_settings_r(sesskey);
}
ssh_remote_bugs = 0;
- if (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
- !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
- !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")) {
+ if (cfg.sshbug_ignore1 == BUG_ON ||
+ (cfg.sshbug_ignore1 == BUG_AUTO &&
+ (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
+ !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
+ !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")))) {
/*
* These versions don't support SSH1_MSG_IGNORE, so we have
* to use a different defence against password length
logevent("We believe remote version has SSH1 ignore bug");
}
- if (!strcmp(imp, "Cisco-1.25")) {
+ if (cfg.sshbug_plainpw1 == BUG_ON ||
+ (cfg.sshbug_plainpw1 == BUG_AUTO &&
+ (!strcmp(imp, "Cisco-1.25")))) {
/*
* These versions need a plain password sent; they can't
* handle having a null and a random length of data after
logevent("We believe remote version needs a plain SSH1 password");
}
- if (!strcmp(imp, "Cisco-1.25")) {
+ if (cfg.sshbug_rsa1 == BUG_ON ||
+ (cfg.sshbug_rsa1 == BUG_AUTO &&
+ (!strcmp(imp, "Cisco-1.25")))) {
/*
* These versions apparently have no clue whatever about
* RSA authentication and will panic and die if they see
logevent("We believe remote version can't handle RSA authentication");
}
- if (!strncmp(imp, "2.1.0", 5) || !strncmp(imp, "2.0.", 4) ||
- !strncmp(imp, "2.2.0", 5) || !strncmp(imp, "2.3.0", 5) ||
- !strncmp(imp, "2.1 ", 4)) {
+ if (cfg.sshbug_hmac2 == BUG_ON ||
+ (cfg.sshbug_hmac2 == BUG_AUTO &&
+ (!strncmp(imp, "2.1.0", 5) || !strncmp(imp, "2.0.", 4) ||
+ !strncmp(imp, "2.2.0", 5) || !strncmp(imp, "2.3.0", 5) ||
+ !strncmp(imp, "2.1 ", 4)))) {
/*
* These versions have the HMAC bug.
*/
logevent("We believe remote version has SSH2 HMAC bug");
}
- if (!strncmp(imp, "2.0.", 4)) {
+ if (cfg.sshbug_derivekey2 == BUG_ON ||
+ (cfg.sshbug_derivekey2 == BUG_AUTO &&
+ (!strncmp(imp, "2.0.", 4)))) {
/*
* These versions have the key-derivation bug (failing to
* include the literal shared secret in the hashes that
logevent("We believe remote version has SSH2 key-derivation bug");
}
- if ((!strncmp(imp, "OpenSSH_2.", 10) && imp[10]>='5' && imp[10]<='9') ||
- (!strncmp(imp, "OpenSSH_3.", 10) && imp[10]>='0' && imp[10]<='2')) {
+ if (cfg.sshbug_rsapad2 == BUG_ON ||
+ (cfg.sshbug_rsapad2 == BUG_AUTO &&
+ ((!strncmp(imp, "OpenSSH_2.", 10) && imp[10]>='5' && imp[10]<='9') ||
+ (!strncmp(imp, "OpenSSH_3.", 10) && imp[10]>='0' && imp[10]<='2')))){
/*
* These versions have the SSH2 RSA padding bug.
*/
if (ssh_state == SSH_STATE_CLOSED
|| ssh_state == SSH_STATE_PREPACKET) return;
if (ssh_version == 1) {
- send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
+ if (!(ssh_remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
+ send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
} else {
ssh2_pkt_init(SSH2_MSG_IGNORE);
ssh2_pkt_addstring_start();
}
/*
+ * A drop-down list box on the right hand side, with a static to
+ * its left.
+ */
+void staticddl(struct ctlpos *cp, char *stext,
+ int sid, int lid, int percentlist)
+{
+ const int height = (COMBOHEIGHT > STATICHEIGHT ?
+ COMBOHEIGHT : STATICHEIGHT);
+ RECT r;
+ int lwid, rwid, rpos;
+
+ rpos =
+ GAPBETWEEN + (100 - percentlist) * (cp->width + GAPBETWEEN) / 100;
+ lwid = rpos - 2 * GAPBETWEEN;
+ rwid = cp->width + GAPBETWEEN - rpos;
+
+ r.left = GAPBETWEEN;
+ r.top = cp->ypos + (height - STATICHEIGHT) / 2;
+ r.right = lwid;
+ r.bottom = STATICHEIGHT;
+ doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
+
+ r.left = rpos;
+ r.top = cp->ypos + (height - EDITHEIGHT) / 2;
+ r.right = rwid;
+ r.bottom = COMBOHEIGHT*4;
+ doctl(cp, r, "COMBOBOX",
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP |
+ CBS_DROPDOWNLIST | CBS_HASSTRINGS, WS_EX_CLIENTEDGE, "", lid);
+
+ cp->ypos += height + GAPBETWEEN;
+}
+
+/*
* A big multiline edit control with a static labelling it.
*/
void bigeditctrl(struct ctlpos *cp, char *stext,
IDC_CIPHERLIST,
IDC_CIPHERUP,
IDC_CIPHERDN,
- IDC_BUGGYMAC,
IDC_SSH2DES,
IDC_SSHPROTSTATIC,
IDC_SSHPROT1ONLY,
IDC_AUTHKI,
sshauthpanelend,
+ sshbugspanelstart,
+ IDC_TITLE_SSHBUGS,
+ IDC_BOX_SSHBUGS1,
+ IDC_BUGS_IGNORE1,
+ IDC_BUGD_IGNORE1,
+ IDC_BUGS_PLAINPW1,
+ IDC_BUGD_PLAINPW1,
+ IDC_BUGS_RSA1,
+ IDC_BUGD_RSA1,
+ IDC_BUGS_HMAC2,
+ IDC_BUGD_HMAC2,
+ IDC_BUGS_DERIVEKEY2,
+ IDC_BUGD_DERIVEKEY2,
+ IDC_BUGS_RSAPAD2,
+ IDC_BUGD_RSAPAD2,
+ sshbugspanelend,
+
selectionpanelstart,
IDC_TITLE_SELECTION,
IDC_BOX_SELECTION1,
case IDC_CIPHERDN:
case IDC_SSH2DES:
return "JI(`',`ssh.ciphers')";
- case IDC_BUGGYMAC:
- return "JI(`',`ssh.buggymac')";
case IDC_SSHPROTSTATIC:
case IDC_SSHPROT1ONLY:
case IDC_SSHPROT1:
case IDC_RPORT_ALL:
return "JI(`',`ssh.tunnels.portfwd.localhost')";
+ case IDC_BUGS_IGNORE1:
+ case IDC_BUGD_IGNORE1:
+ return "JI(`',`ssh.bugs.ignore1')";
+ case IDC_BUGS_PLAINPW1:
+ case IDC_BUGD_PLAINPW1:
+ return "JI(`',`ssh.bugs.plainpw1')";
+ case IDC_BUGS_RSA1:
+ case IDC_BUGD_RSA1:
+ return "JI(`',`ssh.bugs.rsa1')";
+ case IDC_BUGS_HMAC2:
+ case IDC_BUGD_HMAC2:
+ return "JI(`',`ssh.bugs.hmac2')";
+ case IDC_BUGS_DERIVEKEY2:
+ case IDC_BUGD_DERIVEKEY2:
+ return "JI(`',`ssh.bugs.derivekey2')";
+ case IDC_BUGS_RSAPAD2:
+ case IDC_BUGD_RSAPAD2:
+ return "JI(`',`ssh.bugs.rsapad2')";
+
default:
return NULL;
}
SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
- CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
CheckDlgButton(hwnd, IDC_CHANGEUSER, cfg.change_username);
SetDlgItemText(hwnd, IDC_PROXYPASSEDIT, cfg.proxy_password);
CheckRadioButton(hwnd, IDC_PROXYSOCKSVER5, IDC_PROXYSOCKSVER4,
cfg.proxy_socks_version == 4 ? IDC_PROXYSOCKSVER4 : IDC_PROXYSOCKSVER5);
+
+ /* SSH bugs config */
+ SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1, CB_SETCURSEL,
+ cfg.sshbug_ignore1 == BUG_ON ? 2 :
+ cfg.sshbug_ignore1 == BUG_OFF ? 1 : 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1, CB_SETCURSEL,
+ cfg.sshbug_plainpw1 == BUG_ON ? 2 :
+ cfg.sshbug_plainpw1 == BUG_OFF ? 1 : 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSA1, CB_SETCURSEL,
+ cfg.sshbug_rsa1 == BUG_ON ? 2 :
+ cfg.sshbug_rsa1 == BUG_OFF ? 1 : 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2, CB_SETCURSEL,
+ cfg.sshbug_hmac2 == BUG_ON ? 2 :
+ cfg.sshbug_hmac2 == BUG_OFF ? 1 : 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2, CB_SETCURSEL,
+ cfg.sshbug_derivekey2 == BUG_ON ? 2 :
+ cfg.sshbug_derivekey2 == BUG_OFF ? 1 : 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Auto");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"Off");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_ADDSTRING, 0, (LPARAM)"On");
+ SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2, CB_SETCURSEL,
+ cfg.sshbug_rsapad2 == BUG_ON ? 2 :
+ cfg.sshbug_rsapad2 == BUG_OFF ? 1 : 0, 0);
}
struct treeview_faff {
"1 on&ly", IDC_SSHPROT1ONLY,
"&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2,
"2 o&nly", IDC_SSHPROT2ONLY, NULL);
- checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
- IDC_BUGGYMAC);
endbox(&cp);
beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
}
}
+ if (panel == sshbugspanelstart) {
+ /* The SSH bugs panel. Accelerators used: [acgoh] isrmep */
+ struct ctlpos cp;
+ ctlposinit(&cp, hwnd, 80, 3, 13);
+ if (dlgtype == 0) {
+ bartitle(&cp, "Workarounds for SSH server bugs",
+ IDC_TITLE_SSHBUGS);
+ beginbox(&cp, "Detection of known bugs in SSH servers",
+ IDC_BOX_SSHBUGS1);
+ staticddl(&cp, "Chokes on SSH1 &ignore messages",
+ IDC_BUGS_IGNORE1, IDC_BUGD_IGNORE1, 20);
+ staticddl(&cp, "Refuses all SSH1 pa&ssword camouflage",
+ IDC_BUGS_PLAINPW1, IDC_BUGD_PLAINPW1, 20);
+ staticddl(&cp, "Chokes on SSH1 &RSA authentication",
+ IDC_BUGS_RSA1, IDC_BUGD_RSA1, 20);
+ staticddl(&cp, "Miscomputes SSH2 H&MAC keys",
+ IDC_BUGS_HMAC2, IDC_BUGD_HMAC2, 20);
+ staticddl(&cp, "Miscomputes SSH2 &encryption keys",
+ IDC_BUGS_DERIVEKEY2, IDC_BUGD_DERIVEKEY2, 20);
+ staticddl(&cp, "Requires &padding on SSH2 RSA signatures",
+ IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20);
+ endbox(&cp);
+ }
+ }
+
if (panel == tunnelspanelstart) {
/* The Tunnels panel. Accelerators used: [acgoh] deilmrstxp */
struct ctlpos cp;
/* XXX make it closed by default? */
treeview_insert(&tvfaff, 2, "Auth");
treeview_insert(&tvfaff, 2, "Tunnels");
+ treeview_insert(&tvfaff, 2, "Bugs");
}
}
create_controls(hwnd, dlgtype, sshpanelstart);
if (!strcmp(buffer, "Auth"))
create_controls(hwnd, dlgtype, sshauthpanelstart);
+ if (!strcmp(buffer, "Bugs"))
+ create_controls(hwnd, dlgtype, sshbugspanelstart);
if (!strcmp(buffer, "Selection"))
create_controls(hwnd, dlgtype, selectionpanelstart);
if (!strcmp(buffer, "Colours"))
cfg.compression =
IsDlgButtonChecked(hwnd, IDC_COMPRESS);
break;
- case IDC_BUGGYMAC:
- if (HIWORD(wParam) == BN_CLICKED ||
- HIWORD(wParam) == BN_DOUBLECLICKED)
- cfg.buggymac =
- IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
- break;
case IDC_SSH2DES:
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED)
disaster2:;
}
break;
+ case IDC_BUGD_IGNORE1:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_ignore1 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
+ case IDC_BUGD_PLAINPW1:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_plainpw1 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
+ case IDC_BUGD_RSA1:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSA1,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_rsa1 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
+ case IDC_BUGD_HMAC2:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_hmac2 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
+ case IDC_BUGD_DERIVEKEY2:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_derivekey2 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
+ case IDC_BUGD_RSAPAD2:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2,
+ CB_GETCURSEL, 0, 0);
+ cfg.sshbug_rsapad2 = (index == 0 ? BUG_AUTO :
+ index == 1 ? BUG_OFF : BUG_ON);
+ }
+ break;
}
return 0;
case WM_HELP:
char *btext1, int bid1, char *btext2, int bid2);
void staticedit(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit);
+void staticddl(struct ctlpos *cp, char *stext,
+ int sid, int lid, int percentlist);
void combobox(struct ctlpos *cp, char *text, int staticid, int listid);
void staticpassedit(struct ctlpos *cp, char *stext,
int sid, int eid, int percentedit);