2022-01-21 02:14:16 +00:00
|
|
|
package output
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2023-01-19 17:58:50 +00:00
|
|
|
"sort"
|
2022-01-21 02:14:16 +00:00
|
|
|
"strings"
|
2023-08-02 18:38:10 +00:00
|
|
|
"sync"
|
2022-01-21 02:14:16 +00:00
|
|
|
|
|
|
|
"github.com/fatih/color"
|
2023-01-19 17:58:50 +00:00
|
|
|
"golang.org/x/text/cases"
|
|
|
|
"golang.org/x/text/language"
|
2022-10-06 18:55:07 +00:00
|
|
|
|
2023-07-31 18:12:08 +00:00
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
2022-02-10 18:54:33 +00:00
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb"
|
2022-01-21 02:14:16 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2024-04-23 21:29:38 +00:00
|
|
|
yellowPrinter = color.New(color.FgYellow)
|
|
|
|
greenPrinter = color.New(color.FgHiGreen)
|
|
|
|
boldGreenPrinter = color.New(color.Bold, color.FgHiGreen)
|
|
|
|
whitePrinter = color.New(color.FgWhite)
|
|
|
|
boldWhitePrinter = color.New(color.Bold, color.FgWhite)
|
2022-01-21 02:14:16 +00:00
|
|
|
)
|
|
|
|
|
2023-07-31 18:12:08 +00:00
|
|
|
// PlainPrinter is a printer that prints results in plain text format.
|
2023-08-02 18:38:10 +00:00
|
|
|
type PlainPrinter struct{ mu sync.Mutex }
|
2023-07-31 18:12:08 +00:00
|
|
|
|
|
|
|
func (p *PlainPrinter) Print(_ context.Context, r *detectors.ResultWithMetadata) error {
|
2022-01-21 02:14:16 +00:00
|
|
|
out := outputFormat{
|
2024-01-29 16:57:28 +00:00
|
|
|
DetectorType: r.Result.DetectorType.String(),
|
|
|
|
DecoderType: r.Result.DecoderType.String(),
|
|
|
|
Verified: r.Result.Verified,
|
|
|
|
VerificationError: r.Result.VerificationError(),
|
|
|
|
MetaData: r.SourceMetadata,
|
|
|
|
Raw: strings.TrimSpace(string(r.Result.Raw)),
|
2022-01-21 02:14:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
meta, err := structToMap(out.MetaData.Data)
|
|
|
|
if err != nil {
|
2023-02-14 23:00:07 +00:00
|
|
|
return fmt.Errorf("could not marshal result: %w", err)
|
2022-01-21 02:14:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
printer := greenPrinter
|
2023-08-02 18:38:10 +00:00
|
|
|
p.mu.Lock()
|
|
|
|
defer p.mu.Unlock()
|
2022-01-21 02:14:16 +00:00
|
|
|
|
|
|
|
if out.Verified {
|
2024-01-29 16:57:28 +00:00
|
|
|
boldGreenPrinter.Print("✅ Found verified result 🐷🔑\n")
|
2022-01-21 02:14:16 +00:00
|
|
|
} else {
|
|
|
|
printer = whitePrinter
|
2024-01-29 16:57:28 +00:00
|
|
|
boldWhitePrinter.Print("Found unverified result 🐷🔑❓\n")
|
2024-04-23 21:29:38 +00:00
|
|
|
if out.VerificationError != nil {
|
|
|
|
yellowPrinter.Printf("Verification issue: %s\n", out.VerificationError)
|
|
|
|
}
|
2022-01-21 02:14:16 +00:00
|
|
|
}
|
|
|
|
printer.Printf("Detector Type: %s\n", out.DetectorType)
|
2022-10-06 18:55:07 +00:00
|
|
|
printer.Printf("Decoder Type: %s\n", out.DecoderType)
|
2022-01-24 21:48:52 +00:00
|
|
|
printer.Printf("Raw result: %s\n", whitePrinter.Sprint(out.Raw))
|
2023-01-19 17:58:50 +00:00
|
|
|
|
2023-05-16 15:14:42 +00:00
|
|
|
for k, v := range r.Result.ExtraData {
|
|
|
|
printer.Printf(
|
|
|
|
"%s: %v\n",
|
|
|
|
cases.Title(language.AmericanEnglish).String(k),
|
|
|
|
v)
|
|
|
|
}
|
|
|
|
|
2023-05-18 21:42:19 +00:00
|
|
|
if r.Result.StructuredData != nil {
|
|
|
|
for idx, v := range r.Result.StructuredData.GithubSshKey {
|
|
|
|
printer.Printf("GithubSshKey %d User: %s\n", idx, v.User)
|
2023-05-16 15:14:42 +00:00
|
|
|
|
2023-05-18 21:42:19 +00:00
|
|
|
if v.PublicKeyFingerprint != "" {
|
|
|
|
printer.Printf("GithubSshKey %d Fingerprint: %s\n", idx, v.PublicKeyFingerprint)
|
|
|
|
}
|
2023-05-16 15:14:42 +00:00
|
|
|
}
|
|
|
|
|
2023-05-18 21:42:19 +00:00
|
|
|
for idx, v := range r.Result.StructuredData.TlsPrivateKey {
|
|
|
|
printer.Printf("TlsPrivateKey %d Fingerprint: %s\n", idx, v.CertificateFingerprint)
|
|
|
|
printer.Printf("TlsPrivateKey %d Verification URL: %s\n", idx, v.VerificationUrl)
|
|
|
|
printer.Printf("TlsPrivateKey %d Expiration: %d\n", idx, v.ExpirationTimestamp)
|
|
|
|
}
|
2023-05-16 15:14:42 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 11:35:15 +00:00
|
|
|
aggregateData := make(map[string]any)
|
2023-01-19 17:58:50 +00:00
|
|
|
var aggregateDataKeys []string
|
|
|
|
|
2022-01-21 02:14:16 +00:00
|
|
|
for _, data := range meta {
|
|
|
|
for k, v := range data {
|
2023-01-19 17:58:50 +00:00
|
|
|
aggregateDataKeys = append(aggregateDataKeys, k)
|
|
|
|
aggregateData[k] = v
|
2022-01-21 02:14:16 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-19 17:58:50 +00:00
|
|
|
sort.Strings(aggregateDataKeys)
|
|
|
|
for _, k := range aggregateDataKeys {
|
|
|
|
printer.Printf("%s: %v\n", cases.Title(language.AmericanEnglish).String(k), aggregateData[k])
|
|
|
|
}
|
2022-01-21 02:14:16 +00:00
|
|
|
fmt.Println("")
|
2023-02-14 23:00:07 +00:00
|
|
|
return nil
|
2022-01-21 02:14:16 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 11:35:15 +00:00
|
|
|
func structToMap(obj any) (m map[string]map[string]any, err error) {
|
2022-01-21 02:14:16 +00:00
|
|
|
data, err := json.Marshal(obj)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(data, &m)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
type outputFormat struct {
|
2022-10-06 18:55:07 +00:00
|
|
|
DetectorType,
|
|
|
|
DecoderType string
|
2024-01-29 16:57:28 +00:00
|
|
|
Verified bool
|
|
|
|
VerificationError error
|
|
|
|
Raw string
|
2022-01-21 02:14:16 +00:00
|
|
|
*source_metadatapb.MetaData
|
|
|
|
}
|