@@ -10,7 +10,6 @@ import (
10
10
"io"
11
11
"io/fs"
12
12
"os"
13
- "path/filepath"
14
13
"regexp"
15
14
"strings"
16
15
@@ -53,7 +52,8 @@ type ProcessClassifier interface {
53
52
type FilesystemClassifier interface {
54
53
prometheus.Collector
55
54
56
- MatchesFilesystemFile (filePath string ) (* Classification , error )
55
+ MatchesFile (filePath string ) (* Classification , error )
56
+ GetFileSignatures () []* Signature
57
57
}
58
58
59
59
func NewCommandlineClassifier (name string , level Level , allowList []string , blockList []string ) (* CommandlineClassifier , error ) {
@@ -252,8 +252,8 @@ func (sigcl *SignatureMatchClassifier) Matches(executable string, cmdline []stri
252
252
return sigNoMatch , nil
253
253
}
254
254
255
- // MatchesFilesystemFile checks if a filesystem file matches any filesystem signatures
256
- func (sigcl * SignatureMatchClassifier ) MatchesFilesystemFile (filePath string ) (c * Classification , err error ) {
255
+ // MatchesFile checks if a filesystem file matches any filesystem signatures
256
+ func (sigcl * SignatureMatchClassifier ) MatchesFile (filePath string ) (c * Classification , err error ) {
257
257
// Only check signatures with DomainFileSystem
258
258
filesystemSignatures := make ([]* Signature , 0 )
259
259
for _ , sig := range sigcl .Signatures {
@@ -266,28 +266,10 @@ func (sigcl *SignatureMatchClassifier) MatchesFilesystemFile(filePath string) (c
266
266
return sigNoMatch , nil
267
267
}
268
268
269
- // Check filename matching first (cheapest check)
270
- filename := filepath .Base (filePath )
271
- matchingSignatures := make ([]* Signature , 0 )
272
-
273
- for _ , sig := range filesystemSignatures {
274
- if len (sig .Filename ) == 0 {
275
- // No filename restriction, include all signatures
276
- matchingSignatures = append (matchingSignatures , sig )
277
- } else {
278
- // Check if filename matches any of the signature filenames
279
- for _ , sigFilename := range sig .Filename {
280
- if matched , _ := filepath .Match (sigFilename , filename ); matched {
281
- matchingSignatures = append (matchingSignatures , sig )
282
- break
283
- }
284
- }
285
- }
286
- }
287
-
288
- if len (matchingSignatures ) == 0 {
289
- return sigNoMatch , nil
290
- }
269
+ // Skip filename matching - the filesystem detector already filtered files
270
+ // based on signature filename patterns, so any file that reaches here
271
+ // should be checked for content matching against all filesystem signatures
272
+ matchingSignatures := filesystemSignatures
291
273
292
274
// Open file for signature matching
293
275
r , err := os .Open (filePath )
@@ -356,6 +338,17 @@ func (sigcl *SignatureMatchClassifier) Collect(m chan<- prometheus.Metric) {
356
338
sigcl .filesystemMissTotal .Collect (m )
357
339
}
358
340
341
+ // GetFileSignatures returns signatures that are configured for filesystem domain
342
+ func (sigcl * SignatureMatchClassifier ) GetFileSignatures () []* Signature {
343
+ var filesystemSignatures []* Signature
344
+ for _ , sig := range sigcl .Signatures {
345
+ if sig .Domain == DomainFileSystem {
346
+ filesystemSignatures = append (filesystemSignatures , sig )
347
+ }
348
+ }
349
+ return filesystemSignatures
350
+ }
351
+
359
352
// CompositeClassifier combines multiple classifiers into one. The first match wins.
360
353
type CompositeClassifier []ProcessClassifier
361
354
@@ -514,6 +507,14 @@ func (cl *CountingMetricsClassifier) Matches(executable string, cmdline []string
514
507
return cl .D .Matches (executable , cmdline )
515
508
}
516
509
510
+ func (cl * CountingMetricsClassifier ) MatchesFile (filePath string ) (* Classification , error ) {
511
+ cl .callCount .Inc ()
512
+ if fsc , ok := cl .D .(FilesystemClassifier ); ok {
513
+ return fsc .MatchesFile (filePath )
514
+ }
515
+ return sigNoMatch , nil
516
+ }
517
+
517
518
func (cl * CountingMetricsClassifier ) Describe (d chan <- * prometheus.Desc ) {
518
519
cl .callCount .Describe (d )
519
520
cl .D .Describe (d )
@@ -523,3 +524,99 @@ func (cl *CountingMetricsClassifier) Collect(m chan<- prometheus.Metric) {
523
524
cl .callCount .Collect (m )
524
525
cl .D .Collect (m )
525
526
}
527
+
528
+ func (cl * CountingMetricsClassifier ) GetFileSignatures () []* Signature {
529
+ if fsc , ok := cl .D .(FilesystemClassifier ); ok {
530
+ return fsc .GetFileSignatures ()
531
+ }
532
+ return nil
533
+ }
534
+
535
+ func (cl GradedClassifier ) MatchesFile (filePath string ) (* Classification , error ) {
536
+ order := []Level {LevelVery , LevelBarely , LevelAudit }
537
+
538
+ var (
539
+ c * Classification
540
+ err error
541
+ )
542
+ for _ , level := range order {
543
+ classifier , exists := cl [level ]
544
+ if ! exists {
545
+ continue
546
+ }
547
+
548
+ if fsc , ok := classifier .(FilesystemClassifier ); ok {
549
+ c , err = fsc .MatchesFile (filePath )
550
+ if err != nil {
551
+ return nil , err
552
+ }
553
+ if c .Level != LevelNoMatch {
554
+ break
555
+ }
556
+ }
557
+ }
558
+
559
+ if c == nil || c .Level == LevelNoMatch {
560
+ return sigNoMatch , nil
561
+ }
562
+
563
+ res := * c
564
+ res .Classifier = ClassifierGraded + "." + res .Classifier
565
+ return & res , nil
566
+ }
567
+
568
+ func (cl GradedClassifier ) GetFileSignatures () []* Signature {
569
+ var allSignatures []* Signature
570
+
571
+ for _ , classifier := range cl {
572
+ if fsc , ok := classifier .(FilesystemClassifier ); ok {
573
+ signatures := fsc .GetFileSignatures ()
574
+ allSignatures = append (allSignatures , signatures ... )
575
+ }
576
+ }
577
+
578
+ return allSignatures
579
+ }
580
+
581
+ func (cl CompositeClassifier ) MatchesFile (filePath string ) (* Classification , error ) {
582
+ var (
583
+ c * Classification
584
+ err error
585
+ )
586
+ for _ , classifier := range cl {
587
+ if fsc , ok := classifier .(FilesystemClassifier ); ok {
588
+ c , err = fsc .MatchesFile (filePath )
589
+ if err != nil {
590
+ return nil , err
591
+ }
592
+ if c .Level != LevelNoMatch {
593
+ break
594
+ }
595
+ }
596
+ }
597
+
598
+ if c == nil || len (cl ) == 0 {
599
+ // empty composite classifier
600
+ return sigNoMatch , nil
601
+ }
602
+ if c .Level == LevelNoMatch {
603
+ return sigNoMatch , nil
604
+ }
605
+
606
+ res := * c
607
+ res .Classifier = ClassifierComposite + "." + res .Classifier
608
+ return & res , nil
609
+ }
610
+
611
+ func (cl CompositeClassifier ) GetFileSignatures () []* Signature {
612
+ var allSignatures []* Signature
613
+
614
+ for _ , classifier := range cl {
615
+ if fsc , ok := classifier .(FilesystemClassifier ); ok {
616
+ signatures := fsc .GetFileSignatures ()
617
+ allSignatures = append (allSignatures , signatures ... )
618
+ }
619
+ }
620
+
621
+ return allSignatures
622
+ }
0 commit comments