Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
K
koko
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
koko
Commits
c5f287bb
Commit
c5f287bb
authored
Jun 10, 2019
by
Eric
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] add ftp audit log
parent
2c841304
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
219 additions
and
29 deletions
+219
-29
sftp.go
pkg/handler/sftp.go
+85
-18
sftpvolume.go
pkg/httpd/sftpvolume.go
+134
-11
No files found.
pkg/handler/sftp.go
View file @
c5f287bb
...
...
@@ -3,6 +3,7 @@ package handler
import
(
"fmt"
"io"
"net"
"os"
"strings"
"sync"
...
...
@@ -24,8 +25,8 @@ import (
func
SftpHandler
(
sess
ssh
.
Session
)
{
ctx
,
cancel
:=
cctx
.
NewContext
(
sess
)
defer
cancel
()
handler
:=
&
sftpHandler
{
user
:
ctx
.
User
()}
host
,
_
,
_
:=
net
.
SplitHostPort
(
sess
.
RemoteAddr
()
.
String
())
handler
:=
&
sftpHandler
{
user
:
ctx
.
User
()
,
addr
:
host
}
handler
.
initial
()
handlers
:=
sftp
.
Handlers
{
FileGet
:
handler
,
...
...
@@ -37,14 +38,7 @@ func SftpHandler(sess ssh.Session) {
req
:=
sftp
.
NewRequestServer
(
sess
,
handlers
)
if
err
:=
req
.
Serve
();
err
==
io
.
EOF
{
_
=
req
.
Close
()
hosts
:=
handler
.
hosts
for
hostname
,
dir
:=
range
hosts
{
for
name
,
d
:=
range
dir
.
suMaps
{
srvconn
.
RecycleClient
(
d
.
conn
)
delete
(
dir
.
suMaps
,
name
)
}
delete
(
hosts
,
hostname
)
}
handler
.
Close
()
logger
.
Info
(
"sftp client exited session."
)
}
else
if
err
!=
nil
{
logger
.
Error
(
"sftp server completed with error:"
,
err
)
...
...
@@ -53,6 +47,7 @@ func SftpHandler(sess ssh.Session) {
type
sftpHandler
struct
{
user
*
model
.
User
addr
string
assets
model
.
AssetList
rootPath
string
// tmp || home || ~
hosts
map
[
string
]
*
HostNameDir
...
...
@@ -152,7 +147,7 @@ func (fs *sftpHandler) Filelist(r *sftp.Request) (sftp.ListerAt, error) {
return
fileInfos
,
err
}
func
(
fs
*
sftpHandler
)
Filecmd
(
r
*
sftp
.
Request
)
error
{
func
(
fs
*
sftpHandler
)
Filecmd
(
r
*
sftp
.
Request
)
(
err
error
)
{
logger
.
Debug
(
"File cmd: "
,
r
.
Filepath
)
pathNames
:=
strings
.
Split
(
strings
.
TrimPrefix
(
r
.
Filepath
,
"/"
),
"/"
)
if
len
(
pathNames
)
<=
2
{
...
...
@@ -169,23 +164,42 @@ func (fs *sftpHandler) Filecmd(r *sftp.Request) error {
suDir
.
conn
=
conn
}
realPathName
:=
suDir
.
ParsePath
(
r
.
Filepath
)
logData
:=
&
model
.
FTPLog
{
User
:
fs
.
user
.
Username
,
Hostname
:
hostDir
.
asset
.
Hostname
,
OrgID
:
hostDir
.
asset
.
OrgID
,
SystemUser
:
suDir
.
systemUser
.
Name
,
RemoteAddr
:
fs
.
addr
,
Operate
:
r
.
Method
,
Path
:
realPathName
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
fs
.
CreateFTPLog
(
logData
)
switch
r
.
Method
{
case
"Setstat"
:
return
nil
return
case
"Rename"
:
realNewName
:=
suDir
.
ParsePath
(
r
.
Target
)
return
suDir
.
client
.
Rename
(
realPathName
,
realNewName
)
logData
.
Path
=
fmt
.
Sprintf
(
"%s=>%s"
,
realPathName
,
realNewName
)
err
=
suDir
.
client
.
Rename
(
realPathName
,
realNewName
)
case
"Rmdir"
:
return
suDir
.
client
.
RemoveDirectory
(
realPathName
)
err
=
suDir
.
client
.
RemoveDirectory
(
realPathName
)
case
"Remove"
:
return
suDir
.
client
.
Remove
(
realPathName
)
err
=
suDir
.
client
.
Remove
(
realPathName
)
case
"Mkdir"
:
return
suDir
.
client
.
MkdirAll
(
realPathName
)
err
=
suDir
.
client
.
MkdirAll
(
realPathName
)
case
"Symlink"
:
realNewName
:=
suDir
.
ParsePath
(
r
.
Target
)
return
suDir
.
client
.
Symlink
(
realPathName
,
realNewName
)
logData
.
Path
=
fmt
.
Sprintf
(
"%s=>%s"
,
realPathName
,
realNewName
)
err
=
suDir
.
client
.
Symlink
(
realPathName
,
realNewName
)
default
:
return
}
if
err
==
nil
{
logData
.
IsSuccess
=
true
}
return
nil
return
}
func
(
fs
*
sftpHandler
)
Filewrite
(
r
*
sftp
.
Request
)
(
io
.
WriterAt
,
error
)
{
...
...
@@ -205,7 +219,22 @@ func (fs *sftpHandler) Filewrite(r *sftp.Request) (io.WriterAt, error) {
suDir
.
conn
=
conn
}
realPathName
:=
suDir
.
ParsePath
(
r
.
Filepath
)
logData
:=
&
model
.
FTPLog
{
User
:
fs
.
user
.
Username
,
Hostname
:
hostDir
.
asset
.
Hostname
,
OrgID
:
hostDir
.
asset
.
OrgID
,
SystemUser
:
suDir
.
systemUser
.
Name
,
RemoteAddr
:
fs
.
addr
,
Operate
:
"Upload"
,
Path
:
realPathName
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
fs
.
CreateFTPLog
(
logData
)
f
,
err
:=
suDir
.
client
.
Create
(
realPathName
)
if
err
==
nil
{
logData
.
IsSuccess
=
true
}
return
NewWriterAt
(
f
),
err
}
...
...
@@ -226,10 +255,23 @@ func (fs *sftpHandler) Fileread(r *sftp.Request) (io.ReaderAt, error) {
suDir
.
conn
=
client
}
realPathName
:=
suDir
.
ParsePath
(
r
.
Filepath
)
logData
:=
&
model
.
FTPLog
{
User
:
fs
.
user
.
Username
,
Hostname
:
hostDir
.
asset
.
Hostname
,
OrgID
:
hostDir
.
asset
.
OrgID
,
SystemUser
:
suDir
.
systemUser
.
Name
,
RemoteAddr
:
fs
.
addr
,
Operate
:
"Download"
,
Path
:
realPathName
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
fs
.
CreateFTPLog
(
logData
)
f
,
err
:=
suDir
.
client
.
Open
(
realPathName
)
if
err
!=
nil
{
return
nil
,
err
}
logData
.
IsSuccess
=
true
return
NewReaderAt
(
f
),
err
}
...
...
@@ -245,6 +287,31 @@ func (fs *sftpHandler) GetSftpClient(asset *model.Asset, sysUser *model.SystemUs
return
sftpClient
,
sshClient
,
nil
}
func
(
fs
*
sftpHandler
)
CreateFTPLog
(
data
*
model
.
FTPLog
)
{
for
i
:=
0
;
i
<
4
;
i
++
{
err
:=
service
.
PushFTPLog
(
data
)
if
err
==
nil
{
break
}
logger
.
Debugf
(
"create FTP log err: %s"
,
err
.
Error
())
time
.
Sleep
(
500
*
time
.
Millisecond
)
}
}
func
(
fs
*
sftpHandler
)
Close
()
{
for
_
,
dir
:=
range
fs
.
hosts
{
if
dir
.
suMaps
==
nil
{
continue
}
for
_
,
d
:=
range
dir
.
suMaps
{
if
d
.
client
!=
nil
{
_
=
d
.
client
.
Close
()
srvconn
.
RecycleClient
(
d
.
conn
)
}
}
}
}
type
HostNameDir
struct
{
rootPath
string
hostname
string
...
...
pkg/httpd/sftpvolume.go
View file @
c5f287bb
...
...
@@ -28,6 +28,7 @@ func NewUserVolume(user *model.User, addr string) *UserVolume {
rawID
:=
fmt
.
Sprintf
(
"'%s@%s"
,
user
.
Username
,
addr
)
uVolume
:=
&
UserVolume
{
Uuid
:
elfinder
.
GenerateID
(
rawID
),
Addr
:
addr
,
user
:
user
,
Name
:
defaultHomeName
,
basePath
:
fmt
.
Sprintf
(
"/%s"
,
defaultHomeName
),
...
...
@@ -38,6 +39,7 @@ func NewUserVolume(user *model.User, addr string) *UserVolume {
type
UserVolume
struct
{
Uuid
string
Addr
string
Name
string
basePath
string
user
*
model
.
User
...
...
@@ -269,7 +271,24 @@ func (u *UserVolume) GetFile(path string) (reader io.ReadCloser, err error) {
sysUserVol
.
conn
=
conn
}
return
sysUserVol
.
client
.
Open
(
realPath
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Download"
,
Path
:
realPath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
reader
,
err
=
sysUserVol
.
client
.
Open
(
realPath
)
if
err
!=
nil
{
return
}
logData
.
IsSuccess
=
true
return
}
func
(
u
*
UserVolume
)
UploadFile
(
dir
,
filename
string
,
reader
io
.
Reader
)
(
elfinder
.
FileDir
,
error
)
{
...
...
@@ -324,10 +343,24 @@ func (u *UserVolume) UploadFile(dir, filename string, reader io.Reader) (elfinde
return
rest
,
err
}
defer
fd
.
Close
()
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Upload"
,
Path
:
realFilenamePath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
_
,
err
=
io
.
Copy
(
fd
,
reader
)
if
err
!=
nil
{
return
rest
,
err
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
filepath
.
Join
(
dir
,
filename
))
}
...
...
@@ -394,11 +427,24 @@ func (u *UserVolume) MergeChunk(cid, total int, dirPath, filename string) (elfin
}
filenamePath
:=
filepath
.
Join
(
realDirPath
,
filename
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Upload"
,
Path
:
filenamePath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
fd
,
err
:=
sysUserVol
.
client
.
OpenFile
(
filenamePath
,
os
.
O_WRONLY
|
os
.
O_APPEND
|
os
.
O_CREATE
|
os
.
O_TRUNC
)
if
err
!=
nil
{
return
rest
,
err
}
defer
fd
.
Close
()
for
i
:=
0
;
i
<=
total
;
i
++
{
partPath
:=
fmt
.
Sprintf
(
"%s.%d_%d.part_%d"
,
filepath
.
Join
(
u
.
localTmpPath
,
dirPath
,
filename
),
i
,
total
,
cid
)
...
...
@@ -414,9 +460,9 @@ func (u *UserVolume) MergeChunk(cid, total int, dirPath, filename string) (elfin
return
rest
,
os
.
ErrNotExist
}
_
=
partFD
.
Close
()
err
=
os
.
Remove
(
partPath
)
_
=
os
.
Remove
(
partPath
)
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
filepath
.
Join
(
dirPath
,
filename
))
}
...
...
@@ -476,9 +522,22 @@ func (u *UserVolume) MakeDir(dir, newDirname string) (elfinder.FileDir, error) {
}
realDirPath
:=
filepath
.
Join
(
realPath
,
newDirname
)
err
:=
sysUserVol
.
client
.
MkdirAll
(
realDirPath
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Mkdir"
,
Path
:
realDirPath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
if
err
!=
nil
{
return
rest
,
err
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
filepath
.
Join
(
dir
,
newDirname
))
}
...
...
@@ -527,14 +586,26 @@ func (u *UserVolume) MakeFile(dir, newFilename string) (elfinder.FileDir, error)
}
realFilePath
:=
filepath
.
Join
(
realPath
,
newFilename
)
_
,
err
:=
sysUserVol
.
client
.
Create
(
realFilePath
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Append"
,
Path
:
realFilePath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
if
err
!=
nil
{
return
rest
,
err
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
filepath
.
Join
(
dir
,
newFilename
))
}
func
(
u
*
UserVolume
)
Rename
(
oldNamePath
,
new
n
ame
string
)
(
elfinder
.
FileDir
,
error
)
{
func
(
u
*
UserVolume
)
Rename
(
oldNamePath
,
new
N
ame
string
)
(
elfinder
.
FileDir
,
error
)
{
var
rest
elfinder
.
FileDir
pathNames
:=
strings
.
Split
(
strings
.
TrimPrefix
(
oldNamePath
,
"/"
),
"/"
)
hostVol
,
ok
:=
u
.
hosts
[
pathNames
[
1
]]
...
...
@@ -573,12 +644,25 @@ func (u *UserVolume) Rename(oldNamePath, newname string) (elfinder.FileDir, erro
}
dirpath
:=
filepath
.
Dir
(
realPath
)
newFilePath
:=
filepath
.
Join
(
dirpath
,
new
n
ame
)
newFilePath
:=
filepath
.
Join
(
dirpath
,
new
N
ame
)
err
:=
sysUserVol
.
client
.
Rename
(
oldNamePath
,
newFilePath
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Rename"
,
Path
:
fmt
.
Sprintf
(
"%s=>%s"
,
oldNamePath
,
newFilePath
),
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
if
err
!=
nil
{
return
rest
,
err
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
newFilePath
)
}
...
...
@@ -624,7 +708,23 @@ func (u *UserVolume) Remove(path string) error {
sysUserVol
.
conn
=
conn
}
return
sysUserVol
.
client
.
Remove
(
realPath
)
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Delete"
,
Path
:
realPath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
err
:=
sysUserVol
.
client
.
Remove
(
realPath
)
if
err
==
nil
{
logData
.
IsSuccess
=
true
}
return
err
}
func
(
u
*
UserVolume
)
Paste
(
dir
,
filename
,
suffix
string
,
reader
io
.
ReadCloser
)
(
elfinder
.
FileDir
,
error
)
{
...
...
@@ -672,9 +772,21 @@ func (u *UserVolume) Paste(dir, filename, suffix string, reader io.ReadCloser) (
realFilePath
:=
filepath
.
Join
(
realPath
,
filename
)
_
,
err
:=
sysUserVol
.
client
.
Stat
(
realFilePath
)
if
err
==
nil
{
realPath
+=
suffix
}
if
err
!=
nil
{
realFilePath
+=
suffix
}
logData
:=
&
model
.
FTPLog
{
User
:
u
.
user
.
Username
,
Hostname
:
hostVol
.
asset
.
Hostname
,
OrgID
:
hostVol
.
asset
.
OrgID
,
SystemUser
:
sysUserVol
.
systemUser
.
Name
,
RemoteAddr
:
u
.
Addr
,
Operate
:
"Append"
,
Path
:
realFilePath
,
DataStart
:
time
.
Now
()
.
UTC
()
.
Format
(
"2006-01-02 15:04:05 +0000"
),
IsSuccess
:
false
,
}
defer
u
.
CreateFTPLog
(
logData
)
fd
,
err
:=
sysUserVol
.
client
.
OpenFile
(
realPath
,
os
.
O_RDWR
|
os
.
O_CREATE
)
if
err
!=
nil
{
return
rest
,
err
...
...
@@ -684,6 +796,7 @@ func (u *UserVolume) Paste(dir, filename, suffix string, reader io.ReadCloser) (
if
err
!=
nil
{
return
rest
,
err
}
logData
.
IsSuccess
=
true
return
u
.
Info
(
realPath
)
}
...
...
@@ -722,6 +835,17 @@ func (u *UserVolume) Close() {
}
}
func
(
u
*
UserVolume
)
CreateFTPLog
(
data
*
model
.
FTPLog
)
{
for
i
:=
0
;
i
<
4
;
i
++
{
err
:=
service
.
PushFTPLog
(
data
)
if
err
==
nil
{
break
}
logger
.
Debugf
(
"create FTP log err: %s"
,
err
.
Error
())
time
.
Sleep
(
500
*
time
.
Millisecond
)
}
}
type
hostnameVolume
struct
{
VID
string
homePath
string
...
...
@@ -775,7 +899,6 @@ func (su *sysUserVolume) ParsePath(path string) string {
func
(
su
*
sysUserVolume
)
Close
()
{
if
su
.
client
!=
nil
{
_
=
su
.
client
.
Close
()
su
.
client
=
nil
}
srvconn
.
RecycleClient
(
su
.
conn
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment