New option to allow use of the local OS username for login to the remote side
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Mon, 24 Nov 2008 17:51:42 +0000 (17:51 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Mon, 24 Nov 2008 17:51:42 +0000 (17:51 +0000)
if we have no better ideas, with UI shamelessly stolen from Quest PuTTY.

Off by default, which effectively reverts the change to using the local
username by default that came in with GSSAPI support in r8138. Anyone wanting
seamless single sign-on will need to set the new option. (The previous
default behaviour was getting in the way in ad-hoc scenarios.)

Note that the PSCP and Unix-Plink behaviour of using the local username by
default have remained unchanged throughout; they are not affected by the new
option. Not sure if that's the Right Thing.

git-svn-id: svn://svn.tartarus.org/sgt/putty@8324 cda61777-01e9-0310-a592-d414129be87e

config.c
doc/config.but
putty.h
rlogin.c
settings.c
ssh.c
telnet.c
windows/winhelp.h

index 67a018f..09c77d5 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1751,6 +1751,21 @@ void setup_config_box(struct controlbox *b, int midsession,
                         HELPCTX(connection_username),
                         dlg_stdeditbox_handler, I(offsetof(Config,username)),
                         I(sizeof(((Config *)0)->username)));
+           {
+               /* We assume the local username is sufficiently stable
+                * to include on the dialog box. */
+               char *user = get_username();
+               char *userlabel = dupprintf("Use system username (%s)", user);
+               sfree(user);
+               ctrl_radiobuttons(s, "When username is not specified:", 'n', 4,
+                                 HELPCTX(connection_username_from_env),
+                                 dlg_stdradiobutton_handler,
+                                 I(offsetof(Config, username_from_env)),
+                                 "Prompt", I(FALSE),
+                                 userlabel, I(TRUE),
+                                 NULL);
+               sfree(userlabel);
+           }
 
            s = ctrl_getset(b, "Connection/Data", "term",
                            "Terminal details");
index 96f5dbe..27704ee 100644 (file)
@@ -1788,6 +1788,22 @@ it explicitly every time. (Some Telnet servers don't support this.)
 
 In this box you can type that user name.
 
+\S{config-username-from-env} \q{Use of system username}
+
+\cfg{winhelp-topic}{connection.usernamefromenv}
+
+When the previous box (\k{config-username}) is left blank, by default,
+PuTTY will prompt for a username at the time you make a connection.
+
+In some environments, such as large corporate networks with \i{single
+sign-on}, a more sensible default may be to use the name of the user
+logged in to the local operating system (if any). This control allows
+you to change the default behaviour.
+
+The current system username is displayed in the dialog as a
+convenience. It is not saved in the configuration; if a saved session
+is later used by a different user, that user's name will be used.
+
 \S{config-termtype} \q{\ii{Terminal-type} string}
 
 \cfg{winhelp-topic}{connection.termtype}
diff --git a/putty.h b/putty.h
index 20cff54..b372d4a 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -472,6 +472,7 @@ struct config_tag {
     char ttymodes[768];                       /* MODE\tVvalue\0MODE\tA\0\0 */
     char environmt[1024];             /* VAR\tvalue\0VAR\tvalue\0\0 */
     char username[100];
+    int username_from_env;
     char localusername[100];
     int rfc_environ;
     int passive_telnet;
@@ -790,6 +791,7 @@ void random_destroy_seed(void);
  */
 Backend *backend_from_name(const char *name);
 Backend *backend_from_proto(int proto);
+int get_remote_username(Config *cfg, char *user, size_t len);
 char *save_settings(char *section, Config * cfg);
 void save_open_settings(void *sesskey, Config *cfg);
 void load_settings(char *section, Config * cfg);
index c9e7c5e..c392fa0 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -182,12 +182,14 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
     {
        char z = 0;
        char *p;
+       char ruser[sizeof(cfg->username)];
+       (void) get_remote_username(cfg, ruser, sizeof(ruser));
        sk_write(rlogin->s, &z, 1);
        sk_write(rlogin->s, cfg->localusername,
                 strlen(cfg->localusername));
        sk_write(rlogin->s, &z, 1);
-       sk_write(rlogin->s, cfg->username,
-                strlen(cfg->username));
+       sk_write(rlogin->s, ruser,
+                strlen(ruser));
        sk_write(rlogin->s, &z, 1);
        sk_write(rlogin->s, cfg->termtype,
                 strlen(cfg->termtype));
index 2692676..7ecd561 100644 (file)
@@ -75,6 +75,25 @@ Backend *backend_from_proto(int proto)
     return NULL;
 }
 
+int get_remote_username(Config *cfg, char *user, size_t len)
+{
+    if (*cfg->username) {
+       strncpy(user, cfg->username, len);
+       user[len-1] = '\0';
+    } else {
+       if (cfg->username_from_env) {
+           /* Use local username. */
+           char *luser = get_username();
+           strncpy(user, luser, len);
+           user[len-1] = '\0';
+           sfree(luser);
+       } else {
+           *user = '\0';
+       }
+    }
+    return (*user != '\0');
+}
+
 static void gpps(void *handle, const char *name, const char *def,
                 char *val, int len)
 {
@@ -316,6 +335,7 @@ void save_open_settings(void *sesskey, Config *cfg)
     write_setting_s(sesskey, "ProxyTelnetCommand", cfg->proxy_telnet_command);
     wmap(sesskey, "Environment", cfg->environmt, lenof(cfg->environmt));
     write_setting_s(sesskey, "UserName", cfg->username);
+    write_setting_i(sesskey, "UserNameFromEnvironment", cfg->username_from_env);
     write_setting_s(sesskey, "LocalUserName", cfg->localusername);
     write_setting_i(sesskey, "NoPTY", cfg->nopty);
     write_setting_i(sesskey, "Compression", cfg->compression);
@@ -584,7 +604,8 @@ void load_open_settings(void *sesskey, Config *cfg)
     gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
         cfg->proxy_telnet_command, sizeof(cfg->proxy_telnet_command));
     gppmap(sesskey, "Environment", "", cfg->environmt, lenof(cfg->environmt));
-    gpps(sesskey, "UserName", get_username(), cfg->username, sizeof(cfg->username));
+    gpps(sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
+    gppi(sesskey, "UserNameFromEnvironment", 0, &cfg->username_from_env);
     gpps(sesskey, "LocalUserName", "", cfg->localusername,
         sizeof(cfg->localusername));
     gppi(sesskey, "NoPTY", 0, &cfg->nopty);
diff --git a/ssh.c b/ssh.c
index d30626d..9f2d011 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -3361,7 +3361,8 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
 
     fflush(stdout); /* FIXME eh? */
     {
-       if (!*ssh->cfg.username) {
+       if (!get_remote_username(&ssh->cfg, s->username,
+                                sizeof(s->username))) {
            int ret; /* need not be kept over crReturn */
            s->cur_prompt = new_prompts(ssh->frontend);
            s->cur_prompt->to_server = TRUE;
@@ -3386,9 +3387,6 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
            memcpy(s->username, s->cur_prompt->prompts[0]->result,
                   lenof(s->username));
            free_prompts(s->cur_prompt);
-       } else {
-           strncpy(s->username, ssh->cfg.username, sizeof(s->username));
-           s->username[sizeof(s->username)-1] = '\0';
        }
 
        send_packet(ssh, SSH1_CMSG_USER, PKT_STR, s->username, PKT_END);
@@ -7295,7 +7293,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
             * with change_username turned off we don't try to get
             * it again.
             */
-       } else if (!*ssh->cfg.username) {
+       } else if (!get_remote_username(&ssh->cfg, s->username,
+                                       sizeof(s->username))) {
            int ret; /* need not be kept over crReturn */
            s->cur_prompt = new_prompts(ssh->frontend);
            s->cur_prompt->to_server = TRUE;
@@ -7323,8 +7322,6 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
            free_prompts(s->cur_prompt);
        } else {
            char *stuff;
-           strncpy(s->username, ssh->cfg.username, sizeof(s->username));
-           s->username[sizeof(s->username)-1] = '\0';
            if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
                stuff = dupprintf("Using username \"%s\".\r\n", s->username);
                c_write_str(ssh, stuff);
index 4f0a36f..20ccc83 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -466,29 +466,33 @@ static void process_subneg(Telnet telnet)
                    b[n++] = *e++;
                e++;
            }
-           if (*telnet->cfg.username) {
-               b[n++] = var;
-               b[n++] = 'U';
-               b[n++] = 'S';
-               b[n++] = 'E';
-               b[n++] = 'R';
-               b[n++] = value;
-               e = telnet->cfg.username;
-               while (*e)
-                   b[n++] = *e++;
+           {
+               char user[sizeof(telnet->cfg.username)];
+               (void) get_remote_username(&telnet->cfg, user, sizeof(user));
+               if (*user) {
+                   b[n++] = var;
+                   b[n++] = 'U';
+                   b[n++] = 'S';
+                   b[n++] = 'E';
+                   b[n++] = 'R';
+                   b[n++] = value;
+                   e = user;
+                   while (*e)
+                       b[n++] = *e++;
+               }
+               b[n++] = IAC;
+               b[n++] = SE;
+               telnet->bufsize = sk_write(telnet->s, (char *)b, n);
+               logbuf = dupprintf("client:\tSB %s IS %s%s%s%s",
+                                  telopt(telnet->sb_opt),
+                                  *user ? "USER=" : "",
+                                  user,
+                                  *user ? " " : "",
+                                  n == 6 ? "<nothing>" :
+                                  (*telnet->cfg.environmt ? "<stuff>" : ""));
+               logevent(telnet->frontend, logbuf);
+               sfree(logbuf);
            }
-           b[n++] = IAC;
-           b[n++] = SE;
-           telnet->bufsize = sk_write(telnet->s, (char *)b, n);
-           logbuf = dupprintf("client:\tSB %s IS %s%s%s%s",
-                              telopt(telnet->sb_opt),
-                              *telnet->cfg.username ? "USER=" : "",
-                              telnet->cfg.username,
-                              *telnet->cfg.username ? " " : "",
-                              n == 6 ? "<nothing>" :
-                              (*telnet->cfg.environmt ? "<stuff>" : ""));
-           logevent(telnet->frontend, logbuf);
-           sfree(logbuf);
        }
        break;
     }
index fc0b837..4a3c6aa 100644 (file)
@@ -1,6 +1,10 @@
 /*
- * winhelp.h - define Windows Help context names. These match up with
- * the \cfg{winhelp-topic} directives in the Halibut source.
+ * winhelp.h - define Windows Help context names.
+ * Each definition has the form "winhelp-topic:halibut-topic", where:
+ *  - "winhelp-topic" matches up with the \cfg{winhelp-topic} directives
+ *    in the Halibut source, and is used for WinHelp;
+ *  - "halibut-topic" matches up with the Halibut keywords in the source,
+ *    and is used for HTML Help.
  */
 
 /* Maximum length for WINHELP_CTX_foo strings */
@@ -70,6 +74,7 @@
 #define WINHELP_CTX_connection_termtype "connection.termtype:config-termtype"
 #define WINHELP_CTX_connection_termspeed "connection.termspeed:config-termspeed"
 #define WINHELP_CTX_connection_username "connection.username:config-username"
+#define WINHELP_CTX_connection_username_from_env "connection.usernamefromenv:config-username-from-env"
 #define WINHELP_CTX_connection_keepalive "connection.keepalive:config-keepalive"
 #define WINHELP_CTX_connection_nodelay "connection.nodelay:config-nodelay"
 #define WINHELP_CTX_connection_ipversion "connection.ipversion:config-address-family"