emit an audit event with file transfer statistics when an SFTP session is completed (#48051)

* emit an audit event with file transfer statistics when an SFTP session is completed

* remove unused SFTP event codes, don't embed os.File

* send oneof events to parent process to make event unmarshaling easier to reason about

* protect tracked files with mutex
This commit is contained in:
Andrew LeFevre
2024-10-30 18:52:20 +00:00
committed by GitHub
parent 6160a3da61
commit 1589413a56
13 changed files with 2226 additions and 1534 deletions
@@ -1892,6 +1892,54 @@ message SFTP {
string Error = 12 [(gogoproto.jsontag) = "error,omitempty"];
}
// SFTPSummary is emitted at the end of an SFTP transfer
message SFTPSummary {
// Metadata is a common event metadata
Metadata Metadata = 1 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// User is a common user event metadata
UserMetadata User = 2 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ConnectionMetadata holds information about the connection
ConnectionMetadata Connection = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// SessionMetadata is a common event session metadata
SessionMetadata Session = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ServerMetadata is a common server metadata
ServerMetadata Server = 5 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// FileTransferStats contains statistics about transferred files
repeated FileTransferStat FileTransferStats = 6 [(gogoproto.jsontag) = "file_transfer_stats"];
}
// FileTransferStat is statistics about a transferred file
message FileTransferStat {
string Path = 1 [(gogoproto.jsontag) = "path"];
uint64 BytesRead = 2 [(gogoproto.jsontag) = "bytes_read"];
uint64 BytesWritten = 3 [(gogoproto.jsontag) = "bytes_written"];
}
// Subsystem is emitted when a user requests a new subsystem.
message Subsystem {
// Metadata is a common event metadata
@@ -4615,6 +4663,7 @@ message OneOf {
events.UserTaskCreate UserTaskCreate = 188;
events.UserTaskUpdate UserTaskUpdate = 189;
events.UserTaskDelete UserTaskDelete = 190;
events.SFTPSummary SFTPSummary = 191;
}
}
+26
View File
@@ -2302,3 +2302,29 @@ func (m *UserTaskUpdate) TrimToMaxSize(_ int) AuditEvent {
func (m *UserTaskDelete) TrimToMaxSize(_ int) AuditEvent {
return m
}
func (m *SFTPSummary) TrimToMaxSize(maxSize int) AuditEvent {
size := m.Size()
if size <= maxSize {
return m
}
out := utils.CloneProtoMsg(m)
var customFieldsCount int
for i := range out.FileTransferStats {
if out.FileTransferStats[i].Path != "" {
customFieldsCount++
out.FileTransferStats[i].Path = ""
}
}
maxSize = adjustedMaxSize(out, maxSize)
maxFieldsSize := maxSizePerField(maxSize, customFieldsCount)
for i := range out.FileTransferStats {
out.FileTransferStats[i].Path = trimStr(out.FileTransferStats[i].Path, maxFieldsSize)
}
return out
}
+2002 -1257
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -761,6 +761,10 @@ func ToOneOf(in AuditEvent) (*OneOf, error) {
out.Event = &OneOf_UserTaskDelete{
UserTaskDelete: e,
}
case *SFTPSummary:
out.Event = &OneOf_SFTPSummary{
SFTPSummary: e,
}
default:
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType())
unknown := &Unknown{}
+2
View File
@@ -285,6 +285,8 @@ const (
// SFTPEvent means a user attempted a file operation
SFTPEvent = "sftp"
SFTPPath = "path"
// SFTPSummaryEvent is emitted at the end of an SFTP transfer.
SFTPSummaryEvent = "sftp_summary"
// ResizeEvent means that some user resized PTY on the client
ResizeEvent = "resize"
+27 -39
View File
@@ -320,45 +320,29 @@ const (
KubernetesClusterDeleteCode = "T3012I"
// The following codes correspond to SFTP file operations.
SFTPOpenCode = "TS001I"
SFTPOpenFailureCode = "TS001E"
SFTPCloseCode = "TS002I"
SFTPCloseFailureCode = "TS002E"
SFTPReadCode = "TS003I"
SFTPReadFailureCode = "TS003E"
SFTPWriteCode = "TS004I"
SFTPWriteFailureCode = "TS004E"
SFTPLstatCode = "TS005I"
SFTPLstatFailureCode = "TS005E"
SFTPFstatCode = "TS006I"
SFTPFstatFailureCode = "TS006E"
SFTPSetstatCode = "TS007I"
SFTPSetstatFailureCode = "TS007E"
SFTPFsetstatCode = "TS008I"
SFTPFsetstatFailureCode = "TS008E"
SFTPOpendirCode = "TS009I"
SFTPOpendirFailureCode = "TS009E"
SFTPReaddirCode = "TS010I"
SFTPReaddirFailureCode = "TS010E"
SFTPRemoveCode = "TS011I"
SFTPRemoveFailureCode = "TS011E"
SFTPMkdirCode = "TS012I"
SFTPMkdirFailureCode = "TS012E"
SFTPRmdirCode = "TS013I"
SFTPRmdirFailureCode = "TS013E"
SFTPRealpathCode = "TS014I"
SFTPRealpathFailureCode = "TS014E"
SFTPStatCode = "TS015I"
SFTPStatFailureCode = "TS015E"
SFTPRenameCode = "TS016I"
SFTPRenameFailureCode = "TS016E"
SFTPReadlinkCode = "TS017I"
SFTPReadlinkFailureCode = "TS017E"
SFTPSymlinkCode = "TS018I"
SFTPSymlinkFailureCode = "TS018E"
SFTPLinkCode = "TS019I"
SFTPLinkFailureCode = "TS019E"
SFTPDisallowedCode = "TS020E"
SFTPOpenCode = "TS001I"
SFTPOpenFailureCode = "TS001E"
SFTPSetstatCode = "TS007I"
SFTPSetstatFailureCode = "TS007E"
SFTPOpendirCode = "TS009I"
SFTPOpendirFailureCode = "TS009E"
SFTPReaddirCode = "TS010I"
SFTPReaddirFailureCode = "TS010E"
SFTPRemoveCode = "TS011I"
SFTPRemoveFailureCode = "TS011E"
SFTPMkdirCode = "TS012I"
SFTPMkdirFailureCode = "TS012E"
SFTPRmdirCode = "TS013I"
SFTPRmdirFailureCode = "TS013E"
SFTPRenameCode = "TS016I"
SFTPRenameFailureCode = "TS016E"
SFTPSymlinkCode = "TS018I"
SFTPSymlinkFailureCode = "TS018E"
SFTPLinkCode = "TS019I"
SFTPLinkFailureCode = "TS019E"
SFTPDisallowedCode = "TS020E"
// SFTPSummaryCode is the SFTP summary code.
SFTPSummaryCode = "TS021I"
// SessionCommandCode is a session command code.
SessionCommandCode = "T4000I"
@@ -674,3 +658,7 @@ const (
// UnknownCode is used when an event of unknown type is encountered.
UnknownCode = apievents.UnknownCode
)
// After defining an event code, make sure to keep
// `web/packages/teleport/src/services/audit/types.ts` in sync and add an
// entry in the `eventsMap` in `lib/events/events_test.go`.
+3
View File
@@ -445,6 +445,9 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) {
e = &events.UserTaskUpdate{}
case UserTaskDeleteEvent:
e = &events.UserTaskDelete{}
case SFTPSummaryEvent:
e = &events.SFTPSummary{}
default:
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", eventType)
unknown := &events.Unknown{}
+1
View File
@@ -235,6 +235,7 @@ var eventsMap = map[string]apievents.AuditEvent{
UserTaskCreateEvent: &apievents.UserTaskCreate{},
UserTaskUpdateEvent: &apievents.UserTaskUpdate{},
UserTaskDeleteEvent: &apievents.UserTaskDelete{},
SFTPSummaryEvent: &apievents.SFTPSummary{},
}
// TestJSON tests JSON marshal events
+23 -8
View File
@@ -189,20 +189,35 @@ func (s *sftpSubsys) Start(ctx context.Context,
return
}
var sftpEvent apievents.SFTP
err = jsonpb.UnmarshalString(eventStr[:len(eventStr)-1], &sftpEvent)
var oneOfEvent apievents.OneOf
err = jsonpb.UnmarshalString(eventStr[:len(eventStr)-1], &oneOfEvent)
if err != nil {
s.log.WithError(err).Warn("Failed to unmarshal SFTP event.")
continue
}
event, err := apievents.FromOneOf(oneOfEvent)
if err != nil {
s.log.WithError(err).Warn("Failed to convert SFTP event from OneOf.")
continue
}
sftpEvent.Metadata.ClusterName = serverCtx.ClusterName
sftpEvent.ServerMetadata = serverMeta
sftpEvent.SessionMetadata = sessionMeta
sftpEvent.UserMetadata = userMeta
sftpEvent.ConnectionMetadata = connectionMeta
event.SetClusterName(serverCtx.ClusterName)
switch e := event.(type) {
case *apievents.SFTP:
e.ServerMetadata = serverMeta
e.SessionMetadata = sessionMeta
e.UserMetadata = userMeta
e.ConnectionMetadata = connectionMeta
case *apievents.SFTPSummary:
e.ServerMetadata = serverMeta
e.SessionMetadata = sessionMeta
e.UserMetadata = userMeta
e.ConnectionMetadata = connectionMeta
default:
s.log.WithError(err).Warnf("Unknown event type received from SFTP server process: %q", event.GetType())
}
if err := serverCtx.GetServer().EmitAuditEvent(ctx, &sftpEvent); err != nil {
if err := serverCtx.GetServer().EmitAuditEvent(ctx, event); err != nil {
log.WithError(err).Warn("Failed to emit SFTP event.")
}
}
+73 -14
View File
@@ -30,6 +30,8 @@ import (
"os/user"
"path"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/gogo/protobuf/jsonpb"
@@ -89,10 +91,37 @@ type allowedOps struct {
type sftpHandler struct {
logger *log.Entry
allowed *allowedOps
events chan<- *apievents.SFTP
// mtx protects files
mtx sync.Mutex
files []*trackedFile
events chan<- apievents.AuditEvent
}
func newSFTPHandler(logger *log.Entry, req *srv.FileTransferRequest, events chan<- *apievents.SFTP) (*sftpHandler, error) {
type trackedFile struct {
file *os.File
bytesRead atomic.Uint64
bytesWritten atomic.Uint64
}
func (t *trackedFile) ReadAt(b []byte, off int64) (int, error) {
n, err := t.file.ReadAt(b, off)
t.bytesRead.Add(uint64(n))
return n, err
}
func (t *trackedFile) WriteAt(b []byte, off int64) (int, error) {
n, err := t.file.WriteAt(b, off)
t.bytesWritten.Add(uint64(n))
return n, err
}
func (t *trackedFile) Close() error {
return t.file.Close()
}
func newSFTPHandler(logger *log.Entry, req *srv.FileTransferRequest, events chan<- apievents.AuditEvent) (*sftpHandler, error) {
var allowed *allowedOps
if req != nil {
allowed = &allowedOps{
@@ -188,7 +217,7 @@ func (s *sftpHandler) Filewrite(req *sftp.Request) (_ io.WriterAt, retErr error)
return s.openFile(req)
}
func (s *sftpHandler) openFile(req *sftp.Request) (*os.File, error) {
func (s *sftpHandler) openFile(req *sftp.Request) (sftp.WriterAtReaderAt, error) {
if err := s.ensureReqIsAllowed(req); err != nil {
return nil, err
}
@@ -220,8 +249,12 @@ func (s *sftpHandler) openFile(req *sftp.Request) (*os.File, error) {
if err != nil {
return nil, err
}
trackFile := &trackedFile{file: f}
s.mtx.Lock()
s.files = append(s.files, trackFile)
s.mtx.Unlock()
return f, nil
return trackFile, nil
}
// Filecmd handles file modification requests.
@@ -607,7 +640,7 @@ func onSFTP() error {
}
ch := compositeCh{io.NopCloser(bufferedReader), chw}
sftpEvents := make(chan *apievents.SFTP, 1)
sftpEvents := make(chan apievents.AuditEvent, 1)
h, err := newSFTPHandler(logger, fileTransferReq, sftpEvents)
if err != nil {
return trace.Wrap(err)
@@ -627,17 +660,24 @@ func onSFTP() error {
var m jsonpb.Marshaler
var buf bytes.Buffer
for event := range sftpEvents {
oneOfEvent, err := apievents.ToOneOf(event)
if err != nil {
logger.WithError(err).Warn("Failed to convert SFTP event to OneOf.")
continue
}
buf.Reset()
if err := m.Marshal(&buf, event); err != nil {
if err := m.Marshal(&buf, oneOfEvent); err != nil {
logger.WithError(err).Warn("Failed to marshal SFTP event.")
} else {
// Append a NULL byte so the parent process will know where
// this event ends
buf.WriteByte(0x0)
_, err = io.Copy(auditFile, &buf)
if err != nil {
logger.WithError(err).Warn("Failed to send SFTP event to parent.")
}
continue
}
// Append a NULL byte so the parent process will know where
// this event ends
buf.WriteByte(0x0)
_, err = io.Copy(auditFile, &buf)
if err != nil {
logger.WithError(err).Warn("Failed to send SFTP event to parent.")
}
}
@@ -651,6 +691,25 @@ func onSFTP() error {
serveErr = trace.Wrap(serveErr)
}
// Send a summary event last
summaryEvent := &apievents.SFTPSummary{
Metadata: apievents.Metadata{
Type: events.SFTPSummaryEvent,
Code: events.SFTPSummaryCode,
Time: time.Now(),
},
}
// We don't need to worry about closing these files, handler will
// take care of that for us
for _, f := range h.files {
summaryEvent.FileTransferStats = append(summaryEvent.FileTransferStats, &apievents.FileTransferStat{
Path: f.file.Name(),
BytesRead: f.bytesRead.Load(),
BytesWritten: f.bytesWritten.Load(),
})
}
sftpEvents <- summaryEvent
// Wait until event marshaling goroutine is finished
close(sftpEvents)
<-done
@@ -50,20 +50,8 @@ const EventIconMap: Record<EventCode, any> = {
[eventCodes.SCP_DISALLOWED]: Icons.FolderPlus,
[eventCodes.SFTP_OPEN_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_OPEN]: Icons.FolderPlus,
[eventCodes.SFTP_CLOSE_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_CLOSE]: Icons.FolderPlus,
[eventCodes.SFTP_READ_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_READ]: Icons.FolderPlus,
[eventCodes.SFTP_WRITE_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_WRITE]: Icons.FolderPlus,
[eventCodes.SFTP_LSTAT_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_LSTAT]: Icons.FolderPlus,
[eventCodes.SFTP_FSTAT_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_FSTAT]: Icons.FolderPlus,
[eventCodes.SFTP_SETSTAT_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_SETSTAT]: Icons.FolderPlus,
[eventCodes.SFTP_FSETSTAT_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_FSETSTAT]: Icons.FolderPlus,
[eventCodes.SFTP_OPENDIR_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_OPENDIR]: Icons.FolderPlus,
[eventCodes.SFTP_READDIR_FAILURE]: Icons.FolderPlus,
@@ -74,14 +62,8 @@ const EventIconMap: Record<EventCode, any> = {
[eventCodes.SFTP_MKDIR]: Icons.FolderPlus,
[eventCodes.SFTP_RMDIR_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_RMDIR]: Icons.FolderPlus,
[eventCodes.SFTP_REALPATH_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_REALPATH]: Icons.FolderPlus,
[eventCodes.SFTP_STAT_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_STAT]: Icons.FolderPlus,
[eventCodes.SFTP_RENAME_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_RENAME]: Icons.FolderPlus,
[eventCodes.SFTP_READLINK_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_READLINK]: Icons.FolderPlus,
[eventCodes.SFTP_SYMLINK_FAILURE]: Icons.FolderPlus,
[eventCodes.SFTP_SYMLINK]: Icons.FolderPlus,
[eventCodes.SFTP_LINK]: Icons.FolderPlus,
@@ -297,6 +279,7 @@ const EventIconMap: Record<EventCode, any> = {
[eventCodes.USER_TASK_CREATE]: Icons.Info,
[eventCodes.USER_TASK_UPDATE]: Icons.Info,
[eventCodes.USER_TASK_DELETE]: Icons.Info,
[eventCodes.SFTP_SUMMARY]: Icons.FolderPlus,
[eventCodes.UNKNOWN]: Icons.Question,
};
@@ -305,86 +305,6 @@ export const formatters: Formatters = {
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_CLOSE]: {
type: 'sftp',
desc: 'SFTP Close',
format: ({ user, path, ...rest }) =>
`User [${user}] closed file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_CLOSE_FAILURE]: {
type: 'sftp',
desc: 'SFTP Close Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to close file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_READ]: {
type: 'sftp',
desc: 'SFTP Read',
format: ({ user, path, ...rest }) =>
`User [${user}] read from file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_READ_FAILURE]: {
type: 'sftp',
desc: 'SFTP Read Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to read from file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_WRITE]: {
type: 'sftp',
desc: 'SFTP Write',
format: ({ user, path, ...rest }) =>
`User [${user}] wrote to file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_WRITE_FAILURE]: {
type: 'sftp',
desc: 'SFTP Write Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to write to file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_LSTAT]: {
type: 'sftp',
desc: 'SFTP Lstat',
format: ({ user, path, ...rest }) =>
`User [${user}] queried attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_LSTAT_FAILURE]: {
type: 'sftp',
desc: 'SFTP Lstat Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to query attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_FSTAT]: {
type: 'sftp',
desc: 'SFTP Fstat',
format: ({ user, path, ...rest }) =>
`User [${user}] queried attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_FSTAT_FAILURE]: {
type: 'sftp',
desc: 'SFTP Fstat Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to query attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_SETSTAT]: {
type: 'sftp',
desc: 'SFTP Setstat',
@@ -401,22 +321,6 @@ export const formatters: Formatters = {
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_FSETSTAT]: {
type: 'sftp',
desc: 'SFTP Fsetstat',
format: ({ user, path, ...rest }) =>
`User [${user}] changed attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_FSETSTAT_FAILURE]: {
type: 'sftp',
desc: 'SFTP Fsetstat Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to change attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_OPENDIR]: {
type: 'sftp',
desc: 'SFTP Opendir',
@@ -497,38 +401,6 @@ export const formatters: Formatters = {
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_REALPATH]: {
type: 'sftp',
desc: 'SFTP Realpath',
format: ({ user, path, ...rest }) =>
`User [${user}] queried absolute path of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_REALPATH_FAILURE]: {
type: 'sftp',
desc: 'SFTP Realpath Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to query absolute path of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_STAT]: {
type: 'sftp',
desc: 'SFTP Stat',
format: ({ user, path, ...rest }) =>
`User [${user}] queried attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_STAT_FAILURE]: {
type: 'sftp',
desc: 'SFTP Stat Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to query attributes of file [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_RENAME]: {
type: 'sftp',
desc: 'SFTP Rename',
@@ -545,22 +417,6 @@ export const formatters: Formatters = {
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_READLINK]: {
type: 'sftp',
desc: 'SFTP Readlink',
format: ({ user, path, ...rest }) =>
`User [${user}] read symbolic link [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]`,
},
[eventCodes.SFTP_READLINK_FAILURE]: {
type: 'sftp',
desc: 'SFTP Readlink Failed',
format: ({ user, path, error, ...rest }) =>
`User [${user}] failed to read symbolic link [${path}] on node [${
rest['server_hostname'] || rest['addr.local']
}]: [${error}]`,
},
[eventCodes.SFTP_SYMLINK]: {
type: 'sftp',
desc: 'SFTP Symlink',
@@ -1971,6 +1827,13 @@ export const formatters: Formatters = {
return `User [${user}] deleted a user task [${name}]`;
},
},
[eventCodes.SFTP_SUMMARY]: {
type: 'sftp_summary',
desc: 'File Transfer Completed',
format: ({ user, server_hostname }) => {
return `User [${user}] completed a file transfer on [${server_hostname}]`;
},
},
[eventCodes.UNKNOWN]: {
type: 'unknown',
desc: 'Unknown Event',
@@ -163,20 +163,8 @@ export const eventCodes = {
SCP_DISALLOWED: 'T3010E',
SFTP_OPEN_FAILURE: 'TS001E',
SFTP_OPEN: 'TS001I',
SFTP_CLOSE_FAILURE: 'TS002E',
SFTP_CLOSE: 'TS002I',
SFTP_READ_FAILURE: 'TS003E',
SFTP_READ: 'TS003I',
SFTP_WRITE_FAILURE: 'TS004E',
SFTP_WRITE: 'TS004I',
SFTP_LSTAT_FAILURE: 'TS005E',
SFTP_LSTAT: 'TS005I',
SFTP_FSTAT_FAILURE: 'TS006E',
SFTP_FSTAT: 'TS006I',
SFTP_SETSTAT_FAILURE: 'TS007E',
SFTP_SETSTAT: 'TS007I',
SFTP_FSETSTAT_FAILURE: 'TS008E',
SFTP_FSETSTAT: 'TS008I',
SFTP_OPENDIR_FAILURE: 'TS009E',
SFTP_OPENDIR: 'TS009I',
SFTP_READDIR_FAILURE: 'TS010E',
@@ -187,19 +175,14 @@ export const eventCodes = {
SFTP_MKDIR: 'TS012I',
SFTP_RMDIR_FAILURE: 'TS013E',
SFTP_RMDIR: 'TS013I',
SFTP_REALPATH_FAILURE: 'TS014E',
SFTP_REALPATH: 'TS014I',
SFTP_STAT_FAILURE: 'TS015E',
SFTP_STAT: 'TS015I',
SFTP_RENAME_FAILURE: 'TS016E',
SFTP_RENAME: 'TS016I',
SFTP_READLINK_FAILURE: 'TS017E',
SFTP_READLINK: 'TS017I',
SFTP_SYMLINK_FAILURE: 'TS018E',
SFTP_SYMLINK: 'TS018I',
SFTP_LINK: 'TS019I',
SFTP_LINK_FAILURE: 'TS019E',
SFTP_DISALLOWED: 'TS020E',
SFTP_SUMMARY: 'TS021I',
SESSION_COMMAND: 'T4000I',
SESSION_DATA: 'T2006I',
SESSION_DISK: 'T4001I',
@@ -457,34 +440,10 @@ export type RawEvents = {
[eventCodes.SFTP_OPEN_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_OPEN_FAILURE
>;
[eventCodes.SFTP_CLOSE]: RawEventSFTP<typeof eventCodes.SFTP_CLOSE>;
[eventCodes.SFTP_CLOSE_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_CLOSE_FAILURE
>;
[eventCodes.SFTP_READ]: RawEventSFTP<typeof eventCodes.SFTP_READ>;
[eventCodes.SFTP_READ_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_READ_FAILURE
>;
[eventCodes.SFTP_WRITE]: RawEventSFTP<typeof eventCodes.SFTP_WRITE>;
[eventCodes.SFTP_WRITE_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_WRITE_FAILURE
>;
[eventCodes.SFTP_LSTAT]: RawEventSFTP<typeof eventCodes.SFTP_LSTAT>;
[eventCodes.SFTP_LSTAT_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_LSTAT_FAILURE
>;
[eventCodes.SFTP_FSTAT]: RawEventSFTP<typeof eventCodes.SFTP_FSTAT>;
[eventCodes.SFTP_FSTAT_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_FSTAT_FAILURE
>;
[eventCodes.SFTP_SETSTAT]: RawEventSFTP<typeof eventCodes.SFTP_SETSTAT>;
[eventCodes.SFTP_SETSTAT_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_SETSTAT_FAILURE
>;
[eventCodes.SFTP_FSETSTAT]: RawEventSFTP<typeof eventCodes.SFTP_FSETSTAT>;
[eventCodes.SFTP_FSETSTAT_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_FSETSTAT_FAILURE
>;
[eventCodes.SFTP_OPENDIR]: RawEventSFTP<typeof eventCodes.SFTP_OPENDIR>;
[eventCodes.SFTP_OPENDIR_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_OPENDIR_FAILURE
@@ -505,22 +464,10 @@ export type RawEvents = {
[eventCodes.SFTP_RMDIR_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_RMDIR_FAILURE
>;
[eventCodes.SFTP_REALPATH]: RawEventSFTP<typeof eventCodes.SFTP_REALPATH>;
[eventCodes.SFTP_REALPATH_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_REALPATH_FAILURE
>;
[eventCodes.SFTP_STAT]: RawEventSFTP<typeof eventCodes.SFTP_STAT>;
[eventCodes.SFTP_STAT_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_STAT_FAILURE
>;
[eventCodes.SFTP_RENAME]: RawEventSFTP<typeof eventCodes.SFTP_RENAME>;
[eventCodes.SFTP_RENAME_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_RENAME_FAILURE
>;
[eventCodes.SFTP_READLINK]: RawEventSFTP<typeof eventCodes.SFTP_READLINK>;
[eventCodes.SFTP_READLINK_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_READLINK_FAILURE
>;
[eventCodes.SFTP_SYMLINK]: RawEventSFTP<typeof eventCodes.SFTP_SYMLINK>;
[eventCodes.SFTP_SYMLINK_FAILURE]: RawEventSFTP<
typeof eventCodes.SFTP_SYMLINK_FAILURE
@@ -1746,6 +1693,13 @@ export type RawEvents = {
typeof eventCodes.USER_TASK_DELETE,
HasName
>;
[eventCodes.SFTP_SUMMARY]: RawEvent<
typeof eventCodes.SFTP_SUMMARY,
{
user: string;
server_hostname: string;
}
>;
};
/**