Skip to content

Commit

Permalink
capture ExtendedAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
poolpOrg committed Oct 9, 2024
1 parent 2d1079a commit 029c82c
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 43 deletions.
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ require (
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
github.com/denisbrodbeck/machineid v1.0.1
github.com/dustin/go-humanize v1.0.1
github.com/emersion/go-imap v1.2.1
github.com/gabriel-vasile/mimetype v1.4.2
github.com/gobwas/glob v0.2.3
github.com/google/uuid v1.6.0
Expand All @@ -17,8 +16,8 @@ require (
github.com/mattn/go-sqlite3 v1.14.17
github.com/minio/minio-go/v7 v7.0.61
github.com/pierrec/lz4/v4 v4.1.18
github.com/pkg/xattr v0.4.10
github.com/pmezard/go-difflib v1.0.0
github.com/poolpOrg/go-agentbuilder v0.0.0-20240608155005-a8f77b2e95e5
github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4
github.com/syndtr/goleveldb v1.0.0
github.com/vmihailenco/msgpack/v5 v5.3.5
Expand All @@ -28,12 +27,10 @@ require (
golang.org/x/mod v0.21.0
golang.org/x/term v0.23.0
golang.org/x/tools v0.24.0
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.16.7 // indirect
Expand All @@ -49,5 +46,6 @@ require (
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect
)
16 changes: 3 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA=
github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY=
github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead h1:fI1Jck0vUrXT8bnphprS1EoVRe2Q5CKCX8iDlpqjQ/Y=
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
Expand Down Expand Up @@ -69,10 +62,10 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA=
github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/poolpOrg/go-agentbuilder v0.0.0-20240608155005-a8f77b2e95e5 h1:fsrlgpzo91NF/XyVkHb9DN8lT3nxMWcYgaiQDuiOiWk=
github.com/poolpOrg/go-agentbuilder v0.0.0-20240608155005-a8f77b2e95e5/go.mod h1:BxSQ7A1lCcaYfRw5u9iEeb97h2fw7lYji8qACYUxzm0=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 h1:PT+ElG/UUFMfqy5HrxJxNzj3QBOf7dZwupeVC+mG1Lo=
Expand Down Expand Up @@ -107,21 +100,18 @@ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
Expand Down
49 changes: 47 additions & 2 deletions snapshot/importer/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/PlakarLabs/plakar/objects"
"github.com/PlakarLabs/plakar/snapshot/importer"
"github.com/pkg/xattr"
)

type FSImporter struct {
Expand All @@ -38,6 +39,27 @@ func init() {
importer.Register("fs", NewFSImporter)
}

func getExtendedAttributes(path string) (map[string]string, error) {
attrs := make(map[string]string)

// Get the list of attribute names
attributes, err := xattr.List(path)
if err != nil {
return nil, fmt.Errorf("failed to list extended attributes for %s: %w", path, err)
}

// Iterate over each attribute and retrieve its value
for _, attr := range attributes {
value, err := xattr.Get(path, attr)
if err != nil {
return nil, fmt.Errorf("failed to get value for attribute %s: %w", attr, err)
}
attrs[attr] = string(value)
}

return attrs, nil
}

func NewFSImporter(location string) (importer.ImporterBackend, error) {
if strings.HasPrefix(location, "fs://") {
location = location[4:]
Expand Down Expand Up @@ -80,8 +102,31 @@ func (p *FSImporter) Scan() (<-chan importer.ScanResult, error) {
return nil
}

var recordType importer.RecordType
switch mode := info.Mode(); {
case mode.IsRegular():
recordType = importer.RecordTypeFile
case mode.IsDir():
recordType = importer.RecordTypeDir
case mode&os.ModeSymlink != 0:
recordType = importer.RecordTypeSymlink
case mode&os.ModeDevice != 0:
recordType = importer.RecordTypeDevice
case mode&os.ModeNamedPipe != 0:
recordType = importer.RecordTypePipe
case mode&os.ModeSocket != 0:
recordType = importer.RecordTypeSocket
default:
recordType = importer.RecordTypeFile // Default to file if type is unknown
}

extendedAttributes, err := getExtendedAttributes(path)
if err != nil {
c <- importer.ScanError{Pathname: path, Err: err}
}

fileinfo := objects.FileInfoFromStat(info)
c <- importer.ScanRecord{Pathname: filepath.ToSlash(path), Stat: fileinfo}
c <- importer.ScanRecord{Type: recordType, Pathname: filepath.ToSlash(path), Stat: fileinfo, ExtendedAttributes: extendedAttributes}

if !fileinfo.Mode().IsDir() && !fileinfo.Mode().IsRegular() {
lstat, err := os.Lstat(path)
Expand All @@ -97,7 +142,7 @@ func (p *FSImporter) Scan() (<-chan importer.ScanResult, error) {
c <- importer.ScanError{Pathname: path, Err: err}
return nil
}
c <- importer.ScanLink{Pathname: filepath.ToSlash(path), Target: originFile, Stat: lfileinfo}
c <- importer.ScanRecord{Type: recordType, Pathname: filepath.ToSlash(path), Target: originFile, Stat: lfileinfo, ExtendedAttributes: extendedAttributes}
}
}
return nil
Expand Down
6 changes: 3 additions & 3 deletions snapshot/importer/ftp/ftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (p *FTPImporter) createParentNodes(dirPath string, c chan importer.ScanResu
0,
1,
)
c <- importer.ScanRecord{Pathname: currentPath, Stat: dirInfo}
c <- importer.ScanRecord{Type: importer.RecordTypeDir, Pathname: currentPath, Stat: dirInfo}
}

return nil
Expand All @@ -153,14 +153,14 @@ func (p *FTPImporter) scanDirectory(dirPath string, c chan importer.ScanResult)

if entry.IsDir() {
// Directory: Scan it recursively
c <- importer.ScanRecord{Pathname: entryPath, Stat: fileInfo}
c <- importer.ScanRecord{Type: importer.RecordTypeDir, Pathname: entryPath, Stat: fileInfo}
err := p.scanDirectory(entryPath, c)
if err != nil {
return err
}
} else {
// File: Send file information
c <- importer.ScanRecord{Pathname: entryPath, Stat: fileInfo}
c <- importer.ScanRecord{Type: importer.RecordTypeFile, Pathname: entryPath, Stat: fileInfo}
}
}
return nil
Expand Down
35 changes: 25 additions & 10 deletions snapshot/importer/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,35 @@ type ScanResult interface {
scanResult()
}

type ScanRecord struct {
Pathname string
Stat objects.FileInfo
}
type RecordType int8

const (
RecordTypeFile RecordType = 0
RecordTypeDir RecordType = 1
RecordTypeSymlink RecordType = 2
RecordTypeDevice RecordType = 3
RecordTypePipe RecordType = 4
RecordTypeSocket RecordType = 5
)

func (r ScanRecord) scanResult() {}
type FileAttributes struct {
IsHidden bool // Hidden file attribute (Windows, Linux)
IsSystem bool // System file attribute (Windows)
IsReadonly bool // Read-only attribute
IsArchive bool // Archive attribute (Windows)
IsTemporary bool // Temporary file (Windows)
}

type ScanLink struct {
Pathname string
Target string
Stat objects.FileInfo
type ScanRecord struct {
Type RecordType
Pathname string
Target string
Stat objects.FileInfo
ExtendedAttributes map[string]string
FileAttributes []string
}

func (r ScanLink) scanResult() {}
func (r ScanRecord) scanResult() {}

type ScanError struct {
Pathname string
Expand Down
4 changes: 2 additions & 2 deletions snapshot/importer/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ func (p *S3Importer) Scan() (<-chan importer.ScanResult, error) {
})

for _, directory := range directoryNames {
c <- importer.ScanRecord{Pathname: directory, Stat: directories[directory]}
c <- importer.ScanRecord{Type: importer.RecordTypeDir, Pathname: directory, Stat: directories[directory]}
}
for _, filename := range fileNames {
c <- importer.ScanRecord{Pathname: filename, Stat: files[filename]}
c <- importer.ScanRecord{Type: importer.RecordTypeFile, Pathname: filename, Stat: files[filename]}
}
close(c)
}()
Expand Down
20 changes: 11 additions & 9 deletions snapshot/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ func (snapshot *Snapshot) skipExcludedPathname(options *PushOptions, record impo
switch record := record.(type) {
case importer.ScanError:
pathname = record.Pathname
case importer.ScanLink:
pathname = record.Pathname
case importer.ScanRecord:
pathname = record.Pathname
}
Expand Down Expand Up @@ -298,14 +296,18 @@ func (snapshot *Snapshot) Push(scanDir string, options *PushOptions) error {
switch record := record.(type) {
case importer.ScanError:
logger.Warn("%s: %s", record.Pathname, record.Err)
case importer.ScanLink:
err := snapshot.Filesystem.RecordLink(record.Pathname, record.Target, record.Stat)
if err != nil {
logger.Warn("%s: %s", record.Pathname, err)
return err
}
linkCount++

case importer.ScanRecord:
if record.Type == importer.RecordTypeSymlink {
err := snapshot.Filesystem.RecordLink(record.Pathname, record.Target, record.Stat)
if err != nil {
logger.Warn("%s: %s", record.Pathname, err)
return err
}
linkCount++
continue
}

//
extension := strings.ToLower(filepath.Ext(record.Pathname))
if extension == "" {
Expand Down

0 comments on commit 029c82c

Please sign in to comment.