Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into use-bubbletea
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Goodman <[email protected]>
  • Loading branch information
wagoodman committed Jul 5, 2023
2 parents bf86c7a + cfbb9f7 commit c4fdd10
Show file tree
Hide file tree
Showing 21 changed files with 301 additions and 125 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
go.work.sum
go.work

go.work.sum
/bin
/.bin
CHANGELOG.md
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GOLANGCILINT_VERSION := v1.53.3
GOSIMPORTS_VERSION := v0.3.8
BOUNCER_VERSION := v0.4.0
CHRONICLE_VERSION := v0.6.0
GORELEASER_VERSION := v1.19.0
GORELEASER_VERSION := v1.19.1
YAJSV_VERSION := v1.4.1
COSIGN_VERSION := v2.1.1
QUILL_VERSION := v0.2.0
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ The chocolatey distribution of syft is community maintained and not distributed
choco install syft -y
```

### Scoop

```powershell
scoop install syft
```

### Homebrew
```bash
brew install syft
Expand Down Expand Up @@ -599,7 +605,7 @@ file-metadata:
# SYFT_FILE_METADATA_CATALOGER_SCOPE env var
scope: "squashed"

# the file digest algorithms to use when cataloging files (options: "sha256", "md5", "sha1")
# the file digest algorithms to use when cataloging files (options: "md5", "sha1", "sha224", "sha256", "sha384", "sha512")
# SYFT_FILE_METADATA_DIGESTS env var
digests: ["sha256"]

Expand Down Expand Up @@ -637,11 +643,27 @@ secrets:
# SYFT_SECRETS_EXCLUDE_PATTERN_NAMES env var
exclude-pattern-names: []

# options that apply to all scan sources
source:
# alias name for the source
# SYFT_SOURCE_NAME env var; --source-name flag
name: ""

# alias version for the source
# SYFT_SOURCE_VERSION env var; --source-version flag
version: ""

# options affecting the file source type
file:
# the file digest algorithms to use on the scanned file (options: "md5", "sha1", "sha224", "sha256", "sha384", "sha512")
digests: ["sha256"]

# options when pulling directly from a registry via the "registry:" scheme
registry:
# skip TLS verification when communicating with the registry
# SYFT_REGISTRY_INSECURE_SKIP_TLS_VERIFY env var
insecure-skip-tls-verify: false

# use http instead of https when connecting to the registry
# SYFT_REGISTRY_INSECURE_USE_HTTP env var
insecure-use-http: false
Expand Down
12 changes: 9 additions & 3 deletions cmd/syft/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/anchore/syft/cmd/syft/internal/ui"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/config"
"github.com/anchore/syft/internal/file"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/event"
Expand Down Expand Up @@ -81,18 +82,23 @@ func buildSBOM(app *config.Application, userInput string, errs chan error) (*sbo
}
}

hashers, err := file.Hashers(app.Source.File.Digests...)
if err != nil {
return nil, fmt.Errorf("invalid hash: %w", err)
}

src, err := detection.NewSource(
source.DetectionSourceConfig{
Alias: source.Alias{
Name: app.SourceName,
Version: app.SourceVersion,
Name: app.Source.Name,
Version: app.Source.Version,
},
RegistryOptions: app.Registry.ToOptions(),
Platform: platform,
Exclude: source.ExcludeConfig{
Paths: app.Exclusions,
},
DigestAlgorithms: nil,
DigestAlgorithms: hashers,
},
)

Expand Down
25 changes: 4 additions & 21 deletions cmd/syft/cli/eventloop/tasks.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package eventloop

import (
"crypto"
"fmt"

"github.com/anchore/syft/internal/config"
"github.com/anchore/syft/internal/file"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/file/cataloger/filecontent"
"github.com/anchore/syft/syft/file/cataloger/filedigest"
"github.com/anchore/syft/syft/file/cataloger/filemetadata"
Expand Down Expand Up @@ -89,23 +86,9 @@ func generateCatalogFileDigestsTask(app *config.Application) (Task, error) {
return nil, nil
}

supportedHashAlgorithms := make(map[string]crypto.Hash)
for _, h := range []crypto.Hash{
crypto.MD5,
crypto.SHA1,
crypto.SHA256,
} {
supportedHashAlgorithms[file.DigestAlgorithmName(h)] = h
}

var hashes []crypto.Hash
for _, hashStr := range app.FileMetadata.Digests {
name := file.CleanDigestAlgorithmName(hashStr)
hashObj, ok := supportedHashAlgorithms[name]
if !ok {
return nil, fmt.Errorf("unsupported hash algorithm: %s", hashStr)
}
hashes = append(hashes, hashObj)
hashes, err := file.Hashers(app.FileMetadata.Digests...)
if err != nil {
return nil, err
}

digestsCataloger := filedigest.NewCataloger(hashes)
Expand Down
4 changes: 2 additions & 2 deletions cmd/syft/cli/options/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ func bindPackageConfigOptions(flags *pflag.FlagSet, v *viper.Viper) error {
return err
}

if err := v.BindPFlag("source-name", flags.Lookup("source-name")); err != nil {
if err := v.BindPFlag("source.name", flags.Lookup("source-name")); err != nil {
return err
}

if err := v.BindPFlag("source-version", flags.Lookup("source-version")); err != nil {
if err := v.BindPFlag("source.version", flags.Lookup("source-version")); err != nil {
return err
}

Expand Down
13 changes: 10 additions & 3 deletions cmd/syft/cli/packages/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/config"
"github.com/anchore/syft/internal/file"
"github.com/anchore/syft/internal/version"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/artifact"
Expand Down Expand Up @@ -77,18 +78,24 @@ func execWorker(app *config.Application, userInput string, writer sbom.Writer) <
}
}

hashers, err := file.Hashers(app.Source.File.Digests...)
if err != nil {
errs <- fmt.Errorf("invalid hash: %w", err)
return
}

src, err := detection.NewSource(
source.DetectionSourceConfig{
Alias: source.Alias{
Name: app.SourceName,
Version: app.SourceVersion,
Name: app.Source.Name,
Version: app.Source.Version,
},
RegistryOptions: app.Registry.ToOptions(),
Platform: platform,
Exclude: source.ExcludeConfig{
Paths: app.Exclusions,
},
DigestAlgorithms: nil,
DigestAlgorithms: hashers,
},
)

Expand Down
4 changes: 2 additions & 2 deletions cmd/syft/cli/poweruser/poweruser.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func execWorker(app *config.Application, userInput string, writer sbom.Writer) <
src, err := detection.NewSource(
source.DetectionSourceConfig{
Alias: source.Alias{
Name: app.SourceName,
Version: app.SourceVersion,
Name: app.Source.Name,
Version: app.Source.Version,
},
RegistryOptions: app.Registry.ToOptions(),
Platform: platform,
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ require (
github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5
github.com/wagoodman/jotframe v0.0.0-20211129225309-56b0d0a4aebb
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/mod v0.11.0
golang.org/x/mod v0.12.0
golang.org/x/net v0.11.0
golang.org/x/term v0.9.0
golang.org/x/term v0.10.0
gopkg.in/yaml.v2 v2.4.0
)

Expand Down Expand Up @@ -170,7 +170,7 @@ require (
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -937,17 +937,17 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
7 changes: 3 additions & 4 deletions internal/config/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ type Application struct {
Exclusions []string `yaml:"exclude" json:"exclude" mapstructure:"exclude"`
Platform string `yaml:"platform" json:"platform" mapstructure:"platform"`
Name string `yaml:"name" json:"name" mapstructure:"name"`
SourceName string `yaml:"source-name" json:"source-name" mapstructure:"source-name"`
SourceVersion string `yaml:"source-version" json:"source-version" mapstructure:"source-version"`
Source sourceCfg `yaml:"source" json:"source" mapstructure:"source"`
Parallelism int `yaml:"parallelism" json:"parallelism" mapstructure:"parallelism"` // the number of catalog workers to run in parallel
DefaultImagePullSource string `yaml:"default-image-pull-source" json:"default-image-pull-source" mapstructure:"default-image-pull-source"` // specify default image pull source
}
Expand Down Expand Up @@ -147,8 +146,8 @@ func (cfg *Application) parseConfigValues() error {

if cfg.Name != "" {
log.Warnf("name parameter is deprecated. please use: source-name. name will be removed in a future version")
if cfg.SourceName == "" {
cfg.SourceName = cfg.Name
if cfg.Source.Name == "" {
cfg.Source.Name = cfg.Name
}
}

Expand Down
17 changes: 17 additions & 0 deletions internal/config/source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package config

import "github.com/spf13/viper"

type sourceCfg struct {
Name string `json:"name" yaml:"name" mapstructure:"name"`
Version string `json:"version" yaml:"version" mapstructure:"version"`
File fileSource `json:"file" yaml:"file" mapstructure:"file"`
}

type fileSource struct {
Digests []string `json:"digests" yaml:"digests" mapstructure:"digests"`
}

func (cfg sourceCfg) loadDefaultValues(v *viper.Viper) {
v.SetDefault("source.file.digests", []string{"sha256"})
}
76 changes: 76 additions & 0 deletions internal/file/digest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package file

import (
"crypto"
"fmt"
"hash"
"io"
"strings"

"github.com/anchore/syft/syft/file"
)

func supportedHashAlgorithms() []crypto.Hash {
return []crypto.Hash{
crypto.MD5,
crypto.SHA1,
crypto.SHA224,
crypto.SHA256,
crypto.SHA384,
crypto.SHA512,
}
}

func NewDigestsFromFile(closer io.ReadCloser, hashes []crypto.Hash) ([]file.Digest, error) {
// create a set of hasher objects tied together with a single writer to feed content into
hashers := make([]hash.Hash, len(hashes))
writers := make([]io.Writer, len(hashes))
for idx, hashObj := range hashes {
hashers[idx] = hashObj.New()
writers[idx] = hashers[idx]
}

size, err := io.Copy(io.MultiWriter(writers...), closer)
if err != nil {
return nil, err
}

if size == 0 {
return make([]file.Digest, 0), nil
}

result := make([]file.Digest, len(hashes))
// only capture digests when there is content. It is important to do this based on SIZE and not
// FILE TYPE. The reasoning is that it is possible for a tar to be crafted with a header-only
// file type but a body is still allowed.
for idx, hasher := range hashers {
result[idx] = file.Digest{
Algorithm: CleanDigestAlgorithmName(hashes[idx].String()),
Value: fmt.Sprintf("%+x", hasher.Sum(nil)),
}
}

return result, nil
}

func Hashers(names ...string) ([]crypto.Hash, error) {
hashByName := make(map[string]crypto.Hash)
for _, h := range supportedHashAlgorithms() {
hashByName[CleanDigestAlgorithmName(h.String())] = h
}

var hashers []crypto.Hash
for _, hashStr := range names {
hashObj, ok := hashByName[CleanDigestAlgorithmName(hashStr)]
if !ok {
return nil, fmt.Errorf("unsupported hash algorithm: %s", hashStr)
}
hashers = append(hashers, hashObj)
}
return hashers, nil
}

func CleanDigestAlgorithmName(name string) string {
lower := strings.ToLower(name)
return strings.ReplaceAll(lower, "-", "")
}
Loading

0 comments on commit c4fdd10

Please sign in to comment.