Migrate SFTP endpoints
This commit is contained in:
@@ -18,7 +18,7 @@ type Client interface {
|
||||
SetBackupStatus(ctx context.Context, backup string, data api.BackupRequest) error
|
||||
SetInstallationStatus(ctx context.Context, uuid string, successful bool) error
|
||||
SetTransferStatus(ctx context.Context, uuid string, successful bool) error
|
||||
ValidateSftpCredentials(ctx context.Context, request api.SftpAuthRequest) (api.SftpAuthResponse, error)
|
||||
ValidateSftpCredentials(ctx context.Context, request SftpAuthRequest) (SftpAuthResponse, error)
|
||||
}
|
||||
|
||||
type client struct {
|
||||
|
||||
@@ -32,15 +32,9 @@ func (re *RequestError) Error() string {
|
||||
return fmt.Sprintf("Error response from Panel: %s: %s (HTTP/%d)", re.Code, re.Detail, c)
|
||||
}
|
||||
|
||||
type sftpInvalidCredentialsError struct {
|
||||
type SftpInvalidCredentialsError struct {
|
||||
}
|
||||
|
||||
func (ice sftpInvalidCredentialsError) Error() string {
|
||||
func (ice SftpInvalidCredentialsError) Error() string {
|
||||
return "the credentials provided were invalid"
|
||||
}
|
||||
|
||||
func IsInvalidCredentialsError(err error) bool {
|
||||
_, ok := err.(*sftpInvalidCredentialsError)
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -3,30 +3,34 @@ package remote
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/pterodactyl/wings/api"
|
||||
)
|
||||
|
||||
// Usernames all follow the same format, so don't even bother hitting the API if the username is not
|
||||
// at least in the expected format. This is very basic protection against random bots finding the SFTP
|
||||
// server and sending a flood of usernames.
|
||||
var validUsernameRegexp = regexp.MustCompile(`^(?i)(.+)\.([a-z0-9]{8})$`)
|
||||
type SftpAuthRequest struct {
|
||||
User string `json:"username"`
|
||||
Pass string `json:"password"`
|
||||
IP string `json:"ip"`
|
||||
SessionID []byte `json:"session_id"`
|
||||
ClientVersion []byte `json:"client_version"`
|
||||
}
|
||||
|
||||
func (c *client) ValidateSftpCredentials(ctx context.Context, request api.SftpAuthRequest) (api.SftpAuthResponse, error) {
|
||||
if !validUsernameRegexp.MatchString(request.User) {
|
||||
log.WithFields(log.Fields{
|
||||
"subsystem": "sftp",
|
||||
"username": request.User,
|
||||
"ip": request.IP,
|
||||
}).Warn("failed to validate user credentials (invalid format)")
|
||||
return api.SftpAuthResponse{}, new(sftpInvalidCredentialsError)
|
||||
}
|
||||
type SftpAuthResponse struct {
|
||||
Server string `json:"server"`
|
||||
Token string `json:"token"`
|
||||
Permissions []string `json:"permissions"`
|
||||
}
|
||||
|
||||
// ValidateSftpCredentials makes a request to determine if the username and
|
||||
// password combination provided is associated with a valid server on the instance
|
||||
// using the Panel's authentication control mechanisms. This will get itself
|
||||
// throttled if too many requests are made, allowing us to completely offload
|
||||
// all of the authorization security logic to the Panel.
|
||||
func (c *client) ValidateSftpCredentials(ctx context.Context, request SftpAuthRequest) (SftpAuthResponse, error) {
|
||||
var auth SftpAuthResponse
|
||||
res, err := c.post(ctx, "/sftp/auth", request)
|
||||
if err != nil {
|
||||
return api.SftpAuthResponse{}, err
|
||||
return auth, err
|
||||
}
|
||||
|
||||
e := res.Error()
|
||||
@@ -38,13 +42,12 @@ func (c *client) ValidateSftpCredentials(ctx context.Context, request api.SftpAu
|
||||
"ip": request.IP,
|
||||
}).Warn(e.Error())
|
||||
|
||||
return api.SftpAuthResponse{}, &sftpInvalidCredentialsError{}
|
||||
return auth, &SftpInvalidCredentialsError{}
|
||||
}
|
||||
|
||||
return api.SftpAuthResponse{}, errors.New(e.Error())
|
||||
return auth, errors.New(e.Error())
|
||||
}
|
||||
|
||||
r := api.SftpAuthResponse{}
|
||||
err = res.BindJSON(&r)
|
||||
return r, err
|
||||
err = res.BindJSON(&auth)
|
||||
return auth, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user