Disable username switching between SSH2 auth attempts, and add a
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 11 Dec 2001 21:00:01 +0000 (21:00 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 11 Dec 2001 21:00:01 +0000 (21:00 +0000)
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
putty.h
settings.c
ssh.c
windlg.c

index 4d848ef..a15ed7f 100644 (file)
@@ -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 e8cf368..4302b84 100644 (file)
--- 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 */
index 01fd312..90bb9ce 100644 (file)
@@ -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 fe163c0..9f27e3a 100644 (file)
--- 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)) {
index c0da9c2..9da0225 100644 (file)
--- 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: