mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/gliderlabs/ssh"
|
|
"github.com/pkg/sftp"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// SetAllowSFTP enables or disables SFTP support
|
|
func (s *Server) SetAllowSFTP(allow bool) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.allowSFTP = allow
|
|
}
|
|
|
|
// sftpSubsystemHandler handles SFTP subsystem requests
|
|
func (s *Server) sftpSubsystemHandler(sess ssh.Session) {
|
|
sessionKey := s.registerSession(sess, cmdSFTP)
|
|
defer s.unregisterSession(sessionKey)
|
|
|
|
jwtUsername := s.associateJWTUsername(sess, sessionKey)
|
|
|
|
logger := log.WithField("session", sessionKey)
|
|
if jwtUsername != "" {
|
|
logger = logger.WithField("jwt_user", jwtUsername)
|
|
}
|
|
logger.Info("SFTP session started")
|
|
defer logger.Info("SFTP session closed")
|
|
|
|
s.mu.RLock()
|
|
allowSFTP := s.allowSFTP
|
|
s.mu.RUnlock()
|
|
|
|
if !allowSFTP {
|
|
logger.Debug("SFTP subsystem request denied: SFTP disabled")
|
|
if err := sess.Exit(1); err != nil {
|
|
logger.Debugf("SFTP session exit: %v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
result := s.CheckPrivileges(PrivilegeCheckRequest{
|
|
RequestedUsername: sess.User(),
|
|
FeatureSupportsUserSwitch: true,
|
|
FeatureName: FeatureSFTP,
|
|
})
|
|
|
|
if !result.Allowed {
|
|
logger.Warnf("SFTP access denied: %v", result.Error)
|
|
if err := sess.Exit(1); err != nil {
|
|
logger.Debugf("exit SFTP session: %v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if !result.RequiresUserSwitching {
|
|
if err := s.executeSftpDirect(sess); err != nil {
|
|
logger.Errorf("SFTP direct execution: %v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if err := s.executeSftpWithPrivilegeDrop(sess, result.User); err != nil {
|
|
logger.Errorf("SFTP privilege drop execution: %v", err)
|
|
}
|
|
}
|
|
|
|
// executeSftpDirect executes SFTP directly without privilege dropping
|
|
func (s *Server) executeSftpDirect(sess ssh.Session) error {
|
|
sftpServer, err := sftp.NewServer(sess)
|
|
if err != nil {
|
|
return fmt.Errorf("SFTP server creation: %w", err)
|
|
}
|
|
|
|
defer func() {
|
|
if err := sftpServer.Close(); err != nil {
|
|
log.Debugf("failed to close sftp server: %v", err)
|
|
}
|
|
}()
|
|
|
|
if err := sftpServer.Serve(); err != nil && err != io.EOF {
|
|
return fmt.Errorf("serve: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|