From: jacob Date: Mon, 24 Nov 2008 17:51:42 +0000 (+0000) Subject: New option to allow use of the local OS username for login to the remote side X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/471c20b0e70634fcd864da81a502d74c11aa41ee New option to allow use of the local OS username for login to the remote side 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 --- diff --git a/config.c b/config.c index 67a018fe..09c77d57 100644 --- 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"); diff --git a/doc/config.but b/doc/config.but index 96f5dbe4..27704ee9 100644 --- a/doc/config.but +++ b/doc/config.but @@ -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 20cff543..b372d4a3 100644 --- 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); diff --git a/rlogin.c b/rlogin.c index c9e7c5ec..c392fa0a 100644 --- 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)); diff --git a/settings.c b/settings.c index 26926769..7ecd5610 100644 --- a/settings.c +++ b/settings.c @@ -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 d30626dc..9f2d0111 100644 --- 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); diff --git a/telnet.c b/telnet.c index 4f0a36fe..20ccc83e 100644 --- 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 ? "" : + (*telnet->cfg.environmt ? "" : "")); + 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 ? "" : - (*telnet->cfg.environmt ? "" : "")); - logevent(telnet->frontend, logbuf); - sfree(logbuf); } break; } diff --git a/windows/winhelp.h b/windows/winhelp.h index fc0b8370..4a3c6aaa 100644 --- a/windows/winhelp.h +++ b/windows/winhelp.h @@ -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"