2020-10-29 18:23:33 +00:00
|
|
|
package sftpd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"net"
|
|
|
|
|
|
|
|
"github.com/pkg/sftp"
|
|
|
|
|
2021-06-26 05:31:41 +00:00
|
|
|
"github.com/drakkan/sftpgo/v2/common"
|
|
|
|
"github.com/drakkan/sftpgo/v2/dataprovider"
|
|
|
|
"github.com/drakkan/sftpgo/v2/logger"
|
2020-10-29 18:23:33 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type subsystemChannel struct {
|
|
|
|
reader io.Reader
|
|
|
|
writer io.Writer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *subsystemChannel) Read(p []byte) (int, error) {
|
|
|
|
return s.reader.Read(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *subsystemChannel) Write(p []byte) (int, error) {
|
|
|
|
return s.writer.Write(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *subsystemChannel) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func newSubsystemChannel(reader io.Reader, writer io.Writer) *subsystemChannel {
|
|
|
|
return &subsystemChannel{
|
|
|
|
reader: reader,
|
|
|
|
writer: writer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ServeSubSystemConnection handles a connection as SSH subsystem
|
2021-02-16 18:11:36 +00:00
|
|
|
func ServeSubSystemConnection(user *dataprovider.User, connectionID string, reader io.Reader, writer io.Writer) error {
|
2021-03-21 18:15:47 +00:00
|
|
|
err := user.CheckFsRoot(connectionID)
|
2020-10-29 18:23:33 +00:00
|
|
|
if err != nil {
|
2021-03-21 18:15:47 +00:00
|
|
|
errClose := user.CloseFs()
|
|
|
|
logger.Warn(logSender, connectionID, "unable to check fs root: %v close fs error: %v", err, errClose)
|
2020-10-29 18:23:33 +00:00
|
|
|
return err
|
|
|
|
}
|
2021-08-19 13:51:43 +00:00
|
|
|
dataprovider.UpdateLastLogin(user)
|
2020-10-29 18:23:33 +00:00
|
|
|
|
|
|
|
connection := &Connection{
|
2021-07-24 18:11:17 +00:00
|
|
|
BaseConnection: common.NewBaseConnection(connectionID, common.ProtocolSFTP, "", "", *user),
|
2020-10-29 18:23:33 +00:00
|
|
|
ClientVersion: "",
|
|
|
|
RemoteAddr: &net.IPAddr{},
|
2021-07-24 18:11:17 +00:00
|
|
|
LocalAddr: &net.IPAddr{},
|
2020-10-29 18:23:33 +00:00
|
|
|
channel: newSubsystemChannel(reader, writer),
|
|
|
|
}
|
|
|
|
common.Connections.Add(connection)
|
|
|
|
defer common.Connections.Remove(connection.GetID())
|
|
|
|
|
|
|
|
server := sftp.NewRequestServer(connection.channel, sftp.Handlers{
|
|
|
|
FileGet: connection,
|
|
|
|
FilePut: connection,
|
|
|
|
FileCmd: connection,
|
|
|
|
FileList: connection,
|
|
|
|
}, sftp.WithRSAllocator())
|
|
|
|
|
2020-11-18 18:06:12 +00:00
|
|
|
defer server.Close()
|
2020-10-29 18:23:33 +00:00
|
|
|
return server.Serve()
|
|
|
|
}
|