Antonio Mika
·
2026-10-10
1package sftp
2
3import (
4 "errors"
5 "fmt"
6 "io"
7
8 "github.com/picosh/pico/pkg/pssh"
9 "github.com/picosh/pico/pkg/send/utils"
10 "github.com/pkg/sftp"
11)
12
13// func SSHOption(writeHandler utils.CopyFromClientHandler) ssh.Option {
14// return func(server *ssh.Server) error {
15// if server.SubsystemHandlers == nil {
16// server.SubsystemHandlers = map[string]ssh.SubsystemHandler{}
17// }
18
19// server.SubsystemHandlers["sftp"] = SubsystemHandler(writeHandler)
20// return nil
21// }
22// }
23
24func Middleware(writeHandler utils.CopyFromClientHandler) pssh.SSHServerMiddleware {
25 return func(next pssh.SSHServerHandler) pssh.SSHServerHandler {
26 return func(session *pssh.SSHServerConnSession) error {
27 logger := writeHandler.GetLogger(session).With(
28 "sftp", true,
29 )
30
31 defer func() {
32 if r := recover(); r != nil {
33 logger.Error("error running sftp middleware", "err", r)
34 _, _ = fmt.Fprintln(session, "error running sftp middleware, check the flags you are using")
35 }
36 }()
37
38 err := writeHandler.Validate(session)
39 if err != nil {
40 _, _ = fmt.Fprintln(session.Stderr(), err)
41 return err
42 }
43
44 handler := &handlererr{
45 Handler: &handler{
46 session: session,
47 writeHandler: writeHandler,
48 pending: map[string]*pendingFile{},
49 ignored: map[string]int{},
50 hidden: map[string]*pendingFile{},
51 },
52 }
53
54 handlers := sftp.Handlers{
55 FilePut: handler,
56 FileList: handler,
57 FileGet: handler,
58 FileCmd: handler,
59 }
60
61 requestServer := sftp.NewRequestServer(session, handlers)
62
63 err = requestServer.Serve()
64 if err != nil && !errors.Is(err, io.EOF) {
65 _, _ = fmt.Fprintln(session.Stderr(), err)
66 logger.Error("Error serving sftp subsystem", "err", err)
67 }
68
69 return err
70 }
71 }
72}