Skip to content

Commit

Permalink
[v17] emit an audit event with file transfer statistics when an SFTP …
Browse files Browse the repository at this point in the history
…session is completed (#48167)

* 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
  • Loading branch information
capnspacehook authored Oct 30, 2024
1 parent 6a998dd commit bd059df
Show file tree
Hide file tree
Showing 13 changed files with 2,663 additions and 1,971 deletions.
49 changes: 49 additions & 0 deletions api/proto/teleport/legacy/types/events/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -4615,6 +4663,7 @@ message OneOf {
events.UserTaskCreate UserTaskCreate = 188;
events.UserTaskUpdate UserTaskUpdate = 189;
events.UserTaskDelete UserTaskDelete = 190;
events.SFTPSummary SFTPSummary = 191;
}
}

Expand Down
26 changes: 26 additions & 0 deletions api/types/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading

0 comments on commit bd059df

Please sign in to comment.