pkg / sftp

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

Windows issues with current directory and drive changes #444

Open SakiiR opened 3 years ago

SakiiR commented 3 years ago

Hi,

I am encountering issues while trying to implement an SFTP connection over my SSH session ( handled by github.com/gliderlabs/ssh).

Here is the snippet I am using to reproduce the bug:

package main

import (
    "fmt"
    "io"
    "log"
    "os"

    "github.com/gliderlabs/ssh"
    "github.com/pkg/sftp"
)

const PORT uint16 = 31337
const PASSWORD string = "Hello!"

var (
    logger = log.New(os.Stdout, "SFTP: ", 0)
)

func getPasswordHandler(password string) func(ssh.Context, string) bool {
    return (func(ctx ssh.Context, user_password string) bool {
        return user_password == password
    })
}

func SftpHandler(sess ssh.Session) {

    logger.Printf("SFTP attempt")
    debugStream := os.Stdout
    serverOptions := []sftp.ServerOption{
        sftp.WithDebug(debugStream),
    }
    server, err := sftp.NewServer(
        sess,
        serverOptions...,
    )
    if err != nil {
        logger.Printf("sftp server init error: %s", err)
        return
    }
    if err := server.Serve(); err == io.EOF {
        server.Close()
        logger.Printf("sftp client exited session.")
    } else if err != nil {
        logger.Printf("sftp server completed with error: %s", err)
    }

}

func main() {

    server := ssh.Server{
        Addr:            fmt.Sprintf("0.0.0.0:%d", PORT), // IP and PORT to connect on
        PasswordHandler: ssh.PasswordHandler(getPasswordHandler(PASSWORD)),
        SubsystemHandlers: map[string]ssh.SubsystemHandler{
            "sftp": SftpHandler,
        },
    }

    logger.Printf("Listening os %d", PORT)
    err := server.ListenAndServe()
    if err != nil {
        logger.Printf("Failed to start the SSH server: %s", err)
    }

}

I might be doing something wrong .. However it works perfectly on Linux and OSX !

Screenshot 2021-06-29 at 11 45 51

davecheney commented 3 years ago

I haven't looked in detail but I suspect a code path uses path, not path/filepath.

puellanivis commented 3 years ago

I think by the SFTP standards we have to use path for these files, but we need to decode it with filepath.FromSlash before trying to actually use the file on the local OS. I think I have a good idea of what to look at, and will take a look.

puellanivis commented 3 years ago

I’ve got a repo, and I know where to be looking. I’ll keep the issue advised.

drakkan commented 3 years ago

Hi,

even if we fix this bug, I suggest to deprecate the server implementation (with a documentation note) and suggest to switch to the request server.

We could also rewrote the server implementation using the request server interfaces but if we do this we must be prepared to answer to several requests (some users want restrict the root dir, others want to restrict the root dir but at the same time follow symlinks outside it and so on).

The request server allows you to configure the desired behavior without implementing all possible use cases directly within the library.

puellanivis commented 3 years ago

Let me know if https://github.com/pkg/sftp/pull/445 works for you

SakiiR commented 3 years ago

Just tested with the patched version and looks great ! Nice reaction time (: