diff --git a/Recipe b/Recipe index e065c37d..b3739b97 100644 --- a/Recipe +++ b/Recipe @@ -235,12 +235,12 @@ TERMINAL = terminal wcwidth ldiscucs logging tree234 minibidi # GUI front end and terminal emulator (putty, puttytel). GUITERM = TERMINAL window windlg winctrls sizetip winprint winutils - + wincfg sercfg winhelp winjump + + wincfg sercfg winhelp winjump sessprep # Same thing on Unix. UXTERM = TERMINAL uxcfg sercfg uxucs uxprint timing callback miscucs GTKTERM = UXTERM gtkwin gtkcfg gtkdlg gtkfont gtkcols gtkmisc xkeysym - + x11misc gtkcomm + + x11misc gtkcomm sessprep GTKMAIN = gtkmain cmdline # Non-SSH back ends (putty, puttytel, plink). @@ -298,7 +298,7 @@ U_BE_NOSSH = be_nos_s uxser nocproxy putty : [G] GUITERM NONSSH WINSSH W_BE_ALL WINMISC winx11 putty.res LIBS puttytel : [G] GUITERM NONSSH W_BE_NOSSH WINMISC puttytel.res nogss LIBS plink : [C] winplink wincons NONSSH WINSSH W_BE_ALL logging WINMISC - + winx11 plink.res winnojmp noterm LIBS + + winx11 plink.res winnojmp sessprep noterm LIBS pscp : [C] pscp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC + pscp.res winnojmp LIBS psftp : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC @@ -325,7 +325,7 @@ puttytel : [X] GTKTERM uxmisc misc ldisc settings uxsel U_BE_NOSSH + nogss GTKMAIN plink : [U] uxplink uxcons NONSSH UXSSH U_BE_ALL logging UXMISC uxsignal - + ux_x11 noterm uxnogtk cmdline + + ux_x11 noterm uxnogtk sessprep cmdline PUTTYGEN_UNIX = sshrsag sshdssg sshprime sshdes sshbn sshmd5 version + sshrand uxnoise sshsha misc sshrsa sshdss uxcons uxstore uxmisc diff --git a/putty.h b/putty.h index ba7e123a..3ca82b62 100644 --- a/putty.h +++ b/putty.h @@ -1176,6 +1176,11 @@ void pinger_free(Pinger); int conf_launchable(Conf *conf); char const *conf_dest(Conf *conf); +/* + * Exports from sessprep.c. + */ +void prepare_session(Conf *conf); + /* * Exports from sercfg.c. */ diff --git a/sessprep.c b/sessprep.c new file mode 100644 index 00000000..15d830d9 --- /dev/null +++ b/sessprep.c @@ -0,0 +1,84 @@ +/* + * sessprep.c: centralise some preprocessing done on Conf objects + * before launching them. + */ + +#include "putty.h" + +void prepare_session(Conf *conf) +{ + char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); + char *host = hostbuf; + char *p, *q; + + /* + * Trim leading whitespace from the hostname. + */ + host += strspn(host, " \t"); + + /* + * See if host is of the form user@host, and separate out the + * username if so. + */ + if (host[0] != '\0') { + /* + * Use strrchr, in case the _username_ in turn is of the form + * user@host, which has been known. + */ + char *atsign = strrchr(host, '@'); + if (atsign) { + *atsign = '\0'; + conf_set_str(conf, CONF_username, host); + host = atsign + 1; + } + } + + /* + * Trim a colon suffix off the hostname if it's there, and discard + * the text after it. + * + * The exact reason why we _ignore_ this text, rather than + * treating it as a port number, is unfortunately lost in the + * mists of history: the commit which originally introduced this + * change on 2001-05-06 was clear on _what_ it was doing but + * didn't bother to explain _why_. But I [SGT, 2017-12-03] suspect + * it has to do with priority order: what should a saved session + * do if its CONF_host contains 'server.example.com:123' and its + * CONF_port contains 456? If CONF_port contained the _default_ + * port number then it might be a good guess that the colon suffix + * on the host name was intended to override that, but you don't + * really want to get into making heuristic judgments on that + * basis. + * + * (Then again, you could just as easily make the same argument + * about whether a 'user@' prefix on the host name should override + * CONF_username, which this code _does_ do. I don't have a good + * answer, sadly. Both these pieces of behaviour have been around + * for years and it would probably cause subtle breakage in all + * sorts of long-forgotten scripting to go changing things around + * now.) + * + * In order to protect unbracketed IPv6 address literals against + * this treatment, we do not make this change at all if there's + * _more_ than one (un-IPv6-bracketed) colon. + */ + p = host_strchr(host, ':'); + if (p && p != host_strrchr(host, ':')) { + *p = '\0'; + } + + /* + * Remove any remaining whitespace. + */ + p = hostbuf; + q = host; + while (*q) { + if (*q != ' ' && *q != '\t') + *p++ = *q; + q++; + } + *p = '\0'; + + conf_set_str(conf, CONF_host, hostbuf); + sfree(hostbuf); +} diff --git a/unix/uxplink.c b/unix/uxplink.c index 11ca7d1d..ebf14458 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -823,63 +823,7 @@ int main(int argc, char **argv) usage(); } - /* - * Muck about with the hostname in various ways. - */ - { - char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); - char *host = hostbuf; - char *p, *q; - - /* - * Trim leading whitespace. - */ - host += strspn(host, " \t"); - - /* - * See if host is of the form user@host, and separate out - * the username if so. - */ - if (host[0] != '\0') { - char *atsign = strrchr(host, '@'); - if (atsign) { - *atsign = '\0'; - conf_set_str(conf, CONF_username, host); - host = atsign + 1; - } - } - - /* - * Trim a colon suffix off the hostname if it's there. In - * order to protect unbracketed IPv6 address literals - * against this treatment, we do not do this if there's - * _more_ than one colon. - */ - { - char *c = host_strchr(host, ':'); - - if (c) { - char *d = host_strchr(c+1, ':'); - if (!d) - *c = '\0'; - } - } - - /* - * Remove any remaining whitespace. - */ - p = hostbuf; - q = host; - while (*q) { - if (*q != ' ' && *q != '\t') - *p++ = *q; - q++; - } - *p = '\0'; - - conf_set_str(conf, CONF_host, hostbuf); - sfree(hostbuf); - } + prepare_session(conf); /* * Perform command-line overrides on session configuration. diff --git a/windows/window.c b/windows/window.c index 30cbbdc9..1bef1daa 100644 --- a/windows/window.c +++ b/windows/window.c @@ -606,63 +606,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) cleanup_exit(0); } - /* - * Muck about with the hostname in various ways. - */ - { - char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); - char *host = hostbuf; - char *p, *q; - - /* - * Trim leading whitespace. - */ - host += strspn(host, " \t"); - - /* - * See if host is of the form user@host, and separate - * out the username if so. - */ - if (host[0] != '\0') { - char *atsign = strrchr(host, '@'); - if (atsign) { - *atsign = '\0'; - conf_set_str(conf, CONF_username, host); - host = atsign + 1; - } - } - - /* - * Trim a colon suffix off the hostname if it's there. In - * order to protect unbracketed IPv6 address literals - * against this treatment, we do not do this if there's - * _more_ than one colon. - */ - { - char *c = host_strchr(host, ':'); - - if (c) { - char *d = host_strchr(c+1, ':'); - if (!d) - *c = '\0'; - } - } - - /* - * Remove any remaining whitespace. - */ - p = hostbuf; - q = host; - while (*q) { - if (*q != ' ' && *q != '\t') - *p++ = *q; - q++; - } - *p = '\0'; - - conf_set_str(conf, CONF_host, hostbuf); - sfree(hostbuf); - } + prepare_session(conf); } if (!prev) { diff --git a/windows/winplink.c b/windows/winplink.c index 65dd7702..959db5b0 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -498,63 +498,7 @@ int main(int argc, char **argv) usage(); } - /* - * Muck about with the hostname in various ways. - */ - { - char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); - char *host = hostbuf; - char *p, *q; - - /* - * Trim leading whitespace. - */ - host += strspn(host, " \t"); - - /* - * See if host is of the form user@host, and separate out - * the username if so. - */ - if (host[0] != '\0') { - char *atsign = strrchr(host, '@'); - if (atsign) { - *atsign = '\0'; - conf_set_str(conf, CONF_username, host); - host = atsign + 1; - } - } - - /* - * Trim a colon suffix off the hostname if it's there. In - * order to protect unbracketed IPv6 address literals - * against this treatment, we do not do this if there's - * _more_ than one colon. - */ - { - char *c = host_strchr(host, ':'); - - if (c) { - char *d = host_strchr(c+1, ':'); - if (!d) - *c = '\0'; - } - } - - /* - * Remove any remaining whitespace. - */ - p = hostbuf; - q = host; - while (*q) { - if (*q != ' ' && *q != '\t') - *p++ = *q; - q++; - } - *p = '\0'; - - conf_set_str(conf, CONF_host, hostbuf); - sfree(hostbuf); - } + prepare_session(conf); /* * Perform command-line overrides on session configuration.