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  }