pkg / sftp

SFTP support for the go.crypto/ssh package
BSD 2-Clause "Simplified" License
1.52k stars 380 forks source link

sftp connect Cannot continue to judge **sshFxpVersion** and **sftpProtocolVersion** #371

Closed vgopher closed 4 years ago

vgopher commented 4 years ago
func (c *Client) recvVersion() error {
    typ, data, err := c.recvPacket(0)
    if err != nil {
        return err
    }
    if typ != sshFxpVersion {
        return &unexpectedPacketErr{sshFxpVersion, typ}
    }
    version, _ := unmarshalUint32(data)
    if version != sftpProtocolVersion {
        return &unexpectedVersionErr{sftpProtocolVersion, version}
    }
    return nil
} 

if c.recvPacket(0) result === 0 [0/0]0x0 EOF

Cannot continue to judge sshFxpVersion and sftpProtocolVersion

Create NewSession: 0xc0000c4090 Create New RequestSubsystem: 0xc0000c4090 Create New StdinPipe: (0x61d1e0,0xc000194020) Create New StdoutPipe: (0x61d1e0,0xc000194020) NewClientPipe sftp new client: 0xc00019a000 NewClientPipe sftp.applyOptions: 0xc00019a000 NewClientPipe sftp.sendInit: 0xc00019a000 packet recvPacket first ReadFull error: EOF

Client recvVersion: 0 [0/0]0x0 EOF

Client recvVersion recvPacket: EOF NewClientPipe sftp.recvVersion() error: EOF

puellanivis commented 4 years ago

The EOF error looks like you’re gettting an unexpected disconnect event between initialization and receive version. This could be because the server is rejecting the Protocol Version 3 that we’re sending in the sendInit? Or maybe the server is requiring an extension that is not being sent at initialization?

vgopher commented 4 years ago

But if use linux shell command-line tool: scp, you can send the file to same server(SUSE Linux Enterprise Server 12 [Linux local-server 4.12.14-94.41-default #1 SMP Wed Oct 31 12:25:04 UTC 2018 (3090901) x86_64 x86_64 x86_64 GNU/Linux]), without any exception errors. Does scp support more protocol versions?

puellanivis commented 4 years ago

I don’t know any of this information that you’re asking about. You would need to look at a debugging log dump of packets being sent from scp to the remote server, and what the server is sending back.

Anything I could do on my own side would only be helpful by pure luck. There is no guarantee that my server, or my version of scp is the same as yours.

vgopher commented 4 years ago

I try to use ssh session.run scp command-line,is work! Not a perfect solution, but i think it's more important to be able to solve the problem.

if err.Error() == "EOF" {
    logger.Warnf("Create sftp client EOF error: %v:%v, try use cmd scp mode.\n",ip,port)
    session,err := sshConn.NewSession()
    if err != nil {
        logger.Errorf("ssh connect error: %v %v\n", ip, err.Error())
        return err
    }
    defer session.Close()
    w,err := session.StdinPipe()
    if err != nil {
        logger.Errorf("session create StdinPipe error: %v %v\n", ip, err.Error())
        return err
    }
    srcFile, err := os.Open(upPath + localFileName)
    if err != nil {
        logger.Errorf("open src file error: %v %v\n", ip, err.Error())
        return err
    }
    fileInfo, err := os.Stat(upPath + localFileName)
    if err != nil {
        logger.Errorf("get file info error: %v %v\n", ip, err.Error())
        return err
    }
    go func() {
        _,err := fmt.Fprintln(w, "C0644", fileInfo.Size(), localFileName)
        if err != nil {
            logger.Errorf("write data to io.writer error: %v %v\n", ip, err.Error())
            return
        }
        _,err = io.CopyN(w, srcFile, fileInfo.Size())
        if err != nil {
            logger.Errorf("write data io copy error: %v %v\n", ip, err.Error())
            return
        }
        _,err = fmt.Fprint(w, "\x00")
        if err != nil {
            logger.Errorf("write data file eof error: %v %v\n", ip, err.Error())
            return
        }
        w.Close()
    }()
    if err := session.Run(fmt.Sprintf("/usr/bin/scp -qrt %s", remoteDir)); err != nil {
        logger.Errorf("error: %v\n", err)
        return err
    } else {
        logger.Debugf("%v info: %v\n", sshConn.RemoteAddr(),localFileName)
        return nil
    }

}
drakkan commented 4 years ago

I think this should not be closed, can you provide us a way to reproduce the issue? Are you using a proprietary SSH server? Can you share server details? thank you