diff options
Diffstat (limited to 'utils/sessprep.c')
-rw-r--r-- | utils/sessprep.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/utils/sessprep.c b/utils/sessprep.c new file mode 100644 index 00000000..95e7b658 --- /dev/null +++ b/utils/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); +} |