github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/language/java/jar/jar.go (about) 1 package jar 2 3 import ( 4 "context" 5 "io/fs" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "golang.org/x/xerrors" 11 12 dio "github.com/aquasecurity/go-dep-parser/pkg/io" 13 "github.com/aquasecurity/go-dep-parser/pkg/java/jar" 14 "github.com/devseccon/trivy/pkg/fanal/analyzer" 15 "github.com/devseccon/trivy/pkg/fanal/analyzer/language" 16 "github.com/devseccon/trivy/pkg/fanal/types" 17 "github.com/devseccon/trivy/pkg/javadb" 18 "github.com/devseccon/trivy/pkg/parallel" 19 ) 20 21 func init() { 22 analyzer.RegisterPostAnalyzer(analyzer.TypeJar, newJavaLibraryAnalyzer) 23 } 24 25 const version = 1 26 27 var requiredExtensions = []string{ 28 ".jar", 29 ".war", 30 ".ear", 31 ".par", 32 } 33 34 // javaLibraryAnalyzer analyzes jar/war/ear/par files 35 type javaLibraryAnalyzer struct { 36 parallel int 37 } 38 39 func newJavaLibraryAnalyzer(options analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) { 40 return &javaLibraryAnalyzer{ 41 parallel: options.Parallel, 42 }, nil 43 } 44 45 func (a *javaLibraryAnalyzer) PostAnalyze(ctx context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) { 46 // TODO: think about the sonatype API and "--offline" 47 client, err := javadb.NewClient() 48 if err != nil { 49 return nil, xerrors.Errorf("Unable to initialize the Java DB: %s", err) 50 } 51 defer func() { _ = client.Close() }() 52 53 // Skip analyzing JAR files as the nil client means the Java DB was not downloaded successfully. 54 if client == nil { 55 return nil, nil 56 } 57 58 // It will be called on each JAR file 59 onFile := func(path string, info fs.FileInfo, r dio.ReadSeekerAt) (*types.Application, error) { 60 p := jar.NewParser(client, jar.WithSize(info.Size()), jar.WithFilePath(path)) 61 return language.ParsePackage(types.Jar, path, r, p, input.Options.FileChecksum) 62 } 63 64 var apps []types.Application 65 onResult := func(app *types.Application) error { 66 if app == nil { 67 return nil 68 } 69 apps = append(apps, *app) 70 return nil 71 } 72 73 if err = parallel.WalkDir(ctx, input.FS, ".", a.parallel, onFile, onResult); err != nil { 74 return nil, xerrors.Errorf("walk dir error: %w", err) 75 } 76 77 return &analyzer.AnalysisResult{ 78 Applications: apps, 79 }, nil 80 } 81 82 func (a *javaLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool { 83 ext := filepath.Ext(filePath) 84 for _, required := range requiredExtensions { 85 if strings.EqualFold(ext, required) { 86 return true 87 } 88 } 89 return false 90 } 91 92 func (a *javaLibraryAnalyzer) Type() analyzer.Type { 93 return analyzer.TypeJar 94 } 95 96 func (a *javaLibraryAnalyzer) Version() int { 97 return version 98 }