mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-06 22:30:56 +03:00
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -400,10 +399,14 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||
loginType := sconn.Permissions.Extensions["sftpgo_login_method"]
|
||||
connectionID := hex.EncodeToString(sconn.SessionID())
|
||||
|
||||
if err = checkRootPath(&user, connectionID); err != nil {
|
||||
if err = user.CheckFsRoot(connectionID); err != nil {
|
||||
errClose := user.CloseFs()
|
||||
logger.Warn(logSender, connectionID, "unable to check fs root: %v close fs error: %v", err, errClose)
|
||||
return
|
||||
}
|
||||
|
||||
defer user.CloseFs() //nolint:errcheck
|
||||
|
||||
logger.Log(logger.LevelInfo, common.ProtocolSSH, connectionID,
|
||||
"User id: %d, logged in with: %#v, username: %#v, home_dir: %#v remote addr: %#v",
|
||||
user.ID, loginType, user.Username, user.HomeDir, ipAddr)
|
||||
@@ -445,34 +448,24 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||
switch req.Type {
|
||||
case "subsystem":
|
||||
if string(req.Payload[4:]) == "sftp" {
|
||||
fs, err := user.GetFilesystem(connID)
|
||||
if err == nil {
|
||||
ok = true
|
||||
connection := Connection{
|
||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, user, fs),
|
||||
ClientVersion: string(sconn.ClientVersion()),
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
channel: channel,
|
||||
}
|
||||
go c.handleSftpConnection(channel, &connection)
|
||||
} else {
|
||||
logger.Debug(logSender, connID, "unable to create filesystem: %v", err)
|
||||
}
|
||||
}
|
||||
case "exec":
|
||||
// protocol will be set later inside processSSHCommand it could be SSH or SCP
|
||||
fs, err := user.GetFilesystem(connID)
|
||||
if err == nil {
|
||||
ok = true
|
||||
connection := Connection{
|
||||
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", user, fs),
|
||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, user),
|
||||
ClientVersion: string(sconn.ClientVersion()),
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
channel: channel,
|
||||
}
|
||||
ok = processSSHCommand(req.Payload, &connection, c.EnabledSSHCommands)
|
||||
} else {
|
||||
logger.Debug(sshCommandLogSender, connID, "unable to create filesystem: %v", err)
|
||||
go c.handleSftpConnection(channel, &connection)
|
||||
}
|
||||
case "exec":
|
||||
// protocol will be set later inside processSSHCommand it could be SSH or SCP
|
||||
connection := Connection{
|
||||
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", user),
|
||||
ClientVersion: string(sconn.ClientVersion()),
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
channel: channel,
|
||||
}
|
||||
ok = processSSHCommand(req.Payload, &connection, c.EnabledSSHCommands)
|
||||
}
|
||||
if req.WantReply {
|
||||
req.Reply(ok, nil) //nolint:errcheck
|
||||
@@ -541,21 +534,6 @@ func checkAuthError(ip string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func checkRootPath(user *dataprovider.User, connectionID string) error {
|
||||
if user.FsConfig.Provider != dataprovider.SFTPFilesystemProvider {
|
||||
// for sftp fs check root path does nothing so don't open a useless SFTP connection
|
||||
fs, err := user.GetFilesystem(connectionID)
|
||||
if err != nil {
|
||||
logger.Warn(logSender, "", "could not create filesystem for user %#v err: %v", user.Username, err)
|
||||
return err
|
||||
}
|
||||
|
||||
fs.CheckRootPath(user.Username, user.GetUID(), user.GetGID())
|
||||
fs.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh.ConnMetadata) (*ssh.Permissions, error) {
|
||||
connectionID := ""
|
||||
if conn != nil {
|
||||
@@ -568,7 +546,7 @@ func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh.
|
||||
}
|
||||
if utils.IsStringInSlice(common.ProtocolSSH, user.Filters.DeniedProtocols) {
|
||||
logger.Debug(logSender, connectionID, "cannot login user %#v, protocol SSH is not allowed", user.Username)
|
||||
return nil, fmt.Errorf("Protocol SSH is not allowed for user %#v", user.Username)
|
||||
return nil, fmt.Errorf("protocol SSH is not allowed for user %#v", user.Username)
|
||||
}
|
||||
if user.MaxSessions > 0 {
|
||||
activeSessions := common.Connections.GetActiveSessions(user.Username)
|
||||
@@ -580,17 +558,12 @@ func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh.
|
||||
}
|
||||
if !user.IsLoginMethodAllowed(loginMethod, conn.PartialSuccessMethods()) {
|
||||
logger.Debug(logSender, connectionID, "cannot login user %#v, login method %#v is not allowed", user.Username, loginMethod)
|
||||
return nil, fmt.Errorf("Login method %#v is not allowed for user %#v", loginMethod, user.Username)
|
||||
}
|
||||
if dataprovider.GetQuotaTracking() > 0 && user.HasOverlappedMappedPaths() {
|
||||
logger.Debug(logSender, connectionID, "cannot login user %#v, overlapping mapped folders are allowed only with quota tracking disabled",
|
||||
user.Username)
|
||||
return nil, errors.New("overlapping mapped folders are allowed only with quota tracking disabled")
|
||||
return nil, fmt.Errorf("login method %#v is not allowed for user %#v", loginMethod, user.Username)
|
||||
}
|
||||
remoteAddr := conn.RemoteAddr().String()
|
||||
if !user.IsLoginFromAddrAllowed(remoteAddr) {
|
||||
logger.Debug(logSender, connectionID, "cannot login user %#v, remote address is not allowed: %v", user.Username, remoteAddr)
|
||||
return nil, fmt.Errorf("Login for user %#v is not allowed from this address: %v", user.Username, remoteAddr)
|
||||
return nil, fmt.Errorf("login for user %#v is not allowed from this address: %v", user.Username, remoteAddr)
|
||||
}
|
||||
|
||||
json, err := json.Marshal(user)
|
||||
|
||||
Reference in New Issue
Block a user