Migrate SFTP endpoints

This commit is contained in:
Dane Everitt
2021-02-01 20:59:17 -08:00
parent 6775c17324
commit 62cbe5e135
6 changed files with 97 additions and 160 deletions

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}