sftp
sftp copied to clipboard
Windows issues with current directory and drive changes
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 !

I haven't looked in detail but I suspect a code path uses path, not path/filepath.
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.
I’ve got a repo, and I know where to be looking. I’ll keep the issue advised.
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.
Let me know if https://github.com/pkg/sftp/pull/445 works for you
Just tested with the patched version and looks great ! Nice reaction time (: