From 5bb641e1cb8327a54bbe1ed4391782a2cf1b938a Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 11 Dec 2001 21:00:01 +0000 Subject: [PATCH] Disable username switching between SSH2 auth attempts, and add a configurable option so users can re-enable the feature _if_ they know they have an SSH2 server that isn't going to get shirty about it. Inspired by a spectacular increase in OpenSSH's shirtiness. git-svn-id: svn://svn.tartarus.org/sgt/putty@1474 cda61777-01e9-0310-a592-d414129be87e --- doc/config.but | 24 +++++++++++++++++++++++- putty.h | 1 + settings.c | 2 ++ ssh.c | 9 ++++++++- windlg.c | 12 ++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/doc/config.but b/doc/config.but index 4d848ef8..a15ed7f1 100644 --- a/doc/config.but +++ b/doc/config.but @@ -1,4 +1,4 @@ -\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 @@ -1479,6 +1479,28 @@ See \k{pageant} for general information on Pageant, and 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} diff --git a/putty.h b/putty.h index e8cf368d..4302b849 100644 --- a/putty.h +++ b/putty.h @@ -251,6 +251,7 @@ typedef struct { 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 */ diff --git a/settings.c b/settings.c index 01fd312d..90bb9ce2 100644 --- a/settings.c +++ b/settings.c @@ -172,6 +172,7 @@ void save_settings(char *section, int do_host, Config * cfg) 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); @@ -359,6 +360,7 @@ void load_settings(char *section, int do_host, Config * cfg) 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); diff --git a/ssh.c b/ssh.c index fe163c0b..9f27e3a9 100644 --- a/ssh.c +++ b/ssh.c @@ -3712,6 +3712,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) * the username they will want to be able to get back and * retype it! */ + username[0] = '\0'; do { static int pos; static char c; @@ -3720,7 +3721,13 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) * 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)) { diff --git a/windlg.c b/windlg.c index c0da9c28..9da02256 100644 --- a/windlg.c +++ b/windlg.c @@ -477,6 +477,7 @@ enum { IDCX_ABOUT = IDC_PKEDIT, IDC_PKBUTTON, IDC_AGENTFWD, + IDC_CHANGEUSER, IDC_AUTHTIS, IDC_AUTHKI, sshauthpanelend, @@ -833,6 +834,8 @@ char *help_context_cmd(int id) 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: @@ -1063,6 +1066,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) 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); @@ -1674,6 +1678,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) 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); @@ -2756,6 +2762,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, 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: -- 2.11.0