pkg / sftp

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

sftp.NewClient returns an error "packet too long" #529

Closed chrplr closed 1 year ago

chrplr commented 1 year ago

In the following code, sftp.newclient() returns an error "packet too long". This is not simply a connection issue as I can open a ssh connection and use run to display execute a command on the remote server. Below, I have pasted code from dlv showing that the error arises from github.com/pkg/sftp.recvPacket() at line 272.

Passing the option sftp.MaxPacketChecked(1024) or not, has no effect.

I suspect it must be a silly problem in my code, not pkg/sftp, but I do not see the bug.

package main

import (
    "fmt"
    "log"
    "bytes"
    "github.com/pkg/sftp"
    "golang.org/x/crypto/ssh"
    "os"
)

type Params struct  {
    server string
    login string
    passwd string
}

var param = Params{"xxxx", "yyyy", "zzzz"}

func main() {

    config := &ssh.ClientConfig{
        User: param.login,
        Auth: []ssh.AuthMethod{
            ssh.Password(param.passwd),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    client, err := ssh.Dial("tcp", param.server, config)
    if err != nil {
        log.Fatalf("ssh.dial %s", err)
    }
    defer client.Close()

    session, err := client.NewSession()
    if err != nil {
        log.Fatalf("client.Newsession %s", err)
    }
    defer session.Close()

    var buff bytes.Buffer
    session.Stdout = &buff
    if err := session.Run("ls -la"); err != nil {
        log.Fatalf("session.Run %s", err)
    }
    fmt.Println(buff.String())

    sftp, err := sftp.NewClient(client, sftp.MaxPacketChecked(1024))
    if err != nil {
        log.Fatalf("sftp.newclient %s",err)
    }
    defer sftp.Close()

    srcPath := "AAAAAA"
    dstPath := "BBBBBB"

    // Open the source file
    srcFile, err := os.Open(srcPath)
    if err != nil {
        fmt.Println("open src ", err)
    }
    defer srcFile.Close()

    // Create the destination file
    dstFile, err := sftp.Create(dstPath)
    if err != nil {
        fmt.Println("sftp.Create ", err)
    }
    defer dstFile.Close()

    // write to file
    if _, err := dstFile.ReadFrom(srcFile); err != nil {
        fmt.Println("transf")
        fmt.Println(err)
    }

}

github.com/pkg/sftp.recvPacket() /home/cp983411/go/pkg/mod/github.com/pkg/sftp@v1.13.5/packet.go:272 (PC: 0x65512d) 267: } 268: if , err := io.ReadFull(r, b[:4]); err != nil { 269: return 0, nil, err 270: } 271: length, := unmarshalUint32(b) => 272: if length > maxMsgLength { 273: debug("recv packet %d bytes too long", length) 274: return 0, nil, errLongPacket 275: } 276: if length == 0 { 277: debug("recv packet of 0 bytes too short") (dlv) p b []uint8 len: 4, cap: 4, [32,95,95,95] (dlv) p length 543121247

puellanivis commented 1 year ago

Likely, what is happening is that the remote service is has so many extensions, that it oversteps the builtin 256 kibibyte maximum packet size of the packet reader.

chrplr commented 1 year ago

Thanks!

I did not configure sftp manually (I only installed opensshserver under linux ubuntu 20.04)

But I did something I should have tried before, that is, connect from the command line, and the issue is already there (see below). So it is indeed a problem with the configuration of the sftp server. Sorry for opening this issue. I close it. HAve a nice day.

PS: explanation => https://www.pcwdld.com/troubleshooting-received-message-too-long (The starter bash files need to be quiet to not interfere with the SFTP (or SCP2) protocol.). The problem was solved by adding [[ $- == *i* ]] || return on the first line of ~/.bashrc

> sftp localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
xxxxxx@localhost's password: 
Received message too long 543121247