From 71a3e7da9e9b1fc0e95c9d4e02a63fb1c3eed57e Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 9 Mar 2019 08:10:02 +0000 Subject: [PATCH] host_strduptrim: support RFC 4007 address literals. I'd never even heard of these before. We don't need to do anything unusual with these when passing them to our own getaddrinfo, but host_strduptrim considered them a violation of its expectations about what an IPv6 literal looked like, and hence wasn't stripping square brackets off one. So a port-forwarding command-line option such as '-L 12345:[fe80::%eth0]:22' would cause the address string in the direct-tcpip CHANNEL_OPEN packet to be "[fe80::%eth0]" instead of the correct "fe80::%eth0", leading to getaddrinfo failure on the SSH server side. --- utils.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/utils.c b/utils.c index cf02e8aa..a85a5d29 100644 --- a/utils.c +++ b/utils.c @@ -207,11 +207,21 @@ char *host_strduptrim(const char *s) break; p++; } + if (*p == '%') { + /* + * This delimiter character introduces an RFC 4007 scope + * id suffix (e.g. suffixing the address literal with + * %eth1 or %2 or some such). There's no syntax + * specification for the scope id, so just accept anything + * except the closing ]. + */ + p += strcspn(p, "]"); + } if (*p == ']' && !p[1] && colons > 1) { /* * This looks like an IPv6 address literal (hex digits and - * at least two colons, contained in square brackets). - * Trim off the brackets. + * at least two colons, plus optional scope id, contained + * in square brackets). Trim off the brackets. */ return dupprintf("%.*s", (int)(p - (s+1)), s+1); }