Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configuration parsing and custom detectors to engine #968

Merged
merged 2 commits into from Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions main.go
Expand Up @@ -19,6 +19,7 @@ import (
"gopkg.in/alecthomas/kingpin.v2"

"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/config"
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
"github.com/trufflesecurity/trufflehog/v3/pkg/decoders"
"github.com/trufflesecurity/trufflehog/v3/pkg/engine"
Expand All @@ -41,6 +42,7 @@ var (
noVerification = cli.Flag("no-verification", "Don't verify the results.").Bool()
onlyVerified = cli.Flag("only-verified", "Only output verified results.").Bool()
filterUnverified = cli.Flag("filter-unverified", "Only output first unverified result per chunk per detector if there are more than one results.").Bool()
configFilename = cli.Flag("config", "Path to configuration file.").String()
// rules = cli.Flag("rules", "Path to file with custom rules.").String()
printAvgDetectorTime = cli.Flag("print-avg-detector-time", "Print the average time spent on each detector.").Bool()
noUpdate = cli.Flag("no-update", "Don't check for updates.").Bool()
Expand Down Expand Up @@ -181,10 +183,17 @@ func run(state overseer.State) {

defer func() { _ = sync() }()

conf, err := config.Read(*configFilename)
if err != nil {
logger.Error(err, "error parsing the provided configuration file")
os.Exit(1)
}

e := engine.Start(ctx,
engine.WithConcurrency(*concurrency),
engine.WithDecoders(decoders.DefaultDecoders()...),
engine.WithDetectors(!*noVerification, engine.DefaultDetectors()...),
engine.WithDetectors(!*noVerification, conf.Detectors...),
engine.WithFilterUnverified(*filterUnverified),
)

Expand Down
48 changes: 48 additions & 0 deletions pkg/config/config.go
@@ -0,0 +1,48 @@
package config

import (
"os"

"github.com/trufflesecurity/trufflehog/v3/pkg/custom_detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/custom_detectorspb"
"github.com/trufflesecurity/trufflehog/v3/pkg/protoyaml"
)

// Config holds user supplied configuration.
type Config struct {
Detectors []detectors.Detector
}

// Read parses a given filename into a Config.
func Read(filename string) (*Config, error) {
if filename == "" {
return &Config{}, nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: I feel like this should return an error instead of an empty config. Because an empty filename string would occur anytime --config is included but nothing follows it, yeah? (At least I think it would?) Which seems like an accident we should tell the user about, rather than intentionally adding an empty config.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.. that's a good point. I'll have to see if there's a way to differentiate between --config '' and no flag, because currently I think they both return "".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found there's an ExistingFile() method in kingpin which will do the job. Now --config '' will error and no flag will not.

}
input, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
return NewYAML(input)
}

// NewYAML parses the given YAML data into a Config.
func NewYAML(input []byte) (*Config, error) {
// Parse the raw YAML into a structure.
var messages custom_detectorspb.CustomDetectors
if err := protoyaml.UnmarshalStrict(input, &messages); err != nil {
return nil, err
}
// Convert the structured YAML into detectors.
var detectors []detectors.Detector
for _, detectorConfig := range messages.Detectors {
detector, err := custom_detectors.NewWebhookCustomRegex(detectorConfig)
if err != nil {
return nil, err
}
detectors = append(detectors, detector)
}
return &Config{
Detectors: detectors,
}, nil
}