wings/sftp/server.go

95 lines
2.5 KiB
Go
Raw Normal View History

package sftp
import (
"github.com/apex/log"
2019-12-07 23:53:07 +00:00
"github.com/pkg/errors"
"github.com/pterodactyl/sftp-server"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
2019-12-08 01:35:45 +00:00
"github.com/pterodactyl/wings/server"
2019-12-07 23:53:07 +00:00
"go.uber.org/zap"
)
func Initialize(config *config.Configuration) error {
2019-12-07 23:53:07 +00:00
c := &sftp_server.Server{
User: sftp_server.SftpUser{
Uid: config.System.User.Uid,
Gid: config.System.User.Gid,
},
2019-12-07 23:53:07 +00:00
Settings: sftp_server.Settings{
BasePath: config.System.Data,
ReadOnly: config.System.Sftp.ReadOnly,
BindAddress: config.System.Sftp.Address,
BindPort: config.System.Sftp.Port,
},
2019-12-07 23:53:07 +00:00
CredentialValidator: validateCredentials,
PathValidator: validatePath,
DiskSpaceValidator: validateDiskSpace,
}
2019-12-07 23:53:07 +00:00
if err := sftp_server.New(c); err != nil {
return err
}
c.ConfigureLogger(func() *zap.SugaredLogger {
return zap.S().Named("sftp")
})
// Initialize the SFTP server in a background thread since this is
// a long running operation.
go func(instance *sftp_server.Server) {
if err := c.Initalize(); err != nil {
log.WithField("subsystem", "sftp").WithField("error", errors.WithStack(err)).Error("failed to initialize SFTP subsystem")
2019-12-07 23:53:07 +00:00
}
}(c)
return nil
}
func validatePath(fs sftp_server.FileSystem, p string) (string, error) {
2019-12-08 01:35:45 +00:00
s := server.GetServers().Find(func(server *server.Server) bool {
return server.Uuid == fs.UUID
})
if s == nil {
return "", errors.New("no server found with that UUID")
}
return s.Filesystem.SafePath(p)
}
func validateDiskSpace(fs sftp_server.FileSystem) bool {
2019-12-08 01:35:45 +00:00
s := server.GetServers().Find(func(server *server.Server) bool {
return server.Uuid == fs.UUID
})
if s == nil {
return false
}
return s.Filesystem.HasSpaceAvailable()
}
2019-12-07 23:53:07 +00:00
// Validates a set of credentials for a SFTP login aganist Pterodactyl Panel and returns
// the server's UUID if the credentials were valid.
func validateCredentials(c sftp_server.AuthenticationRequest) (*sftp_server.AuthenticationResponse, error) {
2019-12-08 01:35:45 +00:00
resp, err := api.NewRequester().ValidateSftpCredentials(c)
log.WithFields(log.Fields{"subsystem": "sftp", "username": c.User}).Debug("validating credentials for SFTP connection")
2019-12-08 01:35:45 +00:00
if err != nil {
return resp, err
}
s := server.GetServers().Find(func(server *server.Server) bool {
return server.Uuid == resp.Server
})
if s == nil {
return resp, errors.New("no matching server with UUID found")
2019-12-08 01:35:45 +00:00
}
s.Log().WithFields(log.Fields{"subsystem": "sftp", "username": c.User}).Debug("matched user to server instance, credentials successfully validated")
2019-12-08 01:35:45 +00:00
return resp, err
}