Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic logic to block actions to subusers after removing them from server #213

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func Configure(m *wserver.Manager, client remote.Client) *gin.Engine {
server.POST("/reinstall", postServerReinstall)
server.POST("/sync", postServerSync)
server.POST("/ws/deny", postServerDenyWSTokens)
server.DELETE("/sftp/disconnect", deleteServerSFTPConnection)

// This archive request causes the archive to start being created
// this should only be triggered by the panel.
Expand Down
22 changes: 22 additions & 0 deletions router/router_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,25 @@ func postServerDenyWSTokens(c *gin.Context) {

c.Status(http.StatusNoContent)
}

// Remove all SFTP connections for a specific user.
func deleteServerSFTPConnection(c *gin.Context) {
s := ExtractServer(c)

var data struct {
Username string `json:"username"`
}

if err := c.BindJSON(&data); err != nil {
return
}

if activeSessions := s.GetActiveSFTPConnections()[data.Username]; activeSessions != nil {
for _, session := range activeSessions {
session.Close()
}
s.RemoveActiveSFTPConnection(data.Username, nil)
}

c.Status(http.StatusNoContent)
}
37 changes: 37 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/creasty/defaults"
"golang.org/x/crypto/ssh"

"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
Expand Down Expand Up @@ -74,6 +75,8 @@ type Server struct {

logSink *system.SinkPool
installSink *system.SinkPool

activeSFTPConnections map[string][]*ssh.ServerConn
}

// New returns a new server instance with a context and all of the default
Expand All @@ -92,6 +95,7 @@ func New(client remote.Client) (*Server, error) {
system.LogSink: system.NewSinkPool(),
system.InstallSink: system.NewSinkPool(),
},
activeSFTPConnections: make(map[string][]*ssh.ServerConn),
}
if err := defaults.Set(&s); err != nil {
return nil, errors.Wrap(err, "server: could not set default values for struct")
Expand Down Expand Up @@ -362,3 +366,36 @@ func (s *Server) ToAPIResponse() APIResponse {
Configuration: *s.Config(),
}
}

// GetActiveSFTPConnections returns a map of active SFTP connections for the server.
func (s *Server) GetActiveSFTPConnections() map[string][]*ssh.ServerConn {
return s.activeSFTPConnections
}

// RemoveActiveSFTPConnection removes an active SFTP connection for the server.
// If the rs parameter is nil, all active SFTP connections for the user will be removed.
func (s *Server) RemoveActiveSFTPConnection(username string, sc *ssh.ServerConn) {
s.Lock()
defer s.Unlock()

if sc == nil {
delete(s.activeSFTPConnections, username)
} else {
if conns, ok := s.activeSFTPConnections[username]; ok {
for k, v := range conns {
if v == sc {
s.activeSFTPConnections[username] = append(conns[:k], conns[k+1:]...)
break
}
}
}
}
}

// AddActiveSFTPConnection adds an active SFTP connection for the server.
func (s *Server) AddActiveSFTPConnection(username string, sc *ssh.ServerConn) {
s.Lock()
defer s.Unlock()

s.activeSFTPConnections[username] = append(s.activeSFTPConnections[username], sc)
}
3 changes: 3 additions & 0 deletions sftp/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Handler struct {
permissions []string
logger *log.Entry
ro bool
username string
}

// NewHandler returns a new connection handler for the SFTP server. This allows a given user
Expand All @@ -56,6 +57,7 @@ func NewHandler(sc *ssh.ServerConn, srv *server.Server) (*Handler, error) {
events: &events,
ro: config.Get().System.Sftp.ReadOnly,
logger: log.WithFields(log.Fields{"subsystem": "sftp", "user": uuid, "ip": sc.RemoteAddr()}),
username: sc.User(),
}, nil
}

Expand Down Expand Up @@ -292,6 +294,7 @@ func (h *Handler) can(permission string) bool {
if h.server.IsSuspended() {
return false
}

for _, p := range h.permissions {
// If we match the permission specifically, or the user has been granted the "*"
// permission because they're an admin, let them through.
Expand Down
3 changes: 3 additions & 0 deletions sftp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ func (c *SFTPServer) AcceptInbound(conn net.Conn, config *ssh.ServerConfig) erro
return errors.WithStackIf(err)
}
rs := sftp.NewRequestServer(channel, handler.Handlers())
srv.AddActiveSFTPConnection(sconn.Conn.User(), sconn)

if err := rs.Serve(); err == io.EOF {
srv.RemoveActiveSFTPConnection(sconn.Conn.User(), sconn)
_ = rs.Close()
}
}
Expand Down