github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/cmd/gosbom/cli/eventloop/tasks.go (about) 1 package eventloop 2 3 import ( 4 "crypto" 5 "fmt" 6 7 "github.com/nextlinux/gosbom/gosbom" 8 "github.com/nextlinux/gosbom/gosbom/artifact" 9 "github.com/nextlinux/gosbom/gosbom/file" 10 "github.com/nextlinux/gosbom/gosbom/file/cataloger/filecontent" 11 "github.com/nextlinux/gosbom/gosbom/file/cataloger/filedigest" 12 "github.com/nextlinux/gosbom/gosbom/file/cataloger/filemetadata" 13 "github.com/nextlinux/gosbom/gosbom/file/cataloger/secrets" 14 "github.com/nextlinux/gosbom/gosbom/sbom" 15 "github.com/nextlinux/gosbom/gosbom/source" 16 "github.com/nextlinux/gosbom/internal/config" 17 ) 18 19 type Task func(*sbom.Artifacts, *source.Source) ([]artifact.Relationship, error) 20 21 func Tasks(app *config.Application) ([]Task, error) { 22 var tasks []Task 23 24 generators := []func(app *config.Application) (Task, error){ 25 generateCatalogPackagesTask, 26 generateCatalogFileMetadataTask, 27 generateCatalogFileDigestsTask, 28 generateCatalogSecretsTask, 29 generateCatalogContentsTask, 30 } 31 32 for _, generator := range generators { 33 task, err := generator(app) 34 if err != nil { 35 return nil, err 36 } 37 38 if task != nil { 39 tasks = append(tasks, task) 40 } 41 } 42 43 return tasks, nil 44 } 45 46 func generateCatalogPackagesTask(app *config.Application) (Task, error) { 47 if !app.Package.Cataloger.Enabled { 48 return nil, nil 49 } 50 51 task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) { 52 packageCatalog, relationships, theDistro, err := gosbom.CatalogPackages(src, app.ToCatalogerConfig()) 53 54 results.Packages = packageCatalog 55 results.LinuxDistribution = theDistro 56 57 return relationships, err 58 } 59 60 return task, nil 61 } 62 63 func generateCatalogFileMetadataTask(app *config.Application) (Task, error) { 64 if !app.FileMetadata.Cataloger.Enabled { 65 return nil, nil 66 } 67 68 metadataCataloger := filemetadata.NewCataloger() 69 70 task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) { 71 resolver, err := src.FileResolver(app.FileMetadata.Cataloger.ScopeOpt) 72 if err != nil { 73 return nil, err 74 } 75 76 result, err := metadataCataloger.Catalog(resolver) 77 if err != nil { 78 return nil, err 79 } 80 results.FileMetadata = result 81 return nil, nil 82 } 83 84 return task, nil 85 } 86 87 func generateCatalogFileDigestsTask(app *config.Application) (Task, error) { 88 if !app.FileMetadata.Cataloger.Enabled { 89 return nil, nil 90 } 91 92 supportedHashAlgorithms := make(map[string]crypto.Hash) 93 for _, h := range []crypto.Hash{ 94 crypto.MD5, 95 crypto.SHA1, 96 crypto.SHA256, 97 } { 98 supportedHashAlgorithms[file.DigestAlgorithmName(h)] = h 99 } 100 101 var hashes []crypto.Hash 102 for _, hashStr := range app.FileMetadata.Digests { 103 name := file.CleanDigestAlgorithmName(hashStr) 104 hashObj, ok := supportedHashAlgorithms[name] 105 if !ok { 106 return nil, fmt.Errorf("unsupported hash algorithm: %s", hashStr) 107 } 108 hashes = append(hashes, hashObj) 109 } 110 111 digestsCataloger := filedigest.NewCataloger(hashes) 112 113 task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) { 114 resolver, err := src.FileResolver(app.FileMetadata.Cataloger.ScopeOpt) 115 if err != nil { 116 return nil, err 117 } 118 119 result, err := digestsCataloger.Catalog(resolver) 120 if err != nil { 121 return nil, err 122 } 123 results.FileDigests = result 124 return nil, nil 125 } 126 127 return task, nil 128 } 129 130 func generateCatalogSecretsTask(app *config.Application) (Task, error) { 131 if !app.Secrets.Cataloger.Enabled { 132 return nil, nil 133 } 134 135 patterns, err := secrets.GenerateSearchPatterns(secrets.DefaultSecretsPatterns, app.Secrets.AdditionalPatterns, app.Secrets.ExcludePatternNames) 136 if err != nil { 137 return nil, err 138 } 139 140 secretsCataloger, err := secrets.NewCataloger(patterns, app.Secrets.RevealValues, app.Secrets.SkipFilesAboveSize) //nolint:staticcheck 141 if err != nil { 142 return nil, err 143 } 144 145 task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) { 146 resolver, err := src.FileResolver(app.Secrets.Cataloger.ScopeOpt) 147 if err != nil { 148 return nil, err 149 } 150 151 result, err := secretsCataloger.Catalog(resolver) 152 if err != nil { 153 return nil, err 154 } 155 results.Secrets = result 156 return nil, nil 157 } 158 159 return task, nil 160 } 161 162 func generateCatalogContentsTask(app *config.Application) (Task, error) { 163 if !app.FileContents.Cataloger.Enabled { 164 return nil, nil 165 } 166 167 contentsCataloger, err := filecontent.NewCataloger(app.FileContents.Globs, app.FileContents.SkipFilesAboveSize) //nolint:staticcheck 168 if err != nil { 169 return nil, err 170 } 171 172 task := func(results *sbom.Artifacts, src *source.Source) ([]artifact.Relationship, error) { 173 resolver, err := src.FileResolver(app.FileContents.Cataloger.ScopeOpt) 174 if err != nil { 175 return nil, err 176 } 177 178 result, err := contentsCataloger.Catalog(resolver) 179 if err != nil { 180 return nil, err 181 } 182 results.FileContents = result 183 return nil, nil 184 } 185 186 return task, nil 187 } 188 189 func RunTask(t Task, a *sbom.Artifacts, src *source.Source, c chan<- artifact.Relationship, errs chan<- error) { 190 defer close(c) 191 192 relationships, err := t(a, src) 193 if err != nil { 194 errs <- err 195 return 196 } 197 198 for _, relationship := range relationships { 199 c <- relationship 200 } 201 }