-\versionid $Id: config.but,v 1.18 2001/12/06 20:05:39 simon Exp $
+\versionid $Id: config.but,v 1.19 2001/12/11 21:00:01 simon Exp $
\C{config} Configuring PuTTY
there is a security risk involved with enabling this option; see
\k{pageant-security} for details.
+\S{config-ssh-agentfwd} \q{Allow attempted changes of username in SSH2}
+
+\cfg{winhelp-topic}{ssh.auth.changeuser}
+
+In the SSH 1 protocol, it is impossible to change username after
+failing to authenticate. So if you mis-type your username at the
+PuTTY \q{login as:} prompt, you will not be able to change it except
+by restarting PuTTY.
+
+The SSH 2 protocol \e{does} allow changes of username, in principle,
+but does not make it mandatory for SSH 2 servers to accept them. In
+particular, OpenSSH does not accept a change of username; once you
+have sent one username, it will reject attempts to try to
+authenticate as another user. (Depending on the version of OpenSSH,
+it may quietly return failure for all login attempts, or it may send
+an error message.)
+
+For this reason, PuTTY will by default not prompt you for your
+username more than once, in case the server complains. If you know
+your server can cope with it, you can enable the \q{Allow attempted
+changes of username} option to modify PuTTY's behaviour.
+
\S{config-ssh-privkey} \q{Private key file for authentication}
\cfg{winhelp-topic}{ssh.auth.privkey}
int nopty;
int compression;
int agentfwd;
+ int change_username; /* allow username switching in SSH2 */
int ssh_cipherlist[CIPHER_MAX];
char keyfile[FILENAME_MAX];
int sshprot; /* use v1 or v2 when both available */
write_setting_i(sesskey, "NoPTY", cfg->nopty);
write_setting_i(sesskey, "Compression", cfg->compression);
write_setting_i(sesskey, "AgentFwd", cfg->agentfwd);
+ write_setting_i(sesskey, "ChangeUsername", cfg->change_username);
wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX,
cfg->ssh_cipherlist);
write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth);
gppi(sesskey, "NoPTY", 0, &cfg->nopty);
gppi(sesskey, "Compression", 0, &cfg->compression);
gppi(sesskey, "AgentFwd", 0, &cfg->agentfwd);
+ gppi(sesskey, "ChangeUsername", 0, &cfg->change_username);
gprefs(sesskey, "Cipher", "\0",
ciphernames, CIPHER_MAX, cfg->ssh_cipherlist);
gppi(sesskey, "SshProt", 1, &cfg->sshprot);
* the username they will want to be able to get back and
* retype it!
*/
+ username[0] = '\0';
do {
static int pos;
static char c;
* Get a username.
*/
pos = 0;
- if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
+ if (*username && !cfg.change_username) {
+ /*
+ * We got a username last time round this loop, and
+ * with change_username turned off we don't try to get
+ * it again.
+ */
+ } else if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
if (ssh_get_line) {
if (!ssh_get_line("login as: ",
username, sizeof(username), FALSE)) {
IDC_PKEDIT,
IDC_PKBUTTON,
IDC_AGENTFWD,
+ IDC_CHANGEUSER,
IDC_AUTHTIS,
IDC_AUTHKI,
sshauthpanelend,
return "JI(`',`ssh.auth.privkey')";
case IDC_AGENTFWD:
return "JI(`',`ssh.auth.agentfwd')";
+ case IDC_CHANGEUSER:
+ return "JI(`',`ssh.auth.changeuser')";
case IDC_AUTHTIS:
return "JI(`',`ssh.auth.tis')";
case IDC_AUTHKI:
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);
CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
beginbox(&cp, "Authentication parameters",
IDC_BOX_SSHAUTH2);
checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
+ checkbox(&cp, "Allow attempted changes of &username in SSH2",
+ IDC_CHANGEUSER);
editbutton(&cp, "Private &key file for authentication:",
IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
IDC_PKBUTTON);
cfg.agentfwd =
IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
break;
+ case IDC_CHANGEUSER:
+ if (HIWORD(wParam) == BN_CLICKED ||
+ HIWORD(wParam) == BN_DOUBLECLICKED)
+ cfg.change_username =
+ IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
+ break;
case IDC_CIPHERLIST:
case IDC_CIPHERUP:
case IDC_CIPHERDN: