github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/secrets/convert/specific.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package convert 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/google/osv-scalibr/extractor/filesystem" 22 "github.com/google/osv-scalibr/inventory" 23 "github.com/google/osv-scalibr/plugin" 24 "github.com/google/osv-scalibr/veles" 25 ) 26 27 // FromVelesDetectorWithRequire works similar to FromVelesDetector but allows specifying additional files to look at on top of the default ones. 28 func FromVelesDetectorWithRequire(velesDetector veles.Detector, name string, version int, fileRequired func(filesystem.FileAPI) bool) filesystem.Extractor { 29 return &detectorWithRequire{ 30 velesDetector: velesDetector, 31 name: name, 32 version: version, 33 fileRequired: fileRequired, 34 } 35 } 36 37 // extractorKeeper signals that a Detector also functions as a standalone filesystem.Extractor. 38 type extractorKeeper interface { 39 KeepExtractor() bool 40 } 41 42 // Assert that detectorWithRequire implements the required interfaces. 43 var _ veles.Detector = &detectorWithRequire{} 44 var _ filesystem.Extractor = &detectorWithRequire{} 45 var _ extractorKeeper = &detectorWithRequire{} 46 47 // detectorWithRequire is a wrapper around the veles.Detector interface that 48 // implements the additional functions of the filesystem Extractor interface. 49 type detectorWithRequire struct { 50 velesDetector veles.Detector 51 name string 52 version int 53 fileRequired func(filesystem.FileAPI) bool 54 e *veles.DetectionEngine 55 } 56 57 // KeepExtractor signals that this detector must also be registered as a standalone 58 // filesystem.Extractor to handle the additional files specified in the fileRequired callback. 59 func (d *detectorWithRequire) KeepExtractor() bool { return true } 60 61 // MaxSecretLen returns the maximum length a secret from this Detector can have. 62 func (d *detectorWithRequire) MaxSecretLen() uint32 { 63 return d.velesDetector.MaxSecretLen() 64 } 65 66 // Detect finds candidate secrets in the data and returns them alongside their 67 // starting positions. 68 func (d *detectorWithRequire) Detect(data []byte) ([]veles.Secret, []int) { 69 return d.velesDetector.Detect(data) 70 } 71 72 // Name of the secret extractor. 73 func (d *detectorWithRequire) Name() string { 74 return d.name 75 } 76 77 // Version of the secret extractor. 78 func (d *detectorWithRequire) Version() int { 79 return d.version 80 } 81 82 // Requirements of the secret extractor. 83 func (d *detectorWithRequire) Requirements() *plugin.Capabilities { 84 // Veles plugins don't have any special requirements. 85 return &plugin.Capabilities{} 86 } 87 88 // FileRequired returns the provided file required callback. 89 func (d *detectorWithRequire) FileRequired(api filesystem.FileAPI) bool { 90 return d.fileRequired(api) 91 } 92 93 // Extract extracts secret from the filesystem using the provided detector. 94 func (d *detectorWithRequire) Extract(ctx context.Context, input *filesystem.ScanInput) (inventory.Inventory, error) { 95 if d.e == nil { 96 var err error 97 d.e, err = veles.NewDetectionEngine([]veles.Detector{d.velesDetector}) 98 if err != nil { 99 return inventory.Inventory{}, err 100 } 101 } 102 secrets, err := d.e.Detect(ctx, input.Reader) 103 if err != nil { 104 return inventory.Inventory{}, fmt.Errorf("unable to scan for secrets: %w", err) 105 } 106 i := inventory.Inventory{} 107 for _, s := range secrets { 108 i.Secrets = append(i.Secrets, &inventory.Secret{ 109 Secret: s, 110 Location: input.Path, 111 }) 112 } 113 return i, nil 114 }