]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Use the new host_str* functions to improve IPv6 literal support.
authorSimon Tatham <anakin@pobox.com>
Sat, 25 Jan 2014 15:58:54 +0000 (15:58 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 25 Jan 2014 15:58:54 +0000 (15:58 +0000)
I've gone through everywhere we handle host names / addresses (on
command lines, in PuTTY config, in port forwarding, in X display
names, in host key storage...) and tried to make them handle IPv6
literals sensibly, by using the host_str* functions I introduced in my
previous commit. Generally it's now OK to use a bracketed IPv6 literal
anywhere a hostname might have been valid; in a few cases where no
ambiguity exists (e.g. no :port suffix is permitted anyway)
unbracketed IPv6 literals are also acceptable.

[originally from svn r10120]

14 files changed:
cmdline.c
config.c
pscp.c
raw.c
rlogin.c
ssh.c
telnet.c
unix/uxnet.c
unix/uxplink.c
unix/uxputty.c
windows/window.c
windows/winnet.c
windows/winplink.c
x11fwd.c

index bafb939914af4ca0ea24165e40d104fcadff2bd1..0c7ef4c91c98ad721403b186d818881587600a16 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -261,9 +261,9 @@ int cmdline_process_param(char *p, char *value, int need_save, Conf *conf)
 
             type = p[1];               /* 'L' or 'R' */
 
-           q = qq = strchr(value, ':');
+           q = qq = host_strchr(value, ':');
            while (qq) {
-               char *qqq = strchr(qq+1, ':');
+               char *qqq = host_strchr(qq+1, ':');
                if (qqq)
                    q = qq;
                qq = qqq;
@@ -301,7 +301,7 @@ int cmdline_process_param(char *p, char *value, int need_save, Conf *conf)
        UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
        SAVEABLE(0);
 
-       portp = strchr(value, ':');
+       portp = host_strchr(value, ':');
        if (!portp) {
            cmdline_error("-nc expects argument of form 'host:port'");
            return ret;
index 5d0193440fd31aadc58bac1d9832c2b7a88085e1..1596c2f1d97d3ccbde0acdd37c7a6e1c5cfcd944 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1146,7 +1146,7 @@ static void portfwd_handler(union control *ctrl, void *dlg,
            }
            if (*type != 'D') {
                val = dlg_editbox_get(pfd->destbox, dlg);
-               if (!*val || !strchr(val, ':')) {
+               if (!*val || !host_strchr(val, ':')) {
                    dlg_error_msg(dlg,
                                  "You need to specify a destination address\n"
                                  "in the form \"host.name:port\"");
diff --git a/pscp.c b/pscp.c
index 484c348e5e3ee3125eace28c5cb1d2f9b2ff6e6f..f63e6b5986538acfe18ecdbd80281ea800d812f9 100644 (file)
--- a/pscp.c
+++ b/pscp.c
@@ -370,15 +370,9 @@ static void do_cmd(char *host, char *user, char *cmd)
        bump("Empty host name");
 
     /*
-     * Remove fiddly bits of address: remove a colon suffix, and
-     * the square brackets around an IPv6 literal address.
+     * Remove a colon suffix.
      */
-    if (host[0] == '[') {
-       host++;
-       host[strcspn(host, "]")] = '\0';
-    } else {
-       host[strcspn(host, ":")] = '\0';
-    }
+    host[host_strcspn(host, ":")] = '\0';
 
     /*
      * If we haven't loaded session details already (e.g., from -load),
@@ -613,17 +607,7 @@ static char *colon(char *str)
     if (str[0] == '\0' || str[0] == ':' ||
         (str[0] != '[' && str[1] == ':'))
        return (NULL);
-    while (*str != '\0' && *str != ':' && *str != '/' && *str != '\\') {
-       if (*str == '[') {
-           /* Skip over IPv6 literal addresses
-            * (eg: 'jeroen@[2001:db8::1]:myfile.txt') */
-           char *ipv6_end = strchr(str, ']');
-           if (ipv6_end) {
-               str = ipv6_end;
-           }
-       }
-       str++;
-    }
+    str += host_strcspn(str, ":/\\");
     if (*str == ':')
        return (str);
     else
diff --git a/raw.c b/raw.c
index 1d9f854cd65f77e1b9b7cec754a58462133aaa2e..a7fbbc5cc5f32e8c23feae149dc53c5a3193795a 100644 (file)
--- a/raw.c
+++ b/raw.c
@@ -185,15 +185,10 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
 
        sfree(*realhost);
        *realhost = dupstr(loghost);
-       colon = strrchr(*realhost, ':');
-       if (colon) {
-           /*
-            * FIXME: if we ever update this aspect of ssh.c for
-            * IPv6 literal management, this should change in line
-            * with it.
-            */
+
+       colon = host_strrchr(*realhost, ':');
+       if (colon)
            *colon++ = '\0';
-       }
     }
 
     return NULL;
index f582f0c0d736171e6215e82c13c7b8d3a2993ff9..3c86eee8575f20981ae725ed22fe71ef6ec334c7 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -226,15 +226,10 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
 
        sfree(*realhost);
        *realhost = dupstr(loghost);
-       colon = strrchr(*realhost, ':');
-       if (colon) {
-           /*
-            * FIXME: if we ever update this aspect of ssh.c for
-            * IPv6 literal management, this should change in line
-            * with it.
-            */
+
+       colon = host_strrchr(*realhost, ':');
+       if (colon)
            *colon++ = '\0';
-       }
     }
 
     /*
diff --git a/ssh.c b/ssh.c
index 8bcb1e8564a10c2eca99fe03661c48116a0594d9..b86f0de1e41c72f3409c35972c4770c36163cdcd 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -3411,25 +3411,27 @@ static const char *connect_to_host(Ssh ssh, char *host, int port,
     
     loghost = conf_get_str(ssh->conf, CONF_loghost);
     if (*loghost) {
-       char *colon;
+       char *tmphost;
+        char *colon;
 
-       ssh->savedhost = dupstr(loghost);
+        tmphost = dupstr(loghost);
        ssh->savedport = 22;           /* default ssh port */
 
        /*
-        * A colon suffix on savedhost also lets us affect
+        * A colon suffix on the hostname string also lets us affect
         * savedport.
-        * 
-        * (FIXME: do something about IPv6 address literals here.)
         */
-       colon = strrchr(ssh->savedhost, ':');
+       colon = host_strrchr(tmphost, ':');
        if (colon) {
            *colon++ = '\0';
            if (*colon)
                ssh->savedport = atoi(colon);
        }
+
+        ssh->savedhost = host_strduptrim(tmphost);
+        sfree(tmphost);
     } else {
-       ssh->savedhost = dupstr(host);
+       ssh->savedhost = host_strduptrim(host);
        if (port < 0)
            port = 22;                 /* default ssh port */
        ssh->savedport = port;
@@ -4915,13 +4917,15 @@ static void ssh_setup_portfwd(Ssh ssh, Conf *conf)
        if (*kp == 'L' || *kp == 'R')
            type = *kp++;
 
-       if ((kp2 = strchr(kp, ':')) != NULL) {
+       if ((kp2 = host_strchr(kp, ':')) != NULL) {
            /*
             * There's a colon in the middle of the source port
             * string, which means that the part before it is
             * actually a source address.
             */
-           saddr = dupprintf("%.*s", (int)(kp2 - kp), kp);
+           char *saddr_tmp = dupprintf("%.*s", (int)(kp2 - kp), kp);
+            saddr = host_strduptrim(saddr_tmp);
+            sfree(saddr_tmp);
            sports = kp2+1;
        } else {
            saddr = NULL;
@@ -4948,7 +4952,7 @@ static void ssh_setup_portfwd(Ssh ssh, Conf *conf)
         } else {
             /* ordinary forwarding */
            vp = val;
-           vp2 = vp + strcspn(vp, ":");
+           vp2 = vp + host_strcspn(vp, ":");
            host = dupprintf("%.*s", (int)(vp2 - vp), vp);
            if (vp2)
                vp2++;
@@ -11024,7 +11028,11 @@ void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
                    PKT_END);
     } else {
        pktout = ssh2_chanopen_init(c, "direct-tcpip");
-       ssh2_pkt_addstring(pktout, hostname);
+        {
+            char *trimmed_host = host_strduptrim(hostname);
+            ssh2_pkt_addstring(pktout, trimmed_host);
+            sfree(trimmed_host);
+        }
        ssh2_pkt_adduint32(pktout, port);
        /*
         * We make up values for the originator data; partly it's
index 6a56da7745c246137aa57400d247002f9acb93ef..098db292cc05a0c9a64e50db80ecf04954f78a71 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -818,15 +818,10 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
 
        sfree(*realhost);
        *realhost = dupstr(loghost);
-       colon = strrchr(*realhost, ':');
-       if (colon) {
-           /*
-            * FIXME: if we ever update this aspect of ssh.c for
-            * IPv6 literal management, this should change in line
-            * with it.
-            */
+
+       colon = host_strrchr(*realhost, ':');
+       if (colon)
            *colon++ = '\0';
-       }
     }
 
     return NULL;
index 868f9d0a3153f2ca1d5245ff189d61daea7bfe70..1fe78436115878ce98174c6d5d9de8e158db4208 100644 (file)
@@ -221,7 +221,11 @@ SockAddr sk_namelookup(const char *host, char **canonicalname, int address_famil
     hints.ai_addr = NULL;
     hints.ai_canonname = NULL;
     hints.ai_next = NULL;
-    err = getaddrinfo(host, NULL, &hints, &ret->ais);
+    {
+        char *trimmed_host = host_strduptrim(host); /* strip [] on literals */
+        err = getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
+        sfree(trimmed_host);
+    }
     if (err != 0) {
        ret->error = gai_strerror(err);
        return ret;
@@ -868,7 +872,11 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, i
         hints.ai_next = NULL;
        assert(port >= 0 && port <= 99999);
         sprintf(portstr, "%d", port);
-        retcode = getaddrinfo(srcaddr, portstr, &hints, &ai);
+        {
+            char *trimmed_addr = host_strduptrim(srcaddr);
+            retcode = getaddrinfo(trimmed_addr, portstr, &hints, &ai);
+            sfree(trimmed_addr);
+        }
        if (retcode == 0) {
            addr = (union sockaddr_union *)ai->ai_addr;
            addrlen = ai->ai_addrlen;
index 7fbaa36a80d260589f799a74c8bd5de92f3cbf0a..961fcf9a7cbb9fbc532dabf46494edd4c568e3d3 100644 (file)
@@ -705,8 +705,7 @@ int main(int argc, char **argv)
                        q += 2;
                    conf_set_int(conf, CONF_protocol, PROT_TELNET);
                    p = q;
-                   while (*p && *p != ':' && *p != '/')
-                       p++;
+                    p += host_strcspn(p, ":/");
                    c = *p;
                    if (*p)
                        *p++ = '\0';
@@ -847,7 +846,7 @@ int main(int argc, char **argv)
        /*
         * Trim off a colon suffix if it's there.
         */
-       host[strcspn(host, ":")] = '\0';
+       host[host_strcspn(host, ":")] = '\0';
 
        /*
         * Remove any remaining whitespace.
index 1e3604bae67b1f118fbc933b02b56decf809f9e5..c7b0fcb2209c05a97db9be7caf7d6d71ec9543ad 100644 (file)
@@ -76,8 +76,7 @@ int process_nonoption_arg(char *arg, Conf *conf, int *allow_launch)
             q += 2;
         conf_set_int(conf, CONF_protocol, PROT_TELNET);
         p = q;
-        while (*p && *p != ':' && *p != '/')
-            p++;
+        p += host_strcspn(p, ":/");
         c = *p;
         if (*p)
             *p++ = '\0';
index bf212b9ab267df665327b82dc11ce8c58b398b65..bf8d651eb22424056420f391f2bea393e923486f 100644 (file)
@@ -548,8 +548,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
                            q += 2;
                        conf_set_int(conf, CONF_protocol, PROT_TELNET);
                        p = q;
-                       while (*p && *p != ':' && *p != '/')
-                           p++;
+                        p += host_strcspn(p, ":/");
                        c = *p;
                        if (*p)
                            *p++ = '\0';
@@ -614,15 +613,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
             /*
              * Trim a colon suffix off the hostname if it's there. In
-             * order to protect IPv6 address literals against this
-             * treatment, we do not do this if there's _more_ than one
-             * colon.
+             * order to protect unbracketed IPv6 address literals
+             * against this treatment, we do not do this if there's
+             * _more_ than one colon.
              */
             {
-                char *c = strchr(host, ':');
+                char *c = host_strchr(host, ':');
  
                 if (c) {
-                    char *d = strchr(c+1, ':');
+                    char *d = host_strchr(c+1, ':');
                     if (!d)
                         *c = '\0';
                 }
index f4507240ff5497248117a929b90936c6d65596f7..1a5a76f1d1c5dade5e4bab351661ecab8f94f36d 100644 (file)
@@ -527,7 +527,13 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
            memset(&hints, 0, sizeof(hints));
            hints.ai_family = hint_family;
            hints.ai_flags = AI_CANONNAME;
-           if ((err = p_getaddrinfo(host, NULL, &hints, &ret->ais)) == 0)
+            {
+                /* strip [] on IPv6 address literals */
+                char *trimmed_host = host_strduptrim(host);
+                err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
+                sfree(trimmed_host);
+            }
+           if (err == 0)
                ret->resolved = TRUE;
        } else
 #endif
index ac7069a2e3fd966e5b8c376e7a06d9d5e411f685..48232b389280fdf9c48f43753ce60bf34f41116d 100644 (file)
@@ -382,8 +382,7 @@ int main(int argc, char **argv)
                        q += 2;
                    conf_set_int(conf, CONF_protocol, PROT_TELNET);
                    p = q;
-                   while (*p && *p != ':' && *p != '/')
-                       p++;
+                    p += host_strcspn(p, ":/");
                    c = *p;
                    if (*p)
                        *p++ = '\0';
@@ -524,7 +523,7 @@ int main(int argc, char **argv)
        /*
         * Trim off a colon suffix if it's there.
         */
-       host[strcspn(host, ":")] = '\0';
+       host[host_strcspn(host, ":")] = '\0';
 
        /*
         * Remove any remaining whitespace.
index ce572f69a274e3ecd0b5df88d6b91f157ea1a9c3..7ecb4cc27b42cc5c74ef928df3dee64fe69387fd 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -230,7 +230,7 @@ struct X11Display *x11_setup_display(char *display, Conf *conf)
        char *colon, *dot, *slash;
        char *protocol, *hostname;
 
-       colon = strrchr(localcopy, ':');
+       colon = host_strrchr(localcopy, ':');
        if (!colon) {
            sfree(disp);
            sfree(localcopy);
@@ -677,7 +677,7 @@ int x11_get_screen_number(char *display)
 {
     int n;
 
-    n = strcspn(display, ":");
+    n = host_strcspn(display, ":");
     if (!display[n])
        return 0;
     n = strcspn(display, ".");