Bug 2956 - using "sftp root@[2001::16%eth0]", output error: Could not resolve hostname: Name or service not known
Summary: using "sftp root@[2001::16%eth0]", output error: Could not resolve hostname: ...
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sftp (show other bugs)
Version: 7.9p1
Hardware: ix86 Linux
: P5 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-01-22 18:13 AEDT by xuchunmei
Modified: 2019-01-22 18:13 AEDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description xuchunmei 2019-01-22 18:13:53 AEDT
when using sftp to connect ipv6 address without path, error happens like this:
sftp root@[2001::16%eth0]

ssh: Could not resolve hostname [2001::16%eth0]: Name
or service not known
Connection closed.
Connection closed

openssh version is:
openssh-clients-7.8p1-3.fc29.x86_64
OS is fedora29 x86

i try to analyse the error output,
when parse_user_host_path, colon funciton:
char *
colon(char *cp)
{
        int flag = 0;

        if (*cp == ':')         /* Leading colon is part of file name. */
                return NULL;
        if (*cp == '[')
                flag = 1;

        for (; *cp; ++cp) {
                if (*cp == '@' && *(cp+1) == '[')
                        flag = 1;
                if (*cp == ']' && *(cp+1) == ':' && flag)
                        return (cp+1);
                if (*cp == ':' && !flag)
                        return (cp);
                if (*cp == '/')
                        return NULL;
        }
        return NULL;
}

after ']' there must be ':', otherwise return NULL, then the whole arg "root@[2001::16%eth0]" be treated as a plain hostname, host 
resolv failed.

here is my solution:
---
 misc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/misc.c b/misc.c
index bdc06fd..84dc451 100644
--- a/misc.c
+++ b/misc.c
@@ -557,6 +557,8 @@ colon(char *cp)
            flag = 1;
        if (*cp == ']' && *(cp+1) == ':' && flag)
            return (cp+1);
+       if (*cp == ']' && *(cp+1) == '\0' && flag)
+           return (cp+1);
        if (*cp == ':' && !flag)
            return (cp);
        if (*cp == '/')
-- 

please check.