mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-22 07:30:25 +00:00
parent
83c7453957
commit
c41ae116eb
30 changed files with 237 additions and 150 deletions
|
@ -205,7 +205,7 @@ func TestPreDeleteAction(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("id", homeDir, "")
|
fs := vfs.NewOsFs("id", homeDir, "")
|
||||||
c := NewBaseConnection("id", ProtocolSFTP, "", user)
|
c := NewBaseConnection("id", ProtocolSFTP, "", "", user)
|
||||||
|
|
||||||
testfile := filepath.Join(user.HomeDir, "testfile")
|
testfile := filepath.Join(user.HomeDir, "testfile")
|
||||||
err = os.WriteFile(testfile, []byte("test"), os.ModePerm)
|
err = os.WriteFile(testfile, []byte("test"), os.ModePerm)
|
||||||
|
|
|
@ -287,6 +287,7 @@ type ActiveTransfer interface {
|
||||||
type ActiveConnection interface {
|
type ActiveConnection interface {
|
||||||
GetID() string
|
GetID() string
|
||||||
GetUsername() string
|
GetUsername() string
|
||||||
|
GetLocalAddress() string
|
||||||
GetRemoteAddress() string
|
GetRemoteAddress() string
|
||||||
GetClientVersion() string
|
GetClientVersion() string
|
||||||
GetProtocol() string
|
GetProtocol() string
|
||||||
|
@ -596,7 +597,8 @@ func (conns *ActiveConnections) Add(c ActiveConnection) {
|
||||||
|
|
||||||
conns.connections = append(conns.connections, c)
|
conns.connections = append(conns.connections, c)
|
||||||
metric.UpdateActiveConnectionsSize(len(conns.connections))
|
metric.UpdateActiveConnectionsSize(len(conns.connections))
|
||||||
logger.Debug(c.GetProtocol(), c.GetID(), "connection added, num open connections: %v", len(conns.connections))
|
logger.Debug(c.GetProtocol(), c.GetID(), "connection added, local address %#v, remote address %#v, num open connections: %v",
|
||||||
|
c.GetLocalAddress(), c.GetRemoteAddress(), len(conns.connections))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap replaces an existing connection with the given one.
|
// Swap replaces an existing connection with the given one.
|
||||||
|
@ -630,8 +632,8 @@ func (conns *ActiveConnections) Remove(connectionID string) {
|
||||||
conns.connections[lastIdx] = nil
|
conns.connections[lastIdx] = nil
|
||||||
conns.connections = conns.connections[:lastIdx]
|
conns.connections = conns.connections[:lastIdx]
|
||||||
metric.UpdateActiveConnectionsSize(lastIdx)
|
metric.UpdateActiveConnectionsSize(lastIdx)
|
||||||
logger.Debug(conn.GetProtocol(), conn.GetID(), "connection removed, close fs error: %v, num open connections: %v",
|
logger.Debug(conn.GetProtocol(), conn.GetID(), "connection removed, local address %#v, remote address %#v close fs error: %v, num open connections: %v",
|
||||||
err, lastIdx)
|
conn.GetLocalAddress(), conn.GetRemoteAddress(), err, lastIdx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,10 @@ func (c *fakeConnection) GetCommand() string {
|
||||||
return c.command
|
return c.command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *fakeConnection) GetLocalAddress() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (c *fakeConnection) GetRemoteAddress() string {
|
func (c *fakeConnection) GetRemoteAddress() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -255,7 +259,7 @@ func TestMaxConnections(t *testing.T) {
|
||||||
Config.MaxPerHostConnections = perHost
|
Config.MaxPerHostConnections = perHost
|
||||||
|
|
||||||
assert.True(t, Connections.IsNewConnectionAllowed(ipAddr))
|
assert.True(t, Connections.IsNewConnectionAllowed(ipAddr))
|
||||||
c := NewBaseConnection("id", ProtocolSFTP, "", dataprovider.User{})
|
c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{})
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -328,7 +332,7 @@ func TestIdleConnections(t *testing.T) {
|
||||||
Username: username,
|
Username: username,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
c := NewBaseConnection(sshConn1.id+"_1", ProtocolSFTP, "", user)
|
c := NewBaseConnection(sshConn1.id+"_1", ProtocolSFTP, "", "", user)
|
||||||
c.lastActivity = time.Now().Add(-24 * time.Hour).UnixNano()
|
c.lastActivity = time.Now().Add(-24 * time.Hour).UnixNano()
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
|
@ -340,7 +344,7 @@ func TestIdleConnections(t *testing.T) {
|
||||||
Connections.AddSSHConnection(sshConn1)
|
Connections.AddSSHConnection(sshConn1)
|
||||||
Connections.Add(fakeConn)
|
Connections.Add(fakeConn)
|
||||||
assert.Equal(t, Connections.GetActiveSessions(username), 1)
|
assert.Equal(t, Connections.GetActiveSessions(username), 1)
|
||||||
c = NewBaseConnection(sshConn2.id+"_1", ProtocolSSH, "", user)
|
c = NewBaseConnection(sshConn2.id+"_1", ProtocolSSH, "", "", user)
|
||||||
fakeConn = &fakeConnection{
|
fakeConn = &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -348,7 +352,7 @@ func TestIdleConnections(t *testing.T) {
|
||||||
Connections.Add(fakeConn)
|
Connections.Add(fakeConn)
|
||||||
assert.Equal(t, Connections.GetActiveSessions(username), 2)
|
assert.Equal(t, Connections.GetActiveSessions(username), 2)
|
||||||
|
|
||||||
cFTP := NewBaseConnection("id2", ProtocolFTP, "", dataprovider.User{})
|
cFTP := NewBaseConnection("id2", ProtocolFTP, "", "", dataprovider.User{})
|
||||||
cFTP.lastActivity = time.Now().UnixNano()
|
cFTP.lastActivity = time.Now().UnixNano()
|
||||||
fakeConn = &fakeConnection{
|
fakeConn = &fakeConnection{
|
||||||
BaseConnection: cFTP,
|
BaseConnection: cFTP,
|
||||||
|
@ -388,7 +392,7 @@ func TestIdleConnections(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCloseConnection(t *testing.T) {
|
func TestCloseConnection(t *testing.T) {
|
||||||
c := NewBaseConnection("id", ProtocolSFTP, "", dataprovider.User{})
|
c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{})
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -404,7 +408,7 @@ func TestCloseConnection(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSwapConnection(t *testing.T) {
|
func TestSwapConnection(t *testing.T) {
|
||||||
c := NewBaseConnection("id", ProtocolFTP, "", dataprovider.User{})
|
c := NewBaseConnection("id", ProtocolFTP, "", "", dataprovider.User{})
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -412,7 +416,7 @@ func TestSwapConnection(t *testing.T) {
|
||||||
if assert.Len(t, Connections.GetStats(), 1) {
|
if assert.Len(t, Connections.GetStats(), 1) {
|
||||||
assert.Equal(t, "", Connections.GetStats()[0].Username)
|
assert.Equal(t, "", Connections.GetStats()[0].Username)
|
||||||
}
|
}
|
||||||
c = NewBaseConnection("id", ProtocolFTP, "", dataprovider.User{
|
c = NewBaseConnection("id", ProtocolFTP, "", "", dataprovider.User{
|
||||||
BaseUser: sdk.BaseUser{
|
BaseUser: sdk.BaseUser{
|
||||||
Username: userTestUsername,
|
Username: userTestUsername,
|
||||||
},
|
},
|
||||||
|
@ -453,7 +457,7 @@ func TestConnectionStatus(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
c1 := NewBaseConnection("id1", ProtocolSFTP, "", user)
|
c1 := NewBaseConnection("id1", ProtocolSFTP, "", "", user)
|
||||||
fakeConn1 := &fakeConnection{
|
fakeConn1 := &fakeConnection{
|
||||||
BaseConnection: c1,
|
BaseConnection: c1,
|
||||||
}
|
}
|
||||||
|
@ -461,12 +465,12 @@ func TestConnectionStatus(t *testing.T) {
|
||||||
t1.BytesReceived = 123
|
t1.BytesReceived = 123
|
||||||
t2 := NewBaseTransfer(nil, c1, nil, "/p2", "/p2", "/r2", TransferDownload, 0, 0, 0, true, fs)
|
t2 := NewBaseTransfer(nil, c1, nil, "/p2", "/p2", "/r2", TransferDownload, 0, 0, 0, true, fs)
|
||||||
t2.BytesSent = 456
|
t2.BytesSent = 456
|
||||||
c2 := NewBaseConnection("id2", ProtocolSSH, "", user)
|
c2 := NewBaseConnection("id2", ProtocolSSH, "", "", user)
|
||||||
fakeConn2 := &fakeConnection{
|
fakeConn2 := &fakeConnection{
|
||||||
BaseConnection: c2,
|
BaseConnection: c2,
|
||||||
command: "md5sum",
|
command: "md5sum",
|
||||||
}
|
}
|
||||||
c3 := NewBaseConnection("id3", ProtocolWebDAV, "", user)
|
c3 := NewBaseConnection("id3", ProtocolWebDAV, "", "", user)
|
||||||
fakeConn3 := &fakeConnection{
|
fakeConn3 := &fakeConnection{
|
||||||
BaseConnection: c3,
|
BaseConnection: c3,
|
||||||
command: "PROPFIND",
|
command: "PROPFIND",
|
||||||
|
@ -707,7 +711,7 @@ func TestCachedFs(t *testing.T) {
|
||||||
HomeDir: filepath.Clean(os.TempDir()),
|
HomeDir: filepath.Clean(os.TempDir()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
conn := NewBaseConnection("id", ProtocolSFTP, "", user)
|
conn := NewBaseConnection("id", ProtocolSFTP, "", "", user)
|
||||||
// changing the user should not affect the connection
|
// changing the user should not affect the connection
|
||||||
user.HomeDir = filepath.Join(os.TempDir(), "temp")
|
user.HomeDir = filepath.Join(os.TempDir(), "temp")
|
||||||
err := os.Mkdir(user.HomeDir, os.ModePerm)
|
err := os.Mkdir(user.HomeDir, os.ModePerm)
|
||||||
|
|
|
@ -33,13 +33,14 @@ type BaseConnection struct {
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
protocol string
|
protocol string
|
||||||
remoteAddr string
|
remoteAddr string
|
||||||
|
localAddr string
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
transferID uint64
|
transferID uint64
|
||||||
activeTransfers []ActiveTransfer
|
activeTransfers []ActiveTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBaseConnection returns a new BaseConnection
|
// NewBaseConnection returns a new BaseConnection
|
||||||
func NewBaseConnection(id, protocol, remoteAddr string, user dataprovider.User) *BaseConnection {
|
func NewBaseConnection(id, protocol, localAddr, remoteAddr string, user dataprovider.User) *BaseConnection {
|
||||||
connID := id
|
connID := id
|
||||||
if util.IsStringInSlice(protocol, supportedProtocols) {
|
if util.IsStringInSlice(protocol, supportedProtocols) {
|
||||||
connID = fmt.Sprintf("%v_%v", protocol, id)
|
connID = fmt.Sprintf("%v_%v", protocol, id)
|
||||||
|
@ -49,6 +50,7 @@ func NewBaseConnection(id, protocol, remoteAddr string, user dataprovider.User)
|
||||||
User: user,
|
User: user,
|
||||||
startTime: time.Now(),
|
startTime: time.Now(),
|
||||||
protocol: protocol,
|
protocol: protocol,
|
||||||
|
localAddr: localAddr,
|
||||||
remoteAddr: remoteAddr,
|
remoteAddr: remoteAddr,
|
||||||
lastActivity: time.Now().UnixNano(),
|
lastActivity: time.Now().UnixNano(),
|
||||||
transferID: 0,
|
transferID: 0,
|
||||||
|
@ -242,7 +244,8 @@ func (c *BaseConnection) CreateDir(virtualPath string) error {
|
||||||
}
|
}
|
||||||
vfs.SetPathPermissions(fs, fsPath, c.User.GetUID(), c.User.GetGID())
|
vfs.SetPathPermissions(fs, fsPath, c.User.GetUID(), c.User.GetGID())
|
||||||
|
|
||||||
logger.CommandLog(mkdirLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1, c.remoteAddr)
|
logger.CommandLog(mkdirLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1,
|
||||||
|
c.localAddr, c.remoteAddr)
|
||||||
ExecuteActionNotification(&c.User, operationMkdir, fsPath, virtualPath, "", "", c.protocol, 0, nil)
|
ExecuteActionNotification(&c.User, operationMkdir, fsPath, virtualPath, "", "", c.protocol, 0, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -276,7 +279,8 @@ func (c *BaseConnection) RemoveFile(fs vfs.Fs, fsPath, virtualPath string, info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.CommandLog(removeLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1, c.remoteAddr)
|
logger.CommandLog(removeLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1,
|
||||||
|
c.localAddr, c.remoteAddr)
|
||||||
if info.Mode()&os.ModeSymlink == 0 {
|
if info.Mode()&os.ModeSymlink == 0 {
|
||||||
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(virtualPath))
|
vfolder, err := c.User.GetVirtualFolderForPath(path.Dir(virtualPath))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -347,7 +351,8 @@ func (c *BaseConnection) RemoveDir(virtualPath string) error {
|
||||||
return c.GetFsError(fs, err)
|
return c.GetFsError(fs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.CommandLog(rmdirLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1, c.remoteAddr)
|
logger.CommandLog(rmdirLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "", "", -1,
|
||||||
|
c.localAddr, c.remoteAddr)
|
||||||
ExecuteActionNotification(&c.User, operationRmdir, fsPath, virtualPath, "", "", c.protocol, 0, nil)
|
ExecuteActionNotification(&c.User, operationRmdir, fsPath, virtualPath, "", "", c.protocol, 0, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -408,7 +413,7 @@ func (c *BaseConnection) Rename(virtualSourcePath, virtualTargetPath string) err
|
||||||
vfs.SetPathPermissions(fsDst, fsTargetPath, c.User.GetUID(), c.User.GetGID())
|
vfs.SetPathPermissions(fsDst, fsTargetPath, c.User.GetUID(), c.User.GetGID())
|
||||||
c.updateQuotaAfterRename(fsDst, virtualSourcePath, virtualTargetPath, fsTargetPath, initialSize) //nolint:errcheck
|
c.updateQuotaAfterRename(fsDst, virtualSourcePath, virtualTargetPath, fsTargetPath, initialSize) //nolint:errcheck
|
||||||
logger.CommandLog(renameLogSender, fsSourcePath, fsTargetPath, c.User.Username, "", c.ID, c.protocol, -1, -1,
|
logger.CommandLog(renameLogSender, fsSourcePath, fsTargetPath, c.User.Username, "", c.ID, c.protocol, -1, -1,
|
||||||
"", "", "", -1, c.remoteAddr)
|
"", "", "", -1, c.localAddr, c.remoteAddr)
|
||||||
ExecuteActionNotification(&c.User, operationRename, fsSourcePath, virtualSourcePath, fsTargetPath, "", c.protocol, 0, nil)
|
ExecuteActionNotification(&c.User, operationRename, fsSourcePath, virtualSourcePath, fsTargetPath, "", c.protocol, 0, nil)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -445,7 +450,7 @@ func (c *BaseConnection) CreateSymlink(virtualSourcePath, virtualTargetPath stri
|
||||||
return c.GetFsError(fs, err)
|
return c.GetFsError(fs, err)
|
||||||
}
|
}
|
||||||
logger.CommandLog(symlinkLogSender, fsSourcePath, fsTargetPath, c.User.Username, "", c.ID, c.protocol, -1, -1, "",
|
logger.CommandLog(symlinkLogSender, fsSourcePath, fsTargetPath, c.User.Username, "", c.ID, c.protocol, -1, -1, "",
|
||||||
"", "", -1, c.remoteAddr)
|
"", "", -1, c.localAddr, c.remoteAddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +516,7 @@ func (c *BaseConnection) handleChmod(fs vfs.Fs, fsPath, pathForPerms string, att
|
||||||
return c.GetFsError(fs, err)
|
return c.GetFsError(fs, err)
|
||||||
}
|
}
|
||||||
logger.CommandLog(chmodLogSender, fsPath, "", c.User.Username, attributes.Mode.String(), c.ID, c.protocol,
|
logger.CommandLog(chmodLogSender, fsPath, "", c.User.Username, attributes.Mode.String(), c.ID, c.protocol,
|
||||||
-1, -1, "", "", "", -1, c.remoteAddr)
|
-1, -1, "", "", "", -1, c.localAddr, c.remoteAddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,7 +533,7 @@ func (c *BaseConnection) handleChown(fs vfs.Fs, fsPath, pathForPerms string, att
|
||||||
return c.GetFsError(fs, err)
|
return c.GetFsError(fs, err)
|
||||||
}
|
}
|
||||||
logger.CommandLog(chownLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, attributes.UID, attributes.GID,
|
logger.CommandLog(chownLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, attributes.UID, attributes.GID,
|
||||||
"", "", "", -1, c.remoteAddr)
|
"", "", "", -1, c.localAddr, c.remoteAddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +552,7 @@ func (c *BaseConnection) handleChtimes(fs vfs.Fs, fsPath, pathForPerms string, a
|
||||||
accessTimeString := attributes.Atime.Format(chtimesFormat)
|
accessTimeString := attributes.Atime.Format(chtimesFormat)
|
||||||
modificationTimeString := attributes.Mtime.Format(chtimesFormat)
|
modificationTimeString := attributes.Mtime.Format(chtimesFormat)
|
||||||
logger.CommandLog(chtimesLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1,
|
logger.CommandLog(chtimesLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1,
|
||||||
accessTimeString, modificationTimeString, "", -1, c.remoteAddr)
|
accessTimeString, modificationTimeString, "", -1, c.localAddr, c.remoteAddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +586,7 @@ func (c *BaseConnection) SetStat(virtualPath string, attributes *StatAttributes)
|
||||||
return c.GetFsError(fs, err)
|
return c.GetFsError(fs, err)
|
||||||
}
|
}
|
||||||
logger.CommandLog(truncateLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "",
|
logger.CommandLog(truncateLogSender, fsPath, "", c.User.Username, "", c.ID, c.protocol, -1, -1, "", "",
|
||||||
"", attributes.Size, c.remoteAddr)
|
"", attributes.Size, c.localAddr, c.remoteAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -65,7 +65,7 @@ func TestRemoveErrors(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := NewBaseConnection("", ProtocolFTP, "", user)
|
conn := NewBaseConnection("", ProtocolFTP, "", "", user)
|
||||||
err := conn.IsRemoveDirAllowed(fs, mappedPath, "/virtualpath1")
|
err := conn.IsRemoveDirAllowed(fs, mappedPath, "/virtualpath1")
|
||||||
if assert.Error(t, err) {
|
if assert.Error(t, err) {
|
||||||
assert.Contains(t, err.Error(), "permission denied")
|
assert.Contains(t, err.Error(), "permission denied")
|
||||||
|
@ -88,7 +88,7 @@ func TestSetStatMode(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := newMockOsFs(true, "", user.GetHomeDir())
|
fs := newMockOsFs(true, "", user.GetHomeDir())
|
||||||
conn := NewBaseConnection("", ProtocolWebDAV, "", user)
|
conn := NewBaseConnection("", ProtocolWebDAV, "", "", user)
|
||||||
err := conn.handleChmod(fs, fakePath, fakePath, nil)
|
err := conn.handleChmod(fs, fakePath, fakePath, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = conn.handleChown(fs, fakePath, fakePath, nil)
|
err = conn.handleChown(fs, fakePath, fakePath, nil)
|
||||||
|
@ -105,14 +105,14 @@ func TestSetStatMode(t *testing.T) {
|
||||||
|
|
||||||
func TestRecursiveRenameWalkError(t *testing.T) {
|
func TestRecursiveRenameWalkError(t *testing.T) {
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := NewBaseConnection("", ProtocolWebDAV, "", dataprovider.User{})
|
conn := NewBaseConnection("", ProtocolWebDAV, "", "", dataprovider.User{})
|
||||||
err := conn.checkRecursiveRenameDirPermissions(fs, fs, "/source", "/target")
|
err := conn.checkRecursiveRenameDirPermissions(fs, fs, "/source", "/target")
|
||||||
assert.ErrorIs(t, err, os.ErrNotExist)
|
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCrossRenameFsErrors(t *testing.T) {
|
func TestCrossRenameFsErrors(t *testing.T) {
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := NewBaseConnection("", ProtocolWebDAV, "", dataprovider.User{})
|
conn := NewBaseConnection("", ProtocolWebDAV, "", "", dataprovider.User{})
|
||||||
res := conn.hasSpaceForCrossRename(fs, vfs.QuotaCheckResult{}, 1, "missingsource")
|
res := conn.hasSpaceForCrossRename(fs, vfs.QuotaCheckResult{}, 1, "missingsource")
|
||||||
assert.False(t, res)
|
assert.False(t, res)
|
||||||
if runtime.GOOS != osWindows {
|
if runtime.GOOS != osWindows {
|
||||||
|
@ -143,7 +143,7 @@ func TestRenameVirtualFolders(t *testing.T) {
|
||||||
VirtualPath: vdir,
|
VirtualPath: vdir,
|
||||||
})
|
})
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := NewBaseConnection("", ProtocolFTP, "", u)
|
conn := NewBaseConnection("", ProtocolFTP, "", "", u)
|
||||||
res := conn.isRenamePermitted(fs, fs, "source", "target", vdir, "vdirtarget", nil)
|
res := conn.isRenamePermitted(fs, fs, "source", "target", vdir, "vdirtarget", nil)
|
||||||
assert.False(t, res)
|
assert.False(t, res)
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ func TestUpdateQuotaAfterRename(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fs, err := user.GetFilesystem("id")
|
fs, err := user.GetFilesystem("id")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
c := NewBaseConnection("", ProtocolSFTP, "", user)
|
c := NewBaseConnection("", ProtocolSFTP, "", "", user)
|
||||||
request := sftp.NewRequest("Rename", "/testfile")
|
request := sftp.NewRequest("Rename", "/testfile")
|
||||||
if runtime.GOOS != osWindows {
|
if runtime.GOOS != osWindows {
|
||||||
request.Filepath = "/dir"
|
request.Filepath = "/dir"
|
||||||
|
@ -225,7 +225,7 @@ func TestUpdateQuotaAfterRename(t *testing.T) {
|
||||||
|
|
||||||
func TestErrorsMapping(t *testing.T) {
|
func TestErrorsMapping(t *testing.T) {
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := NewBaseConnection("", ProtocolSFTP, "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}})
|
conn := NewBaseConnection("", ProtocolSFTP, "", "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}})
|
||||||
for _, protocol := range supportedProtocols {
|
for _, protocol := range supportedProtocols {
|
||||||
conn.SetProtocol(protocol)
|
conn.SetProtocol(protocol)
|
||||||
err := conn.GetFsError(fs, os.ErrNotExist)
|
err := conn.GetFsError(fs, os.ErrNotExist)
|
||||||
|
@ -291,7 +291,7 @@ func TestMaxWriteSize(t *testing.T) {
|
||||||
}
|
}
|
||||||
fs, err := user.GetFilesystem("123")
|
fs, err := user.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
conn := NewBaseConnection("", ProtocolFTP, "", user)
|
conn := NewBaseConnection("", ProtocolFTP, "", "", user)
|
||||||
quotaResult := vfs.QuotaCheckResult{
|
quotaResult := vfs.QuotaCheckResult{
|
||||||
HasSpace: true,
|
HasSpace: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1927,7 +1927,7 @@ func TestFsPermissionErrors(t *testing.T) {
|
||||||
func TestResolvePathError(t *testing.T) {
|
func TestResolvePathError(t *testing.T) {
|
||||||
u := getTestUser()
|
u := getTestUser()
|
||||||
u.HomeDir = "relative_path"
|
u.HomeDir = "relative_path"
|
||||||
conn := common.NewBaseConnection("", common.ProtocolFTP, "", u)
|
conn := common.NewBaseConnection("", common.ProtocolFTP, "", "", u)
|
||||||
testPath := "apath"
|
testPath := "apath"
|
||||||
_, err := conn.ListDir(testPath)
|
_, err := conn.ListDir(testPath)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
@ -2404,16 +2404,16 @@ func TestSFTPLoopError(t *testing.T) {
|
||||||
user1.VirtualFolders[0].FsConfig.SFTPConfig.Password = kms.NewPlainSecret(defaultPassword)
|
user1.VirtualFolders[0].FsConfig.SFTPConfig.Password = kms.NewPlainSecret(defaultPassword)
|
||||||
user2.FsConfig.SFTPConfig.Password = kms.NewPlainSecret(defaultPassword)
|
user2.FsConfig.SFTPConfig.Password = kms.NewPlainSecret(defaultPassword)
|
||||||
|
|
||||||
conn := common.NewBaseConnection("", common.ProtocolWebDAV, "", user1)
|
conn := common.NewBaseConnection("", common.ProtocolWebDAV, "", "", user1)
|
||||||
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
||||||
assert.ErrorIs(t, err, os.ErrPermission)
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
|
|
||||||
conn = common.NewBaseConnection("", common.ProtocolSFTP, "", user1)
|
conn = common.NewBaseConnection("", common.ProtocolSFTP, "", "", user1)
|
||||||
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
||||||
if assert.Error(t, err) {
|
if assert.Error(t, err) {
|
||||||
assert.Contains(t, err.Error(), "SFTP loop")
|
assert.Contains(t, err.Error(), "SFTP loop")
|
||||||
}
|
}
|
||||||
conn = common.NewBaseConnection("", common.ProtocolFTP, "", user1)
|
conn = common.NewBaseConnection("", common.ProtocolFTP, "", "", user1)
|
||||||
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
_, _, err = conn.GetFsAndResolvedPath(user1.VirtualFolders[0].VirtualPath)
|
||||||
if assert.Error(t, err) {
|
if assert.Error(t, err) {
|
||||||
assert.Contains(t, err.Error(), "SFTP loop")
|
assert.Contains(t, err.Error(), "SFTP loop")
|
||||||
|
@ -2650,7 +2650,7 @@ func TestProxyProtocol(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetProtocol(t *testing.T) {
|
func TestSetProtocol(t *testing.T) {
|
||||||
conn := common.NewBaseConnection("id", "sshd_exec", "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}})
|
conn := common.NewBaseConnection("id", "sshd_exec", "", "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}})
|
||||||
conn.SetProtocol(common.ProtocolSCP)
|
conn.SetProtocol(common.ProtocolSCP)
|
||||||
require.Equal(t, "SCP_id", conn.GetID())
|
require.Equal(t, "SCP_id", conn.GetID())
|
||||||
}
|
}
|
||||||
|
@ -2660,7 +2660,7 @@ func TestGetFsError(t *testing.T) {
|
||||||
u.FsConfig.Provider = sdk.GCSFilesystemProvider
|
u.FsConfig.Provider = sdk.GCSFilesystemProvider
|
||||||
u.FsConfig.GCSConfig.Bucket = "test"
|
u.FsConfig.GCSConfig.Bucket = "test"
|
||||||
u.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("invalid JSON for credentials")
|
u.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("invalid JSON for credentials")
|
||||||
conn := common.NewBaseConnection("", common.ProtocolFTP, "", u)
|
conn := common.NewBaseConnection("", common.ProtocolFTP, "", "", u)
|
||||||
_, _, err := conn.GetFsAndResolvedPath("/vpath")
|
_, _, err := conn.GetFsAndResolvedPath("/vpath")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ func (t *BaseTransfer) Close() error {
|
||||||
elapsed := time.Since(t.start).Nanoseconds() / 1000000
|
elapsed := time.Since(t.start).Nanoseconds() / 1000000
|
||||||
if t.transferType == TransferDownload {
|
if t.transferType == TransferDownload {
|
||||||
logger.TransferLog(downloadLogSender, t.fsPath, elapsed, atomic.LoadInt64(&t.BytesSent), t.Connection.User.Username,
|
logger.TransferLog(downloadLogSender, t.fsPath, elapsed, atomic.LoadInt64(&t.BytesSent), t.Connection.User.Username,
|
||||||
t.Connection.ID, t.Connection.protocol, t.Connection.remoteAddr)
|
t.Connection.ID, t.Connection.protocol, t.Connection.localAddr, t.Connection.remoteAddr)
|
||||||
ExecuteActionNotification(&t.Connection.User, operationDownload, t.fsPath, t.requestPath, "", "", t.Connection.protocol,
|
ExecuteActionNotification(&t.Connection.User, operationDownload, t.fsPath, t.requestPath, "", "", t.Connection.protocol,
|
||||||
atomic.LoadInt64(&t.BytesSent), t.ErrTransfer)
|
atomic.LoadInt64(&t.BytesSent), t.ErrTransfer)
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,7 +247,7 @@ func (t *BaseTransfer) Close() error {
|
||||||
t.Connection.Log(logger.LevelDebug, "uploaded file size %v", fileSize)
|
t.Connection.Log(logger.LevelDebug, "uploaded file size %v", fileSize)
|
||||||
t.updateQuota(numFiles, fileSize)
|
t.updateQuota(numFiles, fileSize)
|
||||||
logger.TransferLog(uploadLogSender, t.fsPath, elapsed, atomic.LoadInt64(&t.BytesReceived), t.Connection.User.Username,
|
logger.TransferLog(uploadLogSender, t.fsPath, elapsed, atomic.LoadInt64(&t.BytesReceived), t.Connection.User.Username,
|
||||||
t.Connection.ID, t.Connection.protocol, t.Connection.remoteAddr)
|
t.Connection.ID, t.Connection.protocol, t.Connection.localAddr, t.Connection.remoteAddr)
|
||||||
ExecuteActionNotification(&t.Connection.User, operationUpload, t.fsPath, t.requestPath, "", "", t.Connection.protocol, fileSize,
|
ExecuteActionNotification(&t.Connection.User, operationUpload, t.fsPath, t.requestPath, "", "", t.Connection.protocol, fileSize,
|
||||||
t.ErrTransfer)
|
t.ErrTransfer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTransferUpdateQuota(t *testing.T) {
|
func TestTransferUpdateQuota(t *testing.T) {
|
||||||
conn := NewBaseConnection("", ProtocolSFTP, "", dataprovider.User{})
|
conn := NewBaseConnection("", ProtocolSFTP, "", "", dataprovider.User{})
|
||||||
transfer := BaseTransfer{
|
transfer := BaseTransfer{
|
||||||
Connection: conn,
|
Connection: conn,
|
||||||
transferType: TransferUpload,
|
transferType: TransferUpload,
|
||||||
|
@ -64,7 +64,7 @@ func TestTransferThrottling(t *testing.T) {
|
||||||
// some tolerance
|
// some tolerance
|
||||||
wantedUploadElapsed -= wantedDownloadElapsed / 10
|
wantedUploadElapsed -= wantedDownloadElapsed / 10
|
||||||
wantedDownloadElapsed -= wantedDownloadElapsed / 10
|
wantedDownloadElapsed -= wantedDownloadElapsed / 10
|
||||||
conn := NewBaseConnection("id", ProtocolSCP, "", u)
|
conn := NewBaseConnection("id", ProtocolSCP, "", "", u)
|
||||||
transfer := NewBaseTransfer(nil, conn, nil, "", "", "", TransferUpload, 0, 0, 0, true, fs)
|
transfer := NewBaseTransfer(nil, conn, nil, "", "", "", TransferUpload, 0, 0, 0, true, fs)
|
||||||
transfer.BytesReceived = testFileSize
|
transfer.BytesReceived = testFileSize
|
||||||
transfer.Connection.UpdateLastActivity()
|
transfer.Connection.UpdateLastActivity()
|
||||||
|
@ -100,7 +100,7 @@ func TestRealPath(t *testing.T) {
|
||||||
u.Permissions["/"] = []string{dataprovider.PermAny}
|
u.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
file, err := os.Create(testFile)
|
file, err := os.Create(testFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", u)
|
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", "", u)
|
||||||
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
||||||
rPath := transfer.GetRealFsPath(testFile)
|
rPath := transfer.GetRealFsPath(testFile)
|
||||||
assert.Equal(t, testFile, rPath)
|
assert.Equal(t, testFile, rPath)
|
||||||
|
@ -137,7 +137,7 @@ func TestTruncate(t *testing.T) {
|
||||||
}
|
}
|
||||||
_, err = file.Write([]byte("hello"))
|
_, err = file.Write([]byte("hello"))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", u)
|
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", "", u)
|
||||||
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 5, 100, false, fs)
|
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 5, 100, false, fs)
|
||||||
|
|
||||||
err = conn.SetStat("/transfer_test_file", &StatAttributes{
|
err = conn.SetStat("/transfer_test_file", &StatAttributes{
|
||||||
|
@ -201,7 +201,7 @@ func TestTransferErrors(t *testing.T) {
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, "unable to open test file")
|
assert.FailNow(t, "unable to open test file")
|
||||||
}
|
}
|
||||||
conn := NewBaseConnection("id", ProtocolSFTP, "", u)
|
conn := NewBaseConnection("id", ProtocolSFTP, "", "", u)
|
||||||
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
||||||
assert.Nil(t, transfer.cancelFn)
|
assert.Nil(t, transfer.cancelFn)
|
||||||
assert.Equal(t, testFile, transfer.GetFsPath())
|
assert.Equal(t, testFile, transfer.GetFsPath())
|
||||||
|
@ -272,7 +272,7 @@ func TestRemovePartialCryptoFile(t *testing.T) {
|
||||||
HomeDir: os.TempDir(),
|
HomeDir: os.TempDir(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", u)
|
conn := NewBaseConnection(fs.ConnectionID(), ProtocolSFTP, "", "", u)
|
||||||
transfer := NewBaseTransfer(nil, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
transfer := NewBaseTransfer(nil, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload, 0, 0, 0, true, fs)
|
||||||
transfer.ErrTransfer = errors.New("test error")
|
transfer.ErrTransfer = errors.New("test error")
|
||||||
_, err = transfer.getUploadFileSize()
|
_, err = transfer.getUploadFileSize()
|
||||||
|
|
|
@ -1532,7 +1532,6 @@ func isPasswordOK(user *User, password string) (bool, error) {
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(user.Password, bcryptPwdPrefix) {
|
} else if strings.HasPrefix(user.Password, bcryptPwdPrefix) {
|
||||||
if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
||||||
providerLog(logger.LevelWarn, "error comparing password with bcrypt hash: %v", err)
|
|
||||||
return match, ErrInvalidCredentials
|
return match, ErrInvalidCredentials
|
||||||
}
|
}
|
||||||
match = true
|
match = true
|
||||||
|
@ -1583,20 +1582,24 @@ func checkUserAndPass(user *User, password, ip, protocol string) (User, error) {
|
||||||
if !user.Filters.Hooks.CheckPasswordDisabled {
|
if !user.Filters.Hooks.CheckPasswordDisabled {
|
||||||
hookResponse, err := executeCheckPasswordHook(user.Username, password, ip, protocol)
|
hookResponse, err := executeCheckPasswordHook(user.Username, password, ip, protocol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
providerLog(logger.LevelDebug, "error executing check password hook: %v", err)
|
providerLog(logger.LevelDebug, "error executing check password hook for user %#v, ip %v, protocol %v: %v",
|
||||||
|
user.Username, ip, protocol, err)
|
||||||
return *user, errors.New("unable to check credentials")
|
return *user, errors.New("unable to check credentials")
|
||||||
}
|
}
|
||||||
switch hookResponse.Status {
|
switch hookResponse.Status {
|
||||||
case -1:
|
case -1:
|
||||||
// no hook configured
|
// no hook configured
|
||||||
case 1:
|
case 1:
|
||||||
providerLog(logger.LevelDebug, "password accepted by check password hook")
|
providerLog(logger.LevelDebug, "password accepted by check password hook for user %#v, ip %v, protocol %v",
|
||||||
|
user.Username, ip, protocol)
|
||||||
return *user, nil
|
return *user, nil
|
||||||
case 2:
|
case 2:
|
||||||
providerLog(logger.LevelDebug, "partial success from check password hook")
|
providerLog(logger.LevelDebug, "partial success from check password hook for user %#v, ip %v, protocol %v",
|
||||||
|
user.Username, ip, protocol)
|
||||||
password = hookResponse.ToVerify
|
password = hookResponse.ToVerify
|
||||||
default:
|
default:
|
||||||
providerLog(logger.LevelDebug, "password rejected by check password hook, status: %v", hookResponse.Status)
|
providerLog(logger.LevelDebug, "password rejected by check password hook for user %#v, ip %v, protocol %v, status: %v",
|
||||||
|
user.Username, ip, protocol, hookResponse.Status)
|
||||||
return *user, ErrInvalidCredentials
|
return *user, ErrInvalidCredentials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2116,7 +2119,8 @@ func executePreLoginHook(username, loginMethod, ip, protocol string) (User, erro
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
out, err := getPreLoginHookResponse(loginMethod, ip, protocol, userAsJSON)
|
out, err := getPreLoginHookResponse(loginMethod, ip, protocol, userAsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return u, fmt.Errorf("pre-login hook error: %v, elapsed %v", err, time.Since(startTime))
|
return u, fmt.Errorf("pre-login hook error: %v, username %#v, ip %v, protocol %v elapsed %v",
|
||||||
|
err, username, ip, protocol, time.Since(startTime))
|
||||||
}
|
}
|
||||||
providerLog(logger.LevelDebug, "pre-login hook completed, elapsed: %v", time.Since(startTime))
|
providerLog(logger.LevelDebug, "pre-login hook completed, elapsed: %v", time.Since(startTime))
|
||||||
if util.IsByteArrayEmpty(out) {
|
if util.IsByteArrayEmpty(out) {
|
||||||
|
@ -2209,8 +2213,8 @@ func ExecutePostLoginHook(user *User, loginMethod, ip, protocol string, err erro
|
||||||
respCode = resp.StatusCode
|
respCode = resp.StatusCode
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
}
|
}
|
||||||
providerLog(logger.LevelDebug, "post login hook executed, response code: %v, elapsed: %v err: %v",
|
providerLog(logger.LevelDebug, "post login hook executed for user %#v, ip %v, protocol %v, response code: %v, elapsed: %v err: %v",
|
||||||
respCode, time.Since(startTime), err)
|
user.Username, ip, protocol, respCode, time.Since(startTime), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||||
|
@ -2224,7 +2228,8 @@ func ExecutePostLoginHook(user *User, loginMethod, ip, protocol string, err erro
|
||||||
fmt.Sprintf("SFTPGO_LOGIND_PROTOCOL=%v", protocol))
|
fmt.Sprintf("SFTPGO_LOGIND_PROTOCOL=%v", protocol))
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
providerLog(logger.LevelDebug, "post login hook executed, elapsed %v err: %v", time.Since(startTime), err)
|
providerLog(logger.LevelDebug, "post login hook executed for user %#v, ip %v, protocol %v, elapsed %v err: %v",
|
||||||
|
user.Username, ip, protocol, time.Since(startTime), err)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2312,9 +2317,9 @@ func doExternalAuth(username, password string, pubKey []byte, keyboardInteractiv
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
out, err := getExternalAuthResponse(username, password, pkey, keyboardInteractive, ip, protocol, tlsCert, userAsJSON)
|
out, err := getExternalAuthResponse(username, password, pkey, keyboardInteractive, ip, protocol, tlsCert, userAsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, fmt.Errorf("external auth error: %v, elapsed: %v", err, time.Since(startTime))
|
return user, fmt.Errorf("external auth error for user %#v: %v, elapsed: %v", username, err, time.Since(startTime))
|
||||||
}
|
}
|
||||||
providerLog(logger.LevelDebug, "external auth completed, elapsed: %v", time.Since(startTime))
|
providerLog(logger.LevelDebug, "external auth completed for user %#v, elapsed: %v", username, time.Since(startTime))
|
||||||
if util.IsByteArrayEmpty(out) {
|
if util.IsByteArrayEmpty(out) {
|
||||||
providerLog(logger.LevelDebug, "empty response from external hook, no modification requested for user %#v id: %v",
|
providerLog(logger.LevelDebug, "empty response from external hook, no modification requested for user %#v id: %v",
|
||||||
username, u.ID)
|
username, u.ID)
|
||||||
|
|
|
@ -13,6 +13,7 @@ The logs can be divided into the following categories:
|
||||||
- `sender` string. `Upload` or `Download`
|
- `sender` string. `Upload` or `Download`
|
||||||
- `time` string. Date/time with millisecond precision
|
- `time` string. Date/time with millisecond precision
|
||||||
- `level` string
|
- `level` string
|
||||||
|
- `local_addr` string. IP/port of the local address the connection arrived on. For example `127.0.0.1:1234`
|
||||||
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
||||||
- `elapsed_ms`, int64. Elapsed time, as milliseconds, for the upload/download
|
- `elapsed_ms`, int64. Elapsed time, as milliseconds, for the upload/download
|
||||||
- `size_bytes`, int64. Size, as bytes, of the download/upload
|
- `size_bytes`, int64. Size, as bytes, of the download/upload
|
||||||
|
@ -23,6 +24,7 @@ The logs can be divided into the following categories:
|
||||||
- **"command logs"**, SFTP/SCP command logs:
|
- **"command logs"**, SFTP/SCP command logs:
|
||||||
- `sender` string. `Rename`, `Rmdir`, `Mkdir`, `Symlink`, `Remove`, `Chmod`, `Chown`, `Chtimes`, `Truncate`, `SSHCommand`
|
- `sender` string. `Rename`, `Rmdir`, `Mkdir`, `Symlink`, `Remove`, `Chmod`, `Chown`, `Chtimes`, `Truncate`, `SSHCommand`
|
||||||
- `level` string
|
- `level` string
|
||||||
|
- `local_addr` string. IP/port of the local address the connection arrived on. For example `127.0.0.1:1234`
|
||||||
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
||||||
- `username`, string
|
- `username`, string
|
||||||
- `file_path` string
|
- `file_path` string
|
||||||
|
@ -39,6 +41,7 @@ The logs can be divided into the following categories:
|
||||||
- **"http logs"**, REST API logs:
|
- **"http logs"**, REST API logs:
|
||||||
- `sender` string. `httpd`
|
- `sender` string. `httpd`
|
||||||
- `level` string
|
- `level` string
|
||||||
|
- `local_addr` string. IP/port of the local address the connection arrived on. For example `127.0.0.1:1234`
|
||||||
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
- `remote_addr` string. IP and, optionally, port of the remote client. For example `127.0.0.1:1234` or `127.0.0.1`
|
||||||
- `proto` string, for example `HTTP/1.1`
|
- `proto` string, for example `HTTP/1.1`
|
||||||
- `method` string. HTTP method (`GET`, `POST`, `PUT`, `DELETE` etc.)
|
- `method` string. HTTP method (`GET`, `POST`, `PUT`, `DELETE` etc.)
|
||||||
|
|
|
@ -40,7 +40,12 @@ func (c *Connection) GetClientVersion() string {
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRemoteAddress return the connected client's address
|
// GetLocalAddress returns local connection address
|
||||||
|
func (c *Connection) GetLocalAddress() string {
|
||||||
|
return c.clientContext.LocalAddr().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRemoteAddress returns the connected client's address
|
||||||
func (c *Connection) GetRemoteAddress() string {
|
func (c *Connection) GetRemoteAddress() string {
|
||||||
return c.clientContext.RemoteAddr().String()
|
return c.clientContext.RemoteAddr().String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,7 +516,7 @@ func TestClientVersion(t *testing.T) {
|
||||||
connID := fmt.Sprintf("2_%v", mockCC.ID())
|
connID := fmt.Sprintf("2_%v", mockCC.ID())
|
||||||
user := dataprovider.User{}
|
user := dataprovider.User{}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
@ -533,7 +533,7 @@ func TestDriverMethodsNotImplemented(t *testing.T) {
|
||||||
connID := fmt.Sprintf("2_%v", mockCC.ID())
|
connID := fmt.Sprintf("2_%v", mockCC.ID())
|
||||||
user := dataprovider.User{}
|
user := dataprovider.User{}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
_, err := connection.Create("")
|
_, err := connection.Create("")
|
||||||
|
@ -560,7 +560,7 @@ func TestResolvePathErrors(t *testing.T) {
|
||||||
mockCC := mockFTPClientContext{}
|
mockCC := mockFTPClientContext{}
|
||||||
connID := fmt.Sprintf("%v", mockCC.ID())
|
connID := fmt.Sprintf("%v", mockCC.ID())
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
err := connection.Mkdir("", os.ModePerm)
|
err := connection.Mkdir("", os.ModePerm)
|
||||||
|
@ -625,7 +625,7 @@ func TestUploadFileStatError(t *testing.T) {
|
||||||
connID := fmt.Sprintf("%v", mockCC.ID())
|
connID := fmt.Sprintf("%v", mockCC.ID())
|
||||||
fs := vfs.NewOsFs(connID, user.HomeDir, "")
|
fs := vfs.NewOsFs(connID, user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
testFile := filepath.Join(user.HomeDir, "test", "testfile")
|
testFile := filepath.Join(user.HomeDir, "test", "testfile")
|
||||||
|
@ -655,7 +655,7 @@ func TestAVBLErrors(t *testing.T) {
|
||||||
mockCC := mockFTPClientContext{}
|
mockCC := mockFTPClientContext{}
|
||||||
connID := fmt.Sprintf("%v", mockCC.ID())
|
connID := fmt.Sprintf("%v", mockCC.ID())
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
_, err := connection.GetAvailableSpace("/")
|
_, err := connection.GetAvailableSpace("/")
|
||||||
|
@ -678,7 +678,7 @@ func TestUploadOverwriteErrors(t *testing.T) {
|
||||||
connID := fmt.Sprintf("%v", mockCC.ID())
|
connID := fmt.Sprintf("%v", mockCC.ID())
|
||||||
fs := newMockOsFs(nil, nil, false, connID, user.GetHomeDir())
|
fs := newMockOsFs(nil, nil, false, connID, user.GetHomeDir())
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
flags := 0
|
flags := 0
|
||||||
|
@ -734,7 +734,7 @@ func TestTransferErrors(t *testing.T) {
|
||||||
connID := fmt.Sprintf("%v", mockCC.ID())
|
connID := fmt.Sprintf("%v", mockCC.ID())
|
||||||
fs := newMockOsFs(nil, nil, false, connID, user.GetHomeDir())
|
fs := newMockOsFs(nil, nil, false, connID, user.GetHomeDir())
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, "", "", user),
|
||||||
clientContext: mockCC,
|
clientContext: mockCC,
|
||||||
}
|
}
|
||||||
baseTransfer := common.NewBaseTransfer(file, connection.BaseConnection, nil, file.Name(), file.Name(), testfile,
|
baseTransfer := common.NewBaseTransfer(file, connection.BaseConnection, nil, file.Name(), file.Name(), testfile,
|
||||||
|
|
|
@ -156,7 +156,8 @@ func (s *Server) ClientConnected(cc ftpserver.ClientContext) (string, error) {
|
||||||
connID := fmt.Sprintf("%v_%v", s.ID, cc.ID())
|
connID := fmt.Sprintf("%v_%v", s.ID, cc.ID())
|
||||||
user := dataprovider.User{}
|
user := dataprovider.User{}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, cc.RemoteAddr().String(), user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolFTP, cc.LocalAddr().String(),
|
||||||
|
cc.RemoteAddr().String(), user),
|
||||||
clientContext: cc,
|
clientContext: cc,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
@ -336,7 +337,8 @@ func (s *Server) validateUser(user dataprovider.User, cc ftpserver.ClientContext
|
||||||
return nil, common.ErrInternalFailure
|
return nil, common.ErrInternalFailure
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fmt.Sprintf("%v_%v", s.ID, cc.ID()), common.ProtocolFTP, remoteAddr, user),
|
BaseConnection: common.NewBaseConnection(fmt.Sprintf("%v_%v", s.ID, cc.ID()), common.ProtocolFTP,
|
||||||
|
cc.LocalAddr().String(), remoteAddr, user),
|
||||||
clientContext: cc,
|
clientContext: cc,
|
||||||
}
|
}
|
||||||
err = common.Connections.Swap(connection)
|
err = common.Connections.Swap(connection)
|
||||||
|
|
|
@ -37,7 +37,8 @@ func getUserConnection(w http.ResponseWriter, r *http.Request) (*Connection, err
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, r.RemoteAddr, user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, util.GetHTTPLocalAddress(r),
|
||||||
|
r.RemoteAddr, user),
|
||||||
request: r,
|
request: r,
|
||||||
}
|
}
|
||||||
return connection, nil
|
return connection, nil
|
||||||
|
|
|
@ -28,7 +28,12 @@ func (c *Connection) GetClientVersion() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRemoteAddress return the connected client's address
|
// GetLocalAddress returns local connection address
|
||||||
|
func (c *Connection) GetLocalAddress() string {
|
||||||
|
return util.GetHTTPLocalAddress(c.request)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRemoteAddress returns the connected client's address
|
||||||
func (c *Connection) GetRemoteAddress() string {
|
func (c *Connection) GetRemoteAddress() string {
|
||||||
if c.request != nil {
|
if c.request != nil {
|
||||||
return c.request.RemoteAddr
|
return c.request.RemoteAddr
|
||||||
|
|
|
@ -177,6 +177,10 @@ func (c *fakeConnection) GetCommand() string {
|
||||||
return c.command
|
return c.command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *fakeConnection) GetLocalAddress() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (c *fakeConnection) GetRemoteAddress() string {
|
func (c *fakeConnection) GetRemoteAddress() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -2778,7 +2782,7 @@ func TestCloseActiveConnection(t *testing.T) {
|
||||||
_, err := httpdtest.CloseConnection("non_existent_id", http.StatusNotFound)
|
_, err := httpdtest.CloseConnection("non_existent_id", http.StatusNotFound)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
user := getTestUser()
|
user := getTestUser()
|
||||||
c := common.NewBaseConnection("connID", common.ProtocolSFTP, "", user)
|
c := common.NewBaseConnection("connID", common.ProtocolSFTP, "", "", user)
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -2791,12 +2795,12 @@ func TestCloseActiveConnection(t *testing.T) {
|
||||||
func TestCloseConnectionAfterUserUpdateDelete(t *testing.T) {
|
func TestCloseConnectionAfterUserUpdateDelete(t *testing.T) {
|
||||||
user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
c := common.NewBaseConnection("connID", common.ProtocolFTP, "", user)
|
c := common.NewBaseConnection("connID", common.ProtocolFTP, "", "", user)
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
common.Connections.Add(fakeConn)
|
common.Connections.Add(fakeConn)
|
||||||
c1 := common.NewBaseConnection("connID1", common.ProtocolSFTP, "", user)
|
c1 := common.NewBaseConnection("connID1", common.ProtocolSFTP, "", "", user)
|
||||||
fakeConn1 := &fakeConnection{
|
fakeConn1 := &fakeConnection{
|
||||||
BaseConnection: c1,
|
BaseConnection: c1,
|
||||||
}
|
}
|
||||||
|
@ -3530,7 +3534,7 @@ func TestLoaddataMode(t *testing.T) {
|
||||||
assert.Equal(t, int64(789), folder.LastQuotaUpdate)
|
assert.Equal(t, int64(789), folder.LastQuotaUpdate)
|
||||||
assert.Len(t, folder.Users, 0)
|
assert.Len(t, folder.Users, 0)
|
||||||
|
|
||||||
c := common.NewBaseConnection("connID", common.ProtocolFTP, "", user)
|
c := common.NewBaseConnection("connID", common.ProtocolFTP, "", "", user)
|
||||||
fakeConn := &fakeConnection{
|
fakeConn := &fakeConnection{
|
||||||
BaseConnection: c,
|
BaseConnection: c,
|
||||||
}
|
}
|
||||||
|
@ -5060,7 +5064,7 @@ func TestWebClientMaxConnections(t *testing.T) {
|
||||||
// now add a fake connection
|
// now add a fake connection
|
||||||
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
||||||
connection := &httpd.Connection{
|
connection := &httpd.Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolHTTP, "", "", user),
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
|
||||||
|
@ -5198,7 +5202,7 @@ func TestMaxSessions(t *testing.T) {
|
||||||
// now add a fake connection
|
// now add a fake connection
|
||||||
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
||||||
connection := &httpd.Connection{
|
connection := &httpd.Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolHTTP, "", "", user),
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
_, err = getJWTWebClientTokenFromTestServer(defaultUsername, defaultPassword)
|
_, err = getJWTWebClientTokenFromTestServer(defaultUsername, defaultPassword)
|
||||||
|
|
|
@ -1211,7 +1211,7 @@ func TestCompressorAbortHandler(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", dataprovider.User{}),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
renderCompressedFiles(&failingWriter{}, connection, "", nil)
|
renderCompressedFiles(&failingWriter{}, connection, "", nil)
|
||||||
|
@ -1226,7 +1226,7 @@ func TestZipErrors(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1442,7 +1442,7 @@ func TestConnection(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
assert.Empty(t, connection.GetClientVersion())
|
assert.Empty(t, connection.GetClientVersion())
|
||||||
|
@ -1466,7 +1466,7 @@ func TestGetFileWriterErrors(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
_, err := connection.getFileWriter("name")
|
_, err := connection.getFileWriter("name")
|
||||||
|
@ -1482,7 +1482,7 @@ func TestGetFileWriterErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
connection = &Connection{
|
connection = &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
_, err = connection.getFileWriter("/path")
|
_, err = connection.getFileWriter("/path")
|
||||||
|
@ -1499,7 +1499,7 @@ func TestHTTPDFile(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", user),
|
BaseConnection: common.NewBaseConnection(xid.New().String(), common.ProtocolHTTP, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,8 @@ func handleWebClientDownloadZip(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, r.RemoteAddr, user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, util.GetHTTPLocalAddress(r),
|
||||||
|
r.RemoteAddr, user),
|
||||||
request: r,
|
request: r,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
@ -326,7 +327,8 @@ func handleClientGetDirContents(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, r.RemoteAddr, user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, util.GetHTTPLocalAddress(r),
|
||||||
|
r.RemoteAddr, user),
|
||||||
request: r,
|
request: r,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
@ -386,7 +388,8 @@ func handleClientGetFiles(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, r.RemoteAddr, user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolHTTP, util.GetHTTPLocalAddress(r),
|
||||||
|
r.RemoteAddr, user),
|
||||||
request: r,
|
request: r,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
|
|
@ -259,10 +259,11 @@ func ErrorToConsole(format string, v ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferLog logs uploads or downloads
|
// TransferLog logs uploads or downloads
|
||||||
func TransferLog(operation, path string, elapsed int64, size int64, user, connectionID, protocol, remoteAddr string) {
|
func TransferLog(operation, path string, elapsed int64, size int64, user, connectionID, protocol, localAddr, remoteAddr string) {
|
||||||
logger.Info().
|
logger.Info().
|
||||||
Timestamp().
|
Timestamp().
|
||||||
Str("sender", operation).
|
Str("sender", operation).
|
||||||
|
Str("local_addr", localAddr).
|
||||||
Str("remote_addr", remoteAddr).
|
Str("remote_addr", remoteAddr).
|
||||||
Int64("elapsed_ms", elapsed).
|
Int64("elapsed_ms", elapsed).
|
||||||
Int64("size_bytes", size).
|
Int64("size_bytes", size).
|
||||||
|
@ -275,7 +276,7 @@ func TransferLog(operation, path string, elapsed int64, size int64, user, connec
|
||||||
|
|
||||||
// CommandLog logs an SFTP/SCP/SSH command
|
// CommandLog logs an SFTP/SCP/SSH command
|
||||||
func CommandLog(command, path, target, user, fileMode, connectionID, protocol string, uid, gid int, atime, mtime,
|
func CommandLog(command, path, target, user, fileMode, connectionID, protocol string, uid, gid int, atime, mtime,
|
||||||
sshCommand string, size int64, remoteAddr string) {
|
sshCommand string, size int64, localAddr, remoteAddr string) {
|
||||||
logger.Info().
|
logger.Info().
|
||||||
Timestamp().
|
Timestamp().
|
||||||
Str("sender", command).
|
Str("sender", command).
|
||||||
|
|
|
@ -2,6 +2,7 @@ package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ func (l *StructuredLogger) NewLogEntry(r *http.Request) middleware.LogEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
fields := map[string]interface{}{
|
||||||
|
"local_addr": getLocalAddress(r),
|
||||||
"remote_addr": r.RemoteAddr,
|
"remote_addr": r.RemoteAddr,
|
||||||
"proto": r.Proto,
|
"proto": r.Proto,
|
||||||
"method": r.Method,
|
"method": r.Method,
|
||||||
|
@ -77,3 +79,14 @@ func (l *StructuredLoggerEntry) Panic(v interface{}, stack []byte) {
|
||||||
Str("panic", fmt.Sprintf("%+v", v)).
|
Str("panic", fmt.Sprintf("%+v", v)).
|
||||||
Send()
|
Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLocalAddress(r *http.Request) string {
|
||||||
|
if r == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
localAddr, ok := r.Context().Value(http.LocalAddrContextKey).(net.Addr)
|
||||||
|
if ok {
|
||||||
|
return localAddr.String()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ type Connection struct {
|
||||||
ClientVersion string
|
ClientVersion string
|
||||||
// Remote address for this connection
|
// Remote address for this connection
|
||||||
RemoteAddr net.Addr
|
RemoteAddr net.Addr
|
||||||
|
LocalAddr net.Addr
|
||||||
channel io.ReadWriteCloser
|
channel io.ReadWriteCloser
|
||||||
command string
|
command string
|
||||||
}
|
}
|
||||||
|
@ -31,7 +32,15 @@ func (c *Connection) GetClientVersion() string {
|
||||||
return c.ClientVersion
|
return c.ClientVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRemoteAddress return the connected client's address
|
// GetLocalAddress returns local connection address
|
||||||
|
func (c *Connection) GetLocalAddress() string {
|
||||||
|
if c.LocalAddr == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return c.LocalAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRemoteAddress returns the connected client's address
|
||||||
func (c *Connection) GetRemoteAddress() string {
|
func (c *Connection) GetRemoteAddress() string {
|
||||||
if c.RemoteAddr == nil {
|
if c.RemoteAddr == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -161,7 +161,7 @@ func TestUploadResumeInvalidOffset(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", user)
|
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", "", user)
|
||||||
baseTransfer := common.NewBaseTransfer(file, conn, nil, file.Name(), file.Name(), testfile, common.TransferUpload, 10, 0, 0, false, fs)
|
baseTransfer := common.NewBaseTransfer(file, conn, nil, file.Name(), file.Name(), testfile, common.TransferUpload, 10, 0, 0, false, fs)
|
||||||
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
||||||
_, err = transfer.WriteAt([]byte("test"), 0)
|
_, err = transfer.WriteAt([]byte("test"), 0)
|
||||||
|
@ -191,7 +191,7 @@ func TestReadWriteErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", user)
|
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", "", user)
|
||||||
baseTransfer := common.NewBaseTransfer(file, conn, nil, file.Name(), file.Name(), testfile, common.TransferDownload, 0, 0, 0, false, fs)
|
baseTransfer := common.NewBaseTransfer(file, conn, nil, file.Name(), file.Name(), testfile, common.TransferDownload, 0, 0, 0, false, fs)
|
||||||
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
||||||
err = file.Close()
|
err = file.Close()
|
||||||
|
@ -239,7 +239,7 @@ func TestReadWriteErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnsupportedListOP(t *testing.T) {
|
func TestUnsupportedListOP(t *testing.T) {
|
||||||
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", dataprovider.User{})
|
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", "", dataprovider.User{})
|
||||||
sftpConn := Connection{
|
sftpConn := Connection{
|
||||||
BaseConnection: conn,
|
BaseConnection: conn,
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ func TestTransferCancelFn(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", user)
|
conn := common.NewBaseConnection("", common.ProtocolSFTP, "", "", user)
|
||||||
baseTransfer := common.NewBaseTransfer(file, conn, cancelFn, file.Name(), file.Name(), testfile, common.TransferDownload, 0, 0, 0, false, fs)
|
baseTransfer := common.NewBaseTransfer(file, conn, cancelFn, file.Name(), file.Name(), testfile, common.TransferDownload, 0, 0, 0, false, fs)
|
||||||
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
transfer := newTransfer(baseTransfer, nil, nil, nil)
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ func TestUploadFiles(t *testing.T) {
|
||||||
fs := vfs.NewOsFs("123", os.TempDir(), "")
|
fs := vfs.NewOsFs("123", os.TempDir(), "")
|
||||||
u := dataprovider.User{}
|
u := dataprovider.User{}
|
||||||
c := Connection{
|
c := Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", u),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", u),
|
||||||
}
|
}
|
||||||
var flags sftp.FileOpenFlags
|
var flags sftp.FileOpenFlags
|
||||||
flags.Write = true
|
flags.Write = true
|
||||||
|
@ -338,7 +338,7 @@ func TestWithInvalidHome(t *testing.T) {
|
||||||
fs, err := u.GetFilesystem("123")
|
fs, err := u.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
c := Connection{
|
c := Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", u),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", u),
|
||||||
}
|
}
|
||||||
_, err = fs.ResolvePath("../upper_path")
|
_, err = fs.ResolvePath("../upper_path")
|
||||||
assert.Error(t, err, "tested path is not a home subdir")
|
assert.Error(t, err, "tested path is not a home subdir")
|
||||||
|
@ -373,7 +373,7 @@ func TestSFTPGetUsedQuota(t *testing.T) {
|
||||||
u.Permissions = make(map[string][]string)
|
u.Permissions = make(map[string][]string)
|
||||||
u.Permissions["/"] = []string{dataprovider.PermAny}
|
u.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := Connection{
|
connection := Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", u),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", u),
|
||||||
}
|
}
|
||||||
quotaResult := connection.HasSpace(false, false, "/")
|
quotaResult := connection.HasSpace(false, false, "/")
|
||||||
assert.False(t, quotaResult.HasSpace)
|
assert.False(t, quotaResult.HasSpace)
|
||||||
|
@ -470,7 +470,7 @@ func TestSSHCommandErrors(t *testing.T) {
|
||||||
user.Permissions = make(map[string][]string)
|
user.Permissions = make(map[string][]string)
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := Connection{
|
connection := Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSSH, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSSH, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
cmd := sshCommand{
|
cmd := sshCommand{
|
||||||
|
@ -610,7 +610,7 @@ func TestCommandsWithExtensionsFilter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSSH, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSSH, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
cmd := sshCommand{
|
cmd := sshCommand{
|
||||||
|
@ -673,7 +673,7 @@ func TestSSHCommandsRemoteFs(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
cmd := sshCommand{
|
cmd := sshCommand{
|
||||||
|
@ -720,7 +720,7 @@ func TestSSHCmdGetFsErrors(t *testing.T) {
|
||||||
user.Permissions = map[string][]string{}
|
user.Permissions = map[string][]string{}
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
cmd := sshCommand{
|
cmd := sshCommand{
|
||||||
|
@ -773,7 +773,7 @@ func TestGitVirtualFolders(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
conn := &Connection{
|
conn := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
cmd := sshCommand{
|
cmd := sshCommand{
|
||||||
command: "git-receive-pack",
|
command: "git-receive-pack",
|
||||||
|
@ -821,7 +821,7 @@ func TestRsyncOptions(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
conn := &Connection{
|
conn := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
sshCmd := sshCommand{
|
sshCmd := sshCommand{
|
||||||
command: "rsync",
|
command: "rsync",
|
||||||
|
@ -838,7 +838,7 @@ func TestRsyncOptions(t *testing.T) {
|
||||||
user.Permissions = permissions
|
user.Permissions = permissions
|
||||||
|
|
||||||
conn = &Connection{
|
conn = &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
sshCmd = sshCommand{
|
sshCmd = sshCommand{
|
||||||
command: "rsync",
|
command: "rsync",
|
||||||
|
@ -872,7 +872,7 @@ func TestSystemCommandSizeForPath(t *testing.T) {
|
||||||
fs, err := user.GetFilesystem("123")
|
fs, err := user.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
conn := &Connection{
|
conn := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
sshCmd := sshCommand{
|
sshCmd := sshCommand{
|
||||||
command: "rsync",
|
command: "rsync",
|
||||||
|
@ -936,7 +936,7 @@ func TestSystemCommandErrors(t *testing.T) {
|
||||||
fs, err := user.GetFilesystem("123")
|
fs, err := user.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
var sshCmd sshCommand
|
var sshCmd sshCommand
|
||||||
|
@ -1012,7 +1012,7 @@ func TestCommandGetFsError(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
conn := &Connection{
|
conn := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
sshCmd := sshCommand{
|
sshCmd := sshCommand{
|
||||||
command: "rsync",
|
command: "rsync",
|
||||||
|
@ -1030,7 +1030,7 @@ func TestCommandGetFsError(t *testing.T) {
|
||||||
ReadError: nil,
|
ReadError: nil,
|
||||||
}
|
}
|
||||||
conn = &Connection{
|
conn = &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1124,7 +1124,7 @@ func TestSCPUploadError(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
|
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1163,7 +1163,7 @@ func TestSCPInvalidEndDir(t *testing.T) {
|
||||||
StdErrBuffer: bytes.NewBuffer(stdErrBuf),
|
StdErrBuffer: bytes.NewBuffer(stdErrBuf),
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", dataprovider.User{
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", dataprovider.User{
|
||||||
BaseUser: sdk.BaseUser{
|
BaseUser: sdk.BaseUser{
|
||||||
HomeDir: os.TempDir(),
|
HomeDir: os.TempDir(),
|
||||||
},
|
},
|
||||||
|
@ -1191,7 +1191,7 @@ func TestSCPParseUploadMessage(t *testing.T) {
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", dataprovider.User{
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", dataprovider.User{
|
||||||
BaseUser: sdk.BaseUser{
|
BaseUser: sdk.BaseUser{
|
||||||
HomeDir: os.TempDir(),
|
HomeDir: os.TempDir(),
|
||||||
},
|
},
|
||||||
|
@ -1230,7 +1230,7 @@ func TestSCPProtocolMessages(t *testing.T) {
|
||||||
WriteError: writeErr,
|
WriteError: writeErr,
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{}),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1291,7 +1291,7 @@ func TestSCPTestDownloadProtocolMessages(t *testing.T) {
|
||||||
WriteError: writeErr,
|
WriteError: writeErr,
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{}),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1365,7 +1365,7 @@ func TestSCPCommandHandleErrors(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{}),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1406,7 +1406,7 @@ func TestSCPErrorsMockFs(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", u),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", u),
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
sshCommand: sshCommand{
|
sshCommand: sshCommand{
|
||||||
|
@ -1448,7 +1448,7 @@ func TestSCPRecursiveDownloadErrors(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
fs := vfs.NewOsFs("123", os.TempDir(), "")
|
fs := vfs.NewOsFs("123", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{
|
||||||
BaseUser: sdk.BaseUser{
|
BaseUser: sdk.BaseUser{
|
||||||
HomeDir: os.TempDir(),
|
HomeDir: os.TempDir(),
|
||||||
},
|
},
|
||||||
|
@ -1496,7 +1496,7 @@ func TestSCPRecursiveUploadErrors(t *testing.T) {
|
||||||
WriteError: writeErr,
|
WriteError: writeErr,
|
||||||
}
|
}
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{}),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1537,7 +1537,7 @@ func TestSCPCreateDirs(t *testing.T) {
|
||||||
fs, err := u.GetFilesystem("123")
|
fs, err := u.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", u),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", u),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1571,7 +1571,7 @@ func TestSCPDownloadFileData(t *testing.T) {
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}}),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", dataprovider.User{BaseUser: sdk.BaseUser{HomeDir: os.TempDir()}}),
|
||||||
channel: &mockSSHChannelReadErr,
|
channel: &mockSSHChannelReadErr,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1623,7 +1623,7 @@ func TestSCPUploadFiledata(t *testing.T) {
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", user),
|
||||||
channel: &mockSSHChannel,
|
channel: &mockSSHChannel,
|
||||||
}
|
}
|
||||||
scpCommand := scpCommand{
|
scpCommand := scpCommand{
|
||||||
|
@ -1714,7 +1714,7 @@ func TestUploadError(t *testing.T) {
|
||||||
}
|
}
|
||||||
fs := vfs.NewOsFs("", os.TempDir(), "")
|
fs := vfs.NewOsFs("", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSCP, "", "", user),
|
||||||
}
|
}
|
||||||
|
|
||||||
testfile := "testfile"
|
testfile := "testfile"
|
||||||
|
@ -1762,7 +1762,7 @@ func TestTransferFailingReader(t *testing.T) {
|
||||||
|
|
||||||
fs := newMockOsFs(nil, nil, true, "", os.TempDir())
|
fs := newMockOsFs(nil, nil, true, "", os.TempDir())
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
|
|
||||||
request := sftp.NewRequest("Open", "afile.txt")
|
request := sftp.NewRequest("Open", "afile.txt")
|
||||||
|
@ -1923,7 +1923,7 @@ func TestRecursiveCopyErrors(t *testing.T) {
|
||||||
fs, err := user.GetFilesystem("123")
|
fs, err := user.GetFilesystem("123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
conn := &Connection{
|
conn := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", user),
|
BaseConnection: common.NewBaseConnection("", common.ProtocolSFTP, "", "", user),
|
||||||
}
|
}
|
||||||
sshCmd := sshCommand{
|
sshCmd := sshCommand{
|
||||||
command: "sftpgo-copy",
|
command: "sftpgo-copy",
|
||||||
|
@ -1974,7 +1974,7 @@ func TestRecoverer(t *testing.T) {
|
||||||
c.AcceptInboundConnection(nil, nil)
|
c.AcceptInboundConnection(nil, nil)
|
||||||
connID := "connectionID"
|
connID := "connectionID"
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, "", dataprovider.User{}),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, "", "", dataprovider.User{}),
|
||||||
}
|
}
|
||||||
c.handleSftpConnection(nil, connection)
|
c.handleSftpConnection(nil, connection)
|
||||||
sshCmd := sshCommand{
|
sshCmd := sshCommand{
|
||||||
|
|
|
@ -437,9 +437,11 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||||
if string(req.Payload[4:]) == "sftp" {
|
if string(req.Payload[4:]) == "sftp" {
|
||||||
ok = true
|
ok = true
|
||||||
connection := Connection{
|
connection := Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, conn.RemoteAddr().String(), user),
|
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, conn.LocalAddr().String(),
|
||||||
|
conn.RemoteAddr().String(), user),
|
||||||
ClientVersion: string(sconn.ClientVersion()),
|
ClientVersion: string(sconn.ClientVersion()),
|
||||||
RemoteAddr: conn.RemoteAddr(),
|
RemoteAddr: conn.RemoteAddr(),
|
||||||
|
LocalAddr: conn.LocalAddr(),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
}
|
}
|
||||||
go c.handleSftpConnection(channel, &connection)
|
go c.handleSftpConnection(channel, &connection)
|
||||||
|
@ -447,9 +449,11 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
||||||
case "exec":
|
case "exec":
|
||||||
// protocol will be set later inside processSSHCommand it could be SSH or SCP
|
// protocol will be set later inside processSSHCommand it could be SSH or SCP
|
||||||
connection := Connection{
|
connection := Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", conn.RemoteAddr().String(), user),
|
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", conn.LocalAddr().String(),
|
||||||
|
conn.RemoteAddr().String(), user),
|
||||||
ClientVersion: string(sconn.ClientVersion()),
|
ClientVersion: string(sconn.ClientVersion()),
|
||||||
RemoteAddr: conn.RemoteAddr(),
|
RemoteAddr: conn.RemoteAddr(),
|
||||||
|
LocalAddr: conn.LocalAddr(),
|
||||||
channel: channel,
|
channel: channel,
|
||||||
}
|
}
|
||||||
ok = processSSHCommand(req.Payload, &connection, c.EnabledSSHCommands)
|
ok = processSSHCommand(req.Payload, &connection, c.EnabledSSHCommands)
|
||||||
|
|
|
@ -753,7 +753,8 @@ func (c *sshCommand) sendExitStatus(err error) {
|
||||||
common.ProtocolSSH, 0, err)
|
common.ProtocolSSH, 0, err)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
logger.CommandLog(sshCommandLogSender, cmdPath, targetPath, c.connection.User.Username, "", c.connection.ID,
|
logger.CommandLog(sshCommandLogSender, cmdPath, targetPath, c.connection.User.Username, "", c.connection.ID,
|
||||||
common.ProtocolSSH, -1, -1, "", "", c.connection.command, -1, c.connection.GetRemoteAddress())
|
common.ProtocolSSH, -1, -1, "", "", c.connection.command, -1, c.connection.GetLocalAddress(),
|
||||||
|
c.connection.GetRemoteAddress())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,10 @@ func ServeSubSystemConnection(user *dataprovider.User, connectionID string, read
|
||||||
dataprovider.UpdateLastLogin(user) //nolint:errcheck
|
dataprovider.UpdateLastLogin(user) //nolint:errcheck
|
||||||
|
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connectionID, common.ProtocolSFTP, "", *user),
|
BaseConnection: common.NewBaseConnection(connectionID, common.ProtocolSFTP, "", "", *user),
|
||||||
ClientVersion: "",
|
ClientVersion: "",
|
||||||
RemoteAddr: &net.IPAddr{},
|
RemoteAddr: &net.IPAddr{},
|
||||||
|
LocalAddr: &net.IPAddr{},
|
||||||
channel: newSubsystemChannel(reader, writer),
|
channel: newSubsystemChannel(reader, writer),
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
|
13
util/util.go
13
util/util.go
|
@ -563,6 +563,19 @@ func GetRealIP(r *http.Request) string {
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHTTPLocalAddress returns the local address for an http.Request
|
||||||
|
// or empty if it cannot be determined
|
||||||
|
func GetHTTPLocalAddress(r *http.Request) string {
|
||||||
|
if r == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
localAddr, ok := r.Context().Value(http.LocalAddrContextKey).(net.Addr)
|
||||||
|
if ok {
|
||||||
|
return localAddr.String()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// ParseAllowedIPAndRanges returns a list of functions that allow to find if a
|
// ParseAllowedIPAndRanges returns a list of functions that allow to find if a
|
||||||
func ParseAllowedIPAndRanges(allowed []string) ([]func(net.IP) bool, error) {
|
func ParseAllowedIPAndRanges(allowed []string) ([]func(net.IP) bool, error) {
|
||||||
res := make([]func(net.IP) bool, len(allowed))
|
res := make([]func(net.IP) bool, len(allowed))
|
||||||
|
|
|
@ -31,7 +31,12 @@ func (c *Connection) GetClientVersion() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRemoteAddress return the connected client's address
|
// GetLocalAddress returns local connection address
|
||||||
|
func (c *Connection) GetLocalAddress() string {
|
||||||
|
return util.GetHTTPLocalAddress(c.request)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRemoteAddress returns the connected client's address
|
||||||
func (c *Connection) GetRemoteAddress() string {
|
func (c *Connection) GetRemoteAddress() string {
|
||||||
if c.request != nil {
|
if c.request != nil {
|
||||||
return c.request.RemoteAddr
|
return c.request.RemoteAddr
|
||||||
|
|
|
@ -335,7 +335,7 @@ func TestOrderDirsToRemove(t *testing.T) {
|
||||||
user := dataprovider.User{}
|
user := dataprovider.User{}
|
||||||
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
request: nil,
|
request: nil,
|
||||||
}
|
}
|
||||||
dirsToRemove := []objectMapping{}
|
dirsToRemove := []objectMapping{}
|
||||||
|
@ -503,7 +503,7 @@ func TestResolvePathErrors(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := connection.Mkdir(ctx, "", os.ModePerm)
|
err := connection.Mkdir(ctx, "", os.ModePerm)
|
||||||
|
@ -574,7 +574,7 @@ func TestFileAccessErrors(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
missingPath := "missing path"
|
missingPath := "missing path"
|
||||||
fsMissingPath := filepath.Join(user.HomeDir, missingPath)
|
fsMissingPath := filepath.Join(user.HomeDir, missingPath)
|
||||||
|
@ -637,7 +637,7 @@ func TestRemoveDirTree(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
|
|
||||||
vpath := path.Join("adir", "missing")
|
vpath := path.Join("adir", "missing")
|
||||||
|
@ -690,7 +690,7 @@ func TestContentType(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
testFilePath := filepath.Join(user.HomeDir, testFile)
|
testFilePath := filepath.Join(user.HomeDir, testFile)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -741,7 +741,7 @@ func TestTransferReadWriteErrors(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
testFilePath := filepath.Join(user.HomeDir, testFile)
|
testFilePath := filepath.Join(user.HomeDir, testFile)
|
||||||
baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
|
baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
|
||||||
|
@ -836,7 +836,7 @@ func TestTransferSeek(t *testing.T) {
|
||||||
user.Permissions["/"] = []string{dataprovider.PermAny}
|
user.Permissions["/"] = []string{dataprovider.PermAny}
|
||||||
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
fs := vfs.NewOsFs("connID", user.HomeDir, "")
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
testFilePath := filepath.Join(user.HomeDir, testFile)
|
testFilePath := filepath.Join(user.HomeDir, testFile)
|
||||||
testFileContents := []byte("content")
|
testFileContents := []byte("content")
|
||||||
|
|
|
@ -201,7 +201,8 @@ func (s *webDavServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx = context.WithValue(ctx, requestStartKey, time.Now())
|
ctx = context.WithValue(ctx, requestStartKey, time.Now())
|
||||||
|
|
||||||
connection := &Connection{
|
connection := &Connection{
|
||||||
BaseConnection: common.NewBaseConnection(connectionID, common.ProtocolWebDAV, r.RemoteAddr, user),
|
BaseConnection: common.NewBaseConnection(connectionID, common.ProtocolWebDAV, util.GetHTTPLocalAddress(r),
|
||||||
|
r.RemoteAddr, user),
|
||||||
request: r,
|
request: r,
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ func TestMaxConnections(t *testing.T) {
|
||||||
// now add a fake connection
|
// now add a fake connection
|
||||||
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
||||||
connection := &webdavd.Connection{
|
connection := &webdavd.Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
assert.Error(t, checkBasicFunc(client))
|
assert.Error(t, checkBasicFunc(client))
|
||||||
|
@ -1085,7 +1085,7 @@ func TestMaxSessions(t *testing.T) {
|
||||||
// now add a fake connection
|
// now add a fake connection
|
||||||
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
fs := vfs.NewOsFs("id", os.TempDir(), "")
|
||||||
connection := &webdavd.Connection{
|
connection := &webdavd.Connection{
|
||||||
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", user),
|
BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
|
||||||
}
|
}
|
||||||
common.Connections.Add(connection)
|
common.Connections.Add(connection)
|
||||||
assert.Error(t, checkBasicFunc(client))
|
assert.Error(t, checkBasicFunc(client))
|
||||||
|
|
Loading…
Reference in a new issue