From b6fafa04a28a35c91b107c7d8d29d4f217fb94ec Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Thu, 16 Nov 2023 13:17:59 +0900 Subject: [PATCH 001/108] test: retry containerd initialization (#5597) Signed-off-by: knqyf263 --- pkg/fanal/test/integration/containerd_test.go | 132 +++++++++--------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/pkg/fanal/test/integration/containerd_test.go b/pkg/fanal/test/integration/containerd_test.go index 45339fd9a347..9ca993ec0627 100644 --- a/pkg/fanal/test/integration/containerd_test.go +++ b/pkg/fanal/test/integration/containerd_test.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -14,7 +15,7 @@ import ( "testing" "time" - "github.com/aquasecurity/trivy/pkg/fanal/analyzer" + "github.com/samber/lo" "github.com/containerd/containerd" "github.com/containerd/containerd/images" @@ -23,9 +24,10 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - testcontainers "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/fanal/applier" "github.com/aquasecurity/trivy/pkg/fanal/artifact" aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" @@ -34,13 +36,12 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/types" ) -func configureTestDataPaths(t *testing.T, namespace string) (string, string) { +func setupContainerd(t *testing.T, ctx context.Context, namespace string) *containerd.Client { t.Helper() - tmpDir, err := os.MkdirTemp("/tmp", "fanal") - require.NoError(t, err) + tmpDir := t.TempDir() containerdDir := filepath.Join(tmpDir, "containerd") - err = os.MkdirAll(containerdDir, os.ModePerm) + err := os.MkdirAll(containerdDir, os.ModePerm) require.NoError(t, err) socketPath := filepath.Join(containerdDir, "containerd.sock") @@ -49,10 +50,29 @@ func configureTestDataPaths(t *testing.T, namespace string) (string, string) { t.Setenv("CONTAINERD_ADDRESS", socketPath) t.Setenv("CONTAINERD_NAMESPACE", namespace) - return tmpDir, socketPath + startContainerd(t, ctx, tmpDir) + + // Retry up to 3 times until containerd is ready + var client *containerd.Client + iteration, _, err := lo.AttemptWhileWithDelay(3, 1*time.Second, func(int, time.Duration) (error, bool) { + client, err = containerd.New(socketPath) + if err != nil { + if !errors.Is(err, os.ErrPermission) { + return err, false // unexpected error + } + return err, true + } + t.Cleanup(func() { + assert.NoError(t, client.Close()) + }) + return nil, false + }) + require.NoErrorf(t, err, "attempted %d times ", iteration) + + return client } -func startContainerd(t *testing.T, ctx context.Context, hostPath string) testcontainers.Container { +func startContainerd(t *testing.T, ctx context.Context, hostPath string) { t.Helper() t.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true") req := testcontainers.ContainerRequest{ @@ -84,18 +104,19 @@ func startContainerd(t *testing.T, ctx context.Context, hostPath string) testcon }) require.NoError(t, err) - return containerdC + t.Cleanup(func() { + assert.NoError(t, containerdC.Terminate(ctx)) + }) } // Each of these tests imports an image and tags it with the name found in the // `imageName` field. Then, the containerd store is searched by the reference // provided in the `searchName` field. func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { - type testInstance struct { - name string - imageName string - searchName string - expectErr bool + // Each architecture needs different images and test cases. + // Currently only amd64 architecture is supported + if runtime.GOARCH != "amd64" { + t.Skip("'Containerd' test only supports amd64 architecture") } digest := "sha256:f12582b2f2190f350e3904462c1c23aaf366b4f76705e97b199f9bbded1d816a" @@ -103,7 +124,12 @@ func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { tag := "world" importedImageOriginalName := "ghcr.io/aquasecurity/trivy-test-images:alpine-310" - tests := []testInstance{ + tests := []struct { + name string + imageName string + searchName string + wantErr bool + }{ { name: "familiarName:tag", imageName: fmt.Sprintf("%s:%s", basename, tag), @@ -128,13 +154,13 @@ func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { name: "other-registry.io/library/name:wrongTag should fail", imageName: fmt.Sprintf("other-registry.io/library/%s:%s", basename, tag), searchName: fmt.Sprintf("other-registry.io/library/%s:badtag", basename), - expectErr: true, + wantErr: true, }, { name: "other-registry.io/library/wrongName:tag should fail", imageName: fmt.Sprintf("other-registry.io/library/%s:%s", basename, tag), searchName: fmt.Sprintf("other-registry.io/library/badname:%s", tag), - expectErr: true, + wantErr: true, }, { name: "digest should succeed", @@ -145,7 +171,7 @@ func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { name: "wrong digest should fail", imageName: "", searchName: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - expectErr: true, + wantErr: true, }, { name: "name@digest", @@ -171,32 +197,19 @@ func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { name: "wrongName@digest should fail", imageName: fmt.Sprintf("%s:%s", basename, tag), searchName: fmt.Sprintf("badname@%s", digest), - expectErr: true, + wantErr: true, }, { name: "compound/wrongName@digest should fail", imageName: fmt.Sprintf("compound/%s:%s", basename, tag), searchName: fmt.Sprintf("compound/badname@%s", digest), - expectErr: true, + wantErr: true, }, } - // Each architecture needs different images and test cases. - // Currently only amd64 architecture is supported - if runtime.GOARCH != "amd64" { - t.Skip("'Containerd' test only supports amd64 architecture") - } namespace := "default" ctx := namespaces.WithNamespace(context.Background(), namespace) - tmpDir, socketPath := configureTestDataPaths(t, namespace) - defer os.RemoveAll(tmpDir) - - containerdC := startContainerd(t, ctx, tmpDir) - defer containerdC.Terminate(ctx) - - client, err := containerd.New(socketPath) - require.NoError(t, err) - defer client.Close() + client := setupContainerd(t, ctx, namespace) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -240,7 +253,7 @@ func TestContainerd_SearchLocalStoreByNameOrDigest(t *testing.T) { img, cleanup, err := image.NewContainerImage(ctx, tt.searchName, types.ImageOptions{ImageSources: types.ImageSources{types.ContainerdImageSource}}) defer cleanup() - if tt.expectErr { + if tt.wantErr { require.Error(t, err) return } @@ -272,7 +285,12 @@ func TestContainerd_LocalImage_Alternative_Namespace(t *testing.T) { } func localImageTestWithNamespace(t *testing.T, namespace string) { - t.Helper() + // Each architecture needs different images and test cases. + // Currently only amd64 architecture is supported + if runtime.GOARCH != "amd64" { + t.Skip("'Containerd' test only supports amd64 architecture") + } + tests := []struct { name string imageName string @@ -644,22 +662,10 @@ func localImageTestWithNamespace(t *testing.T, namespace string) { }, }, } - // Each architecture needs different images and test cases. - // Currently only amd64 architecture is supported - if runtime.GOARCH != "amd64" { - t.Skip("'Containerd' test only supports amd64 architecture") - } - ctx := namespaces.WithNamespace(context.Background(), namespace) - - tmpDir, socketPath := configureTestDataPaths(t, namespace) - defer os.RemoveAll(tmpDir) - - containerdC := startContainerd(t, ctx, tmpDir) - defer containerdC.Terminate(ctx) - client, err := containerd.New(socketPath) - require.NoError(t, err) - defer client.Close() + t.Helper() + ctx := namespaces.WithNamespace(context.Background(), namespace) + client := setupContainerd(t, ctx, namespace) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -731,6 +737,12 @@ func localImageTestWithNamespace(t *testing.T, namespace string) { } func TestContainerd_PullImage(t *testing.T) { + // Each architecture needs different images and test cases. + // Currently only amd64 architecture is supported + if runtime.GOARCH != "amd64" { + t.Skip("'Containerd' test only supports amd64 architecture") + } + tests := []struct { name string imageName string @@ -786,23 +798,9 @@ func TestContainerd_PullImage(t *testing.T) { }, } - // Each architecture needs different images and test cases. - // Currently only amd64 architecture is supported - if runtime.GOARCH != "amd64" { - t.Skip("'Containerd' test only supports amd64 architecture") - } - namespace := "default" ctx := namespaces.WithNamespace(context.Background(), namespace) - - tmpDir, socketPath := configureTestDataPaths(t, namespace) - - containerdC := startContainerd(t, ctx, tmpDir) - defer containerdC.Terminate(ctx) - - cli, err := containerd.New(socketPath) - require.NoError(t, err) - defer cli.Close() + client := setupContainerd(t, ctx, namespace) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -815,7 +813,7 @@ func TestContainerd_PullImage(t *testing.T) { c.Close() }() - _, err = cli.Pull(ctx, tt.imageName) + _, err = client.Pull(ctx, tt.imageName) require.NoError(t, err) // Enable only containerd From ae4bcf6a063ea212623570e6ac6523db4e046679 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Thu, 16 Nov 2023 14:42:30 +0900 Subject: [PATCH 002/108] fix(report): use time.Time for CreatedAt (#5598) Signed-off-by: knqyf263 --- integration/testdata/almalinux-8.json.golden | 2 +- integration/testdata/alpine-310-registry.json.golden | 2 +- integration/testdata/alpine-310.json.golden | 2 +- integration/testdata/alpine-39-high-critical.json.golden | 2 +- integration/testdata/alpine-39-ignore-cveids.json.golden | 2 +- integration/testdata/alpine-39-skip.json.golden | 2 +- integration/testdata/alpine-39.json.golden | 2 +- integration/testdata/alpine-distroless.json.golden | 2 +- integration/testdata/amazon-1.json.golden | 2 +- integration/testdata/amazon-2.json.golden | 2 +- integration/testdata/amazonlinux2-gp2-x86-vm.json.golden | 2 +- integration/testdata/busybox-with-lockfile.json.golden | 2 +- integration/testdata/centos-6.json.golden | 2 +- integration/testdata/centos-7-ignore-unfixed.json.golden | 2 +- integration/testdata/centos-7-medium.json.golden | 2 +- integration/testdata/centos-7.json.golden | 2 +- integration/testdata/cocoapods.json.golden | 2 +- integration/testdata/composer.lock.json.golden | 2 +- integration/testdata/conan.json.golden | 2 +- .../testdata/debian-buster-ignore-unfixed.json.golden | 2 +- integration/testdata/debian-buster.json.golden | 2 +- integration/testdata/debian-stretch.json.golden | 2 +- integration/testdata/distroless-base.json.golden | 2 +- integration/testdata/distroless-python27.json.golden | 2 +- integration/testdata/dockerfile-custom-policies.json.golden | 2 +- .../testdata/dockerfile-namespace-exception.json.golden | 2 +- integration/testdata/dockerfile-rule-exception.json.golden | 2 +- integration/testdata/dockerfile.json.golden | 2 +- integration/testdata/dockerfile_file_pattern.json.golden | 2 +- integration/testdata/dotnet.json.golden | 2 +- integration/testdata/fluentd-gems.json.golden | 2 +- integration/testdata/fluentd-multiple-lockfiles.json.golden | 2 +- integration/testdata/gomod-skip.json.golden | 2 +- integration/testdata/gomod.json.golden | 2 +- integration/testdata/gradle.json.golden | 2 +- integration/testdata/helm.json.golden | 2 +- integration/testdata/helm_badname.json.golden | 2 +- integration/testdata/helm_testchart.json.golden | 2 +- integration/testdata/helm_testchart.overridden.json.golden | 2 +- integration/testdata/mariner-1.0.json.golden | 2 +- integration/testdata/minikube-kbom.json.golden | 2 +- integration/testdata/mix.lock.json.golden | 2 +- integration/testdata/npm-with-dev.json.golden | 2 +- integration/testdata/npm.json.golden | 2 +- integration/testdata/nuget.json.golden | 2 +- integration/testdata/opensuse-leap-151.json.golden | 2 +- integration/testdata/oraclelinux-8.json.golden | 2 +- integration/testdata/photon-30.json.golden | 2 +- integration/testdata/pip.json.golden | 2 +- integration/testdata/pipenv.json.golden | 2 +- integration/testdata/pnpm.json.golden | 2 +- integration/testdata/poetry.json.golden | 2 +- integration/testdata/pom.json.golden | 2 +- integration/testdata/pubspec.lock.json.golden | 2 +- integration/testdata/rockylinux-8.json.golden | 2 +- integration/testdata/secrets.json.golden | 2 +- integration/testdata/spring4shell-jre11.json.golden | 2 +- integration/testdata/spring4shell-jre8.json.golden | 2 +- integration/testdata/swift.json.golden | 2 +- integration/testdata/test-repo.json.golden | 2 +- integration/testdata/ubi-7.json.golden | 2 +- integration/testdata/ubuntu-1804-ignore-unfixed.json.golden | 2 +- integration/testdata/ubuntu-1804.json.golden | 2 +- integration/testdata/ubuntu-gp2-x86-vm.json.golden | 2 +- integration/testdata/yarn.json.golden | 2 +- pkg/cloud/aws/commands/run_test.go | 6 ++++++ pkg/cloud/report/report.go | 2 ++ pkg/cloud/report/service_test.go | 4 ++++ pkg/scanner/scan.go | 2 +- pkg/scanner/scan_test.go | 2 +- pkg/types/report.go | 3 ++- 71 files changed, 81 insertions(+), 68 deletions(-) diff --git a/integration/testdata/almalinux-8.json.golden b/integration/testdata/almalinux-8.json.golden index b0c63578f3c4..824279932ef2 100644 --- a/integration/testdata/almalinux-8.json.golden +++ b/integration/testdata/almalinux-8.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/almalinux-8.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-310-registry.json.golden b/integration/testdata/alpine-310-registry.json.golden index 7ceeca40e612..c5336caaa4ed 100644 --- a/integration/testdata/alpine-310-registry.json.golden +++ b/integration/testdata/alpine-310-registry.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "localhost:53869/alpine:3.10", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-310.json.golden b/integration/testdata/alpine-310.json.golden index b0d8dcfbf992..6b0f8fb57389 100644 --- a/integration/testdata/alpine-310.json.golden +++ b/integration/testdata/alpine-310.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-310.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-39-high-critical.json.golden b/integration/testdata/alpine-39-high-critical.json.golden index 5fa44cf795a2..3d9a5acc2c12 100644 --- a/integration/testdata/alpine-39-high-critical.json.golden +++ b/integration/testdata/alpine-39-high-critical.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-39-ignore-cveids.json.golden b/integration/testdata/alpine-39-ignore-cveids.json.golden index 8402925ba637..1d187b9ed057 100644 --- a/integration/testdata/alpine-39-ignore-cveids.json.golden +++ b/integration/testdata/alpine-39-ignore-cveids.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-39-skip.json.golden b/integration/testdata/alpine-39-skip.json.golden index 6fedc78a89cf..2584d251c0b7 100644 --- a/integration/testdata/alpine-39-skip.json.golden +++ b/integration/testdata/alpine-39-skip.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-39.json.golden b/integration/testdata/alpine-39.json.golden index 38f23f8a7a96..f5dc05335673 100644 --- a/integration/testdata/alpine-39.json.golden +++ b/integration/testdata/alpine-39.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/alpine-distroless.json.golden b/integration/testdata/alpine-distroless.json.golden index 2ca81fd332ce..5dc55d99806b 100644 --- a/integration/testdata/alpine-distroless.json.golden +++ b/integration/testdata/alpine-distroless.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/alpine-distroless.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/amazon-1.json.golden b/integration/testdata/amazon-1.json.golden index 6377d1fc0531..9324ad548ed2 100644 --- a/integration/testdata/amazon-1.json.golden +++ b/integration/testdata/amazon-1.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/amazon-1.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/amazon-2.json.golden b/integration/testdata/amazon-2.json.golden index bcf5d075f1ea..5b19f2d5e006 100644 --- a/integration/testdata/amazon-2.json.golden +++ b/integration/testdata/amazon-2.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/amazon-2.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden index 9571ef66604a..aa3b62adbcb8 100644 --- a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden +++ b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "disk.img", "ArtifactType": "vm", "Metadata": { diff --git a/integration/testdata/busybox-with-lockfile.json.golden b/integration/testdata/busybox-with-lockfile.json.golden index af904c31f36b..f17f8796aa8b 100644 --- a/integration/testdata/busybox-with-lockfile.json.golden +++ b/integration/testdata/busybox-with-lockfile.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/busybox-with-lockfile.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/centos-6.json.golden b/integration/testdata/centos-6.json.golden index 741e300d03ef..3fbca6d85ad6 100644 --- a/integration/testdata/centos-6.json.golden +++ b/integration/testdata/centos-6.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/centos-6.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/centos-7-ignore-unfixed.json.golden b/integration/testdata/centos-7-ignore-unfixed.json.golden index 3c32c19fc701..f27d99919849 100644 --- a/integration/testdata/centos-7-ignore-unfixed.json.golden +++ b/integration/testdata/centos-7-ignore-unfixed.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/centos-7.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/centos-7-medium.json.golden b/integration/testdata/centos-7-medium.json.golden index 4fc41b8a0167..955c833a34c1 100644 --- a/integration/testdata/centos-7-medium.json.golden +++ b/integration/testdata/centos-7-medium.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/centos-7.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/centos-7.json.golden b/integration/testdata/centos-7.json.golden index 26138b9a32ee..e549fdac14db 100644 --- a/integration/testdata/centos-7.json.golden +++ b/integration/testdata/centos-7.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/centos-7.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/cocoapods.json.golden b/integration/testdata/cocoapods.json.golden index a9a126997012..35ea7c41a051 100644 --- a/integration/testdata/cocoapods.json.golden +++ b/integration/testdata/cocoapods.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/cocoapods", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/composer.lock.json.golden b/integration/testdata/composer.lock.json.golden index d175123d144f..6b8dbc6cf6bc 100644 --- a/integration/testdata/composer.lock.json.golden +++ b/integration/testdata/composer.lock.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/composer", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/conan.json.golden b/integration/testdata/conan.json.golden index ec7298b12054..3b0d8d4f4e0d 100644 --- a/integration/testdata/conan.json.golden +++ b/integration/testdata/conan.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/conan", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/debian-buster-ignore-unfixed.json.golden b/integration/testdata/debian-buster-ignore-unfixed.json.golden index 7d8e8418dc50..57c94d41b662 100644 --- a/integration/testdata/debian-buster-ignore-unfixed.json.golden +++ b/integration/testdata/debian-buster-ignore-unfixed.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/debian-buster.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/debian-buster.json.golden b/integration/testdata/debian-buster.json.golden index ef99f7455995..6124ab93de1b 100644 --- a/integration/testdata/debian-buster.json.golden +++ b/integration/testdata/debian-buster.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/debian-buster.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/debian-stretch.json.golden b/integration/testdata/debian-stretch.json.golden index 2cec165ac3cb..0b31b5eedaa5 100644 --- a/integration/testdata/debian-stretch.json.golden +++ b/integration/testdata/debian-stretch.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/debian-stretch.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/distroless-base.json.golden b/integration/testdata/distroless-base.json.golden index 39aba72910ac..ff3156dacfd6 100644 --- a/integration/testdata/distroless-base.json.golden +++ b/integration/testdata/distroless-base.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/distroless-base.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/distroless-python27.json.golden b/integration/testdata/distroless-python27.json.golden index c5f72aa791d8..4e6a2464b941 100644 --- a/integration/testdata/distroless-python27.json.golden +++ b/integration/testdata/distroless-python27.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/distroless-python27.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/dockerfile-custom-policies.json.golden b/integration/testdata/dockerfile-custom-policies.json.golden index aea2e3a5b235..c9ec6cd7d5b4 100644 --- a/integration/testdata/dockerfile-custom-policies.json.golden +++ b/integration/testdata/dockerfile-custom-policies.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/custom-policy", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/dockerfile-namespace-exception.json.golden b/integration/testdata/dockerfile-namespace-exception.json.golden index 53e6f93a6db3..d3a974f52410 100644 --- a/integration/testdata/dockerfile-namespace-exception.json.golden +++ b/integration/testdata/dockerfile-namespace-exception.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/namespace-exception", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/dockerfile-rule-exception.json.golden b/integration/testdata/dockerfile-rule-exception.json.golden index 6d447d980536..f37cb5fc1c15 100644 --- a/integration/testdata/dockerfile-rule-exception.json.golden +++ b/integration/testdata/dockerfile-rule-exception.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/rule-exception", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/dockerfile.json.golden b/integration/testdata/dockerfile.json.golden index 72ebc7d00a9b..67fb571b18ee 100644 --- a/integration/testdata/dockerfile.json.golden +++ b/integration/testdata/dockerfile.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/dockerfile", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/dockerfile_file_pattern.json.golden b/integration/testdata/dockerfile_file_pattern.json.golden index fae1f25b28c3..810c6ed1e425 100644 --- a/integration/testdata/dockerfile_file_pattern.json.golden +++ b/integration/testdata/dockerfile_file_pattern.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/dockerfile_file_pattern", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/dotnet.json.golden b/integration/testdata/dotnet.json.golden index 6409886f684b..d04624965482 100644 --- a/integration/testdata/dotnet.json.golden +++ b/integration/testdata/dotnet.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/dotnet", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/fluentd-gems.json.golden b/integration/testdata/fluentd-gems.json.golden index 2a6f60da3886..f75e6ac6fb2a 100644 --- a/integration/testdata/fluentd-gems.json.golden +++ b/integration/testdata/fluentd-gems.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/fluentd-multiple-lockfiles.json.golden b/integration/testdata/fluentd-multiple-lockfiles.json.golden index 46cb86eda6ef..a3917f31d7b6 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json", "ArtifactType": "cyclonedx", "Metadata": { diff --git a/integration/testdata/gomod-skip.json.golden b/integration/testdata/gomod-skip.json.golden index b58c9abed51e..a0ad5e7182cc 100644 --- a/integration/testdata/gomod-skip.json.golden +++ b/integration/testdata/gomod-skip.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/gomod", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/gomod.json.golden b/integration/testdata/gomod.json.golden index 397cfac89244..fb495a8e07ed 100644 --- a/integration/testdata/gomod.json.golden +++ b/integration/testdata/gomod.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/gomod", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/gradle.json.golden b/integration/testdata/gradle.json.golden index eac7bab6093a..48c2580b8cba 100644 --- a/integration/testdata/gradle.json.golden +++ b/integration/testdata/gradle.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/gradle", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/helm.json.golden b/integration/testdata/helm.json.golden index 08b89c8cbe89..037d02a8c26a 100644 --- a/integration/testdata/helm.json.golden +++ b/integration/testdata/helm.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/helm", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/helm_badname.json.golden b/integration/testdata/helm_badname.json.golden index 8b935eb05bb2..081df6943447 100644 --- a/integration/testdata/helm_badname.json.golden +++ b/integration/testdata/helm_badname.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/helm_badname", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/helm_testchart.json.golden b/integration/testdata/helm_testchart.json.golden index 00d8c862528f..58bce82835f9 100644 --- a/integration/testdata/helm_testchart.json.golden +++ b/integration/testdata/helm_testchart.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/helm_testchart", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/helm_testchart.overridden.json.golden b/integration/testdata/helm_testchart.overridden.json.golden index 6adb11041096..62d914c2b024 100644 --- a/integration/testdata/helm_testchart.overridden.json.golden +++ b/integration/testdata/helm_testchart.overridden.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/helm_testchart", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/mariner-1.0.json.golden b/integration/testdata/mariner-1.0.json.golden index 7c93c46e7f44..3c9ccbcd50e3 100644 --- a/integration/testdata/mariner-1.0.json.golden +++ b/integration/testdata/mariner-1.0.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/mariner-1.0.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/minikube-kbom.json.golden b/integration/testdata/minikube-kbom.json.golden index 4d4b277c7e3b..92215cf7b6e3 100644 --- a/integration/testdata/minikube-kbom.json.golden +++ b/integration/testdata/minikube-kbom.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/sbom/minikube-kbom.json", "ArtifactType": "cyclonedx", "Metadata": { diff --git a/integration/testdata/mix.lock.json.golden b/integration/testdata/mix.lock.json.golden index 8af6ae404292..b7180404bc3c 100644 --- a/integration/testdata/mix.lock.json.golden +++ b/integration/testdata/mix.lock.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/mixlock", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/npm-with-dev.json.golden b/integration/testdata/npm-with-dev.json.golden index a77dcd400ca4..9ace83bf5b27 100644 --- a/integration/testdata/npm-with-dev.json.golden +++ b/integration/testdata/npm-with-dev.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/npm", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/npm.json.golden b/integration/testdata/npm.json.golden index 0fbf98b5eec2..94dd11ae41db 100644 --- a/integration/testdata/npm.json.golden +++ b/integration/testdata/npm.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/npm", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/nuget.json.golden b/integration/testdata/nuget.json.golden index 7f5eb95503dd..c0285aea9555 100644 --- a/integration/testdata/nuget.json.golden +++ b/integration/testdata/nuget.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/nuget", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/opensuse-leap-151.json.golden b/integration/testdata/opensuse-leap-151.json.golden index 70e4c9f700c7..5b66db1b580f 100644 --- a/integration/testdata/opensuse-leap-151.json.golden +++ b/integration/testdata/opensuse-leap-151.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/opensuse-leap-151.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/oraclelinux-8.json.golden b/integration/testdata/oraclelinux-8.json.golden index f280f58ec20f..d44fb10ec399 100644 --- a/integration/testdata/oraclelinux-8.json.golden +++ b/integration/testdata/oraclelinux-8.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/oraclelinux-8.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/photon-30.json.golden b/integration/testdata/photon-30.json.golden index e3919d189a52..f27af155f454 100644 --- a/integration/testdata/photon-30.json.golden +++ b/integration/testdata/photon-30.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/photon-30.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/pip.json.golden b/integration/testdata/pip.json.golden index 0c69d66da2a4..ef4af98f6293 100644 --- a/integration/testdata/pip.json.golden +++ b/integration/testdata/pip.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/pip", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/pipenv.json.golden b/integration/testdata/pipenv.json.golden index be56a0c3ea2f..507ecfe6a45e 100644 --- a/integration/testdata/pipenv.json.golden +++ b/integration/testdata/pipenv.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/pipenv", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/pnpm.json.golden b/integration/testdata/pnpm.json.golden index 9a14d801262f..d5001c1758cb 100644 --- a/integration/testdata/pnpm.json.golden +++ b/integration/testdata/pnpm.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/pnpm", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/poetry.json.golden b/integration/testdata/poetry.json.golden index 0e9389d65eea..ac174525bcc4 100644 --- a/integration/testdata/poetry.json.golden +++ b/integration/testdata/poetry.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/poetry", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/pom.json.golden b/integration/testdata/pom.json.golden index b15579088f5d..249f3c24505b 100644 --- a/integration/testdata/pom.json.golden +++ b/integration/testdata/pom.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/pom", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/pubspec.lock.json.golden b/integration/testdata/pubspec.lock.json.golden index b67718d741a4..bceade5a9b6a 100644 --- a/integration/testdata/pubspec.lock.json.golden +++ b/integration/testdata/pubspec.lock.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/pubspec", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/rockylinux-8.json.golden b/integration/testdata/rockylinux-8.json.golden index 5fc4816d0387..67ecc66b246d 100644 --- a/integration/testdata/rockylinux-8.json.golden +++ b/integration/testdata/rockylinux-8.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/rockylinux-8.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/secrets.json.golden b/integration/testdata/secrets.json.golden index 4da66ddf2f13..15ab882e150c 100644 --- a/integration/testdata/secrets.json.golden +++ b/integration/testdata/secrets.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/secrets", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/spring4shell-jre11.json.golden b/integration/testdata/spring4shell-jre11.json.golden index 794725cf657e..1b9d2db6885c 100644 --- a/integration/testdata/spring4shell-jre11.json.golden +++ b/integration/testdata/spring4shell-jre11.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/spring4shell-jre11.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/spring4shell-jre8.json.golden b/integration/testdata/spring4shell-jre8.json.golden index 90927327dc99..13fbc3943355 100644 --- a/integration/testdata/spring4shell-jre8.json.golden +++ b/integration/testdata/spring4shell-jre8.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/spring4shell-jre8.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/swift.json.golden b/integration/testdata/swift.json.golden index ab0b4ab44a7b..10b004671c89 100644 --- a/integration/testdata/swift.json.golden +++ b/integration/testdata/swift.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/swift", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/test-repo.json.golden b/integration/testdata/test-repo.json.golden index 4fb33be4a35e..4235056228c0 100644 --- a/integration/testdata/test-repo.json.golden +++ b/integration/testdata/test-repo.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "https://github.com/knqyf263/trivy-ci-test", "ArtifactType": "repository", "Metadata": { diff --git a/integration/testdata/ubi-7.json.golden b/integration/testdata/ubi-7.json.golden index bfad8f153e59..c2939762b954 100644 --- a/integration/testdata/ubi-7.json.golden +++ b/integration/testdata/ubi-7.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/ubi-7.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden index 1674c96f7d5b..a35729b41d71 100644 --- a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden +++ b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/ubuntu-1804.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/ubuntu-1804.json.golden b/integration/testdata/ubuntu-1804.json.golden index 312a3e19cb62..8c8d174674b2 100644 --- a/integration/testdata/ubuntu-1804.json.golden +++ b/integration/testdata/ubuntu-1804.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/images/ubuntu-1804.tar.gz", "ArtifactType": "container_image", "Metadata": { diff --git a/integration/testdata/ubuntu-gp2-x86-vm.json.golden b/integration/testdata/ubuntu-gp2-x86-vm.json.golden index e027cdd00bc9..1ec3c1c86015 100644 --- a/integration/testdata/ubuntu-gp2-x86-vm.json.golden +++ b/integration/testdata/ubuntu-gp2-x86-vm.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "disk.img", "ArtifactType": "vm", "Metadata": { diff --git a/integration/testdata/yarn.json.golden b/integration/testdata/yarn.json.golden index 816c3221c1bb..1e9054339883 100644 --- a/integration/testdata/yarn.json.golden +++ b/integration/testdata/yarn.json.golden @@ -1,6 +1,6 @@ { "SchemaVersion": 2, - "CreatedAt": 1629894030, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "testdata/fixtures/repo/yarn", "ArtifactType": "repository", "Metadata": { diff --git a/pkg/cloud/aws/commands/run_test.go b/pkg/cloud/aws/commands/run_test.go index a7ac58886f8b..3c7a188f2d33 100644 --- a/pkg/cloud/aws/commands/run_test.go +++ b/pkg/cloud/aws/commands/run_test.go @@ -3,6 +3,7 @@ package commands import ( "bytes" "context" + "github.com/aquasecurity/trivy/pkg/clock" "os" "path/filepath" "testing" @@ -18,6 +19,7 @@ import ( ) const expectedS3ScanResult = `{ + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "12345678", "ArtifactType": "aws_account", "Metadata": { @@ -265,6 +267,7 @@ const expectedS3ScanResult = `{ ` const expectedCustomScanResult = `{ + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "12345678", "ArtifactType": "aws_account", "Metadata": { @@ -545,6 +548,7 @@ const expectedCustomScanResult = `{ ` const expectedS3AndCloudTrailResult = `{ + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactName": "123456789", "ArtifactType": "aws_account", "Metadata": { @@ -1124,6 +1128,8 @@ Summary Report for compliance: my-custom-spec expectErr: true, }, } + + clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.allServices != nil { diff --git a/pkg/cloud/report/report.go b/pkg/cloud/report/report.go index 6742db9d043a..6c7b1ac6d874 100644 --- a/pkg/cloud/report/report.go +++ b/pkg/cloud/report/report.go @@ -11,6 +11,7 @@ import ( "github.com/aquasecurity/defsec/pkg/scan" "github.com/aquasecurity/tml" + "github.com/aquasecurity/trivy/pkg/clock" cr "github.com/aquasecurity/trivy/pkg/compliance/report" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/flag" @@ -94,6 +95,7 @@ func Write(rep *Report, opt flag.Options, fromCache bool) error { }) base := types.Report{ + CreatedAt: clock.Now(), ArtifactName: rep.AccountID, ArtifactType: ftypes.ArtifactAWSAccount, Results: filtered, diff --git a/pkg/cloud/report/service_test.go b/pkg/cloud/report/service_test.go index d520285cabf1..b60e6f37c7ce 100644 --- a/pkg/cloud/report/service_test.go +++ b/pkg/cloud/report/service_test.go @@ -2,7 +2,9 @@ package report import ( "bytes" + "github.com/aquasecurity/trivy/pkg/clock" "testing" + "time" "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/stretchr/testify/assert" @@ -146,6 +148,7 @@ Scan Overview for AWS Account }, fromCache: false, expected: `{ + "CreatedAt": "2021-08-25T12:20:30.000000005Z", "ArtifactType": "aws_account", "Metadata": { "ImageConfig": { @@ -306,6 +309,7 @@ Scan Overview for AWS Account }`, }, } + clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { report := New( diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index 1981f4828e64..cc1950b31fc9 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -173,7 +173,7 @@ func (s Scanner) ScanArtifact(ctx context.Context, options types.ScanOptions) (t return types.Report{ SchemaVersion: report.SchemaVersion, - CreatedAt: clock.Now().Unix(), + CreatedAt: clock.Now(), ArtifactName: artifactInfo.Name, ArtifactType: artifactInfo.Type, Metadata: types.Metadata{ diff --git a/pkg/scanner/scan_test.go b/pkg/scanner/scan_test.go index 808596f745ba..ba78193e7962 100644 --- a/pkg/scanner/scan_test.go +++ b/pkg/scanner/scan_test.go @@ -99,7 +99,7 @@ func TestScanner_ScanArtifact(t *testing.T) { }, want: types.Report{ SchemaVersion: 2, - CreatedAt: 1629894030, + CreatedAt: time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC), ArtifactName: "alpine:3.11", ArtifactType: ftypes.ArtifactContainerImage, Metadata: types.Metadata{ diff --git a/pkg/types/report.go b/pkg/types/report.go index edead1568ca1..c923097ee4a0 100644 --- a/pkg/types/report.go +++ b/pkg/types/report.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "time" v1 "github.com/google/go-containerregistry/pkg/v1" // nolint: goimports @@ -11,7 +12,7 @@ import ( // Report represents a scan result type Report struct { SchemaVersion int `json:",omitempty"` - CreatedAt int64 `json:",omitempty"` + CreatedAt time.Time `json:",omitempty"` ArtifactName string `json:",omitempty"` ArtifactType ftypes.ArtifactType `json:",omitempty"` Metadata Metadata `json:",omitempty"` From 44d0b28ada21d5f6ab206b61c9c3899f74b890a9 Mon Sep 17 00:00:00 2001 From: Sylvain Baubeau Date: Thu, 16 Nov 2023 07:37:39 +0100 Subject: [PATCH 003/108] feat: set InstalledFiles for DEB and RPM packages (#5488) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- pkg/fanal/analyzer/pkg/dpkg/dpkg.go | 14 ++++++++++++++ pkg/fanal/analyzer/pkg/rpm/rpm.go | 8 +++++--- pkg/fanal/analyzer/pkg/rpm/rpm_test.go | 5 +++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/pkg/fanal/analyzer/pkg/dpkg/dpkg.go b/pkg/fanal/analyzer/pkg/dpkg/dpkg.go index 7a8f429f3c35..74fd4d82ef7b 100644 --- a/pkg/fanal/analyzer/pkg/dpkg/dpkg.go +++ b/pkg/fanal/analyzer/pkg/dpkg/dpkg.go @@ -65,6 +65,8 @@ func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysis return path != availableFile } + packageFiles := make(map[string][]string) + // parse other files err = fsutils.WalkDir(input.FS, ".", required, func(path string, d fs.DirEntry, r io.Reader) error { // parse list files @@ -74,6 +76,7 @@ func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysis if err != nil { return err } + packageFiles[strings.TrimSuffix(filepath.Base(path), ".list")] = systemFiles systemInstalledFiles = append(systemInstalledFiles, systemFiles...) return nil } @@ -89,6 +92,17 @@ func (a dpkgAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysis return nil, xerrors.Errorf("dpkg walk error: %w", err) } + // map the packages to their respective files + for i, pkgInfo := range packageInfos { + for j, pkg := range pkgInfo.Packages { + installedFiles, found := packageFiles[pkg.Name] + if !found { + installedFiles = packageFiles[pkg.Name+":"+pkg.Arch] + } + packageInfos[i].Packages[j].InstalledFiles = installedFiles + } + } + return &analyzer.AnalysisResult{ PackageInfos: packageInfos, SystemInstalledFiles: systemInstalledFiles, diff --git a/pkg/fanal/analyzer/pkg/rpm/rpm.go b/pkg/fanal/analyzer/pkg/rpm/rpm.go index 4a4911f46ccb..1efd91c0e8e1 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpm.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpm.go @@ -138,9 +138,10 @@ func (a rpmPkgAnalyzer) listPkgs(db RPMDB) (types.Packages, []string, error) { if err != nil { return nil, nil, xerrors.Errorf("unable to get installed files: %w", err) } - files = lo.Map(files, func(file string, _ int) string { - return filepath.ToSlash(file) - }) + + for i, file := range files { + files[i] = filepath.ToSlash(file) + } } // RPM DB uses MD5 digest @@ -171,6 +172,7 @@ func (a rpmPkgAnalyzer) listPkgs(db RPMDB) (types.Packages, []string, error) { DependsOn: pkg.Requires, // Will be replaced with package IDs Maintainer: pkg.Vendor, Digest: d, + InstalledFiles: files, } pkgs = append(pkgs, p) installedFiles = append(installedFiles, files...) diff --git a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go index d5888b8574d6..aebb70928fb1 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go @@ -151,6 +151,11 @@ func Test_rpmPkgAnalyzer_listPkgs(t *testing.T) { SrcVersion: "2.17", SrcRelease: "317.el7", Maintainer: "Red Hat", + InstalledFiles: []string{ + "/etc/ld.so.conf", + "/etc/rpc", + "/lib64/libm-2.27.so", + }, }, }, wantFiles: []string{ From 214546427e76da21bbc61a5b70ec00d5b95f6d0b Mon Sep 17 00:00:00 2001 From: chenk Date: Thu, 16 Nov 2023 08:41:45 +0200 Subject: [PATCH 004/108] fix: k8s friendly error messages kbom non cluster scans (#5594) Signed-off-by: chenk --- pkg/k8s/commands/run.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/k8s/commands/run.go b/pkg/k8s/commands/run.go index df6836997632..9207363342c6 100644 --- a/pkg/k8s/commands/run.go +++ b/pkg/k8s/commands/run.go @@ -47,8 +47,14 @@ func Run(ctx context.Context, args []string, opts flag.Options) error { case clusterArtifact: return clusterRun(ctx, opts, cluster) case allArtifact: + if opts.Format == types.FormatCycloneDX { + return xerrors.Errorf("KBOM with CycloneDX format is not supported for all namespace scans") + } return namespaceRun(ctx, opts, cluster) default: // resourceArtifact + if opts.Format == types.FormatCycloneDX { + return xerrors.Errorf("KBOM with CycloneDX format is not supported for resource scans") + } return resourceRun(ctx, args, opts, cluster) } } From 3c817270349f1fed85bdd30787111745e20e69ef Mon Sep 17 00:00:00 2001 From: Jeremy Adams Date: Sun, 19 Nov 2023 16:54:26 -0800 Subject: [PATCH 005/108] docs: Add Dagger integration section and cleanup Ecosystem CICD docs page (#5608) Signed-off-by: Jeremy Adams --- docs/ecosystem/cicd.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/ecosystem/cicd.md b/docs/ecosystem/cicd.md index 301902cee68b..12d050cd6b0e 100644 --- a/docs/ecosystem/cicd.md +++ b/docs/ecosystem/cicd.md @@ -1,5 +1,12 @@ # CI/CD Integrations +## Azure DevOps (Official) +[Azure Devops](https://azure.microsoft.com/en-us/products/devops/#overview) is Microsoft Azure cloud native CI/CD service. + +Trivy has a "Azure Devops Pipelines Task" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI. + +👉 Get it at: + ## GitHub Actions [GitHub Actions](https://github.com/features/actions) is GitHub's native CI/CD and job orchestration service. @@ -9,13 +16,6 @@ GitHub Action for integrating Trivy into your GitHub pipeline 👉 Get it at: -## Azure DevOps (Official) -[Azure Devops](https://azure.microsoft.com/en-us/products/devops/#overview) is Microsoft Azure cloud native CI/CD service. - -Trivy has a "Azure Devops Pipelines Task" for Trivy, that lets you easily introduce security scanning into your workflow, with an integrated Azure Devops UI. - -👉 Get it at: - ### trivy-action (Community) GitHub Action to scan vulnerability using Trivy. If vulnerabilities are found by Trivy, it creates a GitHub Issue. @@ -28,12 +28,20 @@ In this action, Trivy scans the dependency files such as package-lock.json and g 👉 Get it at: -### Buildkite Plugin (Community) +## Buildkite Plugin (Community) The trivy buildkite plugin provides a convenient mechanism for running the open-source trivy static analysis tool on your project. 👉 Get it at: https://github.com/equinixmetal-buildkite/trivy-buildkite-plugin +## Dagger (Community) +[Dagger](https://dagger.io/) is CI/CD as code that runs anywhere. + +The Dagger module for Trivy provides functions for scanning container images from registries as well as Dagger Container objects from any Dagger SDK (e.g. Go, Python, Node.js, etc). + +👉 Get it at: + + ## Semaphore (Community) [Semaphore](https://semaphoreci.com/) is a CI/CD service. From ed0022b91547d582e14fb05731520ea0f61a90d3 Mon Sep 17 00:00:00 2001 From: Tom Janson Date: Mon, 20 Nov 2023 02:13:27 +0100 Subject: [PATCH 006/108] docs(vuln): fix link anchor (#5606) --- docs/docs/scanner/vulnerability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/scanner/vulnerability.md b/docs/docs/scanner/vulnerability.md index 3d63ea7b1884..3e3ed617248d 100644 --- a/docs/docs/scanner/vulnerability.md +++ b/docs/docs/scanner/vulnerability.md @@ -5,7 +5,7 @@ The following packages are supported. - [OS packages](#os-packages) - [Language-specific packages](#language-specific-packages) -- [Kubernetes components (control plane, node and addons)](#kubernetes-components-control-plane-node-and-addons) +- [Kubernetes components (control plane, node and addons)](#kubernetes) Trivy also detects known vulnerabilities in Kubernetes components using KBOM (Kubernetes bill of Material) scanning. To learn more, see the [documentation for Kubernetes scanning](../target/kubernetes.md#KBOM). From c866f1c4e99ba0026fe9f632fbe97fc5d89165d1 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Mon, 20 Nov 2023 21:38:45 +0900 Subject: [PATCH 007/108] chore: add prefix to image errors (#5601) Signed-off-by: knqyf263 --- pkg/commands/artifact/inject.go | 8 ++++---- pkg/commands/artifact/scanner.go | 8 ++++---- pkg/commands/artifact/wire_gen.go | 8 ++++---- pkg/fanal/image/image.go | 2 ++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/pkg/commands/artifact/inject.go b/pkg/commands/artifact/inject.go index c6bf6f4594a6..19d6e8565f02 100644 --- a/pkg/commands/artifact/inject.go +++ b/pkg/commands/artifact/inject.go @@ -20,9 +20,9 @@ import ( // Standalone ////////////// -// initializeDockerScanner is for container image scanning in standalone mode +// initializeImageScanner is for container image scanning in standalone mode // e.g. dockerd, container registry, podman, etc. -func initializeDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, +func initializeImageScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, imageOpt types.ImageOptions, artifactOption artifact.Option) ( scanner.Scanner, func(), error) { wire.Build(scanner.StandaloneDockerSet) @@ -67,9 +67,9 @@ func initializeVMScanner(ctx context.Context, filePath string, artifactCache cac // Client/Server ///////////////// -// initializeRemoteDockerScanner is for container image scanning in client/server mode +// initializeRemoteImageScanner is for container image scanning in client/server mode // e.g. dockerd, container registry, podman, etc. -func initializeRemoteDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, +func initializeRemoteImageScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, imageOpt types.ImageOptions, artifactOption artifact.Option) ( scanner.Scanner, func(), error) { wire.Build(scanner.RemoteDockerSet) diff --git a/pkg/commands/artifact/scanner.go b/pkg/commands/artifact/scanner.go index e5946193b789..5685572a10c4 100644 --- a/pkg/commands/artifact/scanner.go +++ b/pkg/commands/artifact/scanner.go @@ -12,10 +12,10 @@ import ( // imageStandaloneScanner initializes a container image scanner in standalone mode // $ trivy image alpine:3.15 func imageStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) { - s, cleanup, err := initializeDockerScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, + s, cleanup, err := initializeImageScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption.ImageOption, conf.ArtifactOption) if err != nil { - return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a docker scanner: %w", err) + return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize an image scanner: %w", err) } return s, cleanup, nil } @@ -34,10 +34,10 @@ func archiveStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner. // $ trivy image --server localhost:4954 alpine:3.15 func imageRemoteScanner(ctx context.Context, conf ScannerConfig) ( scanner.Scanner, func(), error) { - s, cleanup, err := initializeRemoteDockerScanner(ctx, conf.Target, conf.ArtifactCache, conf.ServerOption, + s, cleanup, err := initializeRemoteImageScanner(ctx, conf.Target, conf.ArtifactCache, conf.ServerOption, conf.ArtifactOption.ImageOption, conf.ArtifactOption) if err != nil { - return scanner.Scanner{}, nil, xerrors.Errorf("unable to initialize the remote docker scanner: %w", err) + return scanner.Scanner{}, nil, xerrors.Errorf("unable to initialize a remote image scanner: %w", err) } return s, cleanup, nil } diff --git a/pkg/commands/artifact/wire_gen.go b/pkg/commands/artifact/wire_gen.go index 2c8cb311d431..e91ae3d5e8c8 100644 --- a/pkg/commands/artifact/wire_gen.go +++ b/pkg/commands/artifact/wire_gen.go @@ -29,9 +29,9 @@ import ( // Injectors from inject.go: -// initializeDockerScanner is for container image scanning in standalone mode +// initializeImageScanner is for container image scanning in standalone mode // e.g. dockerd, container registry, podman, etc. -func initializeDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, imageOpt types.ImageOptions, artifactOption artifact.Option) (scanner.Scanner, func(), error) { +func initializeImageScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, imageOpt types.ImageOptions, artifactOption artifact.Option) (scanner.Scanner, func(), error) { applierApplier := applier.NewApplier(localArtifactCache) ospkgScanner := ospkg.NewScanner() langpkgScanner := langpkg.NewScanner() @@ -140,9 +140,9 @@ func initializeVMScanner(ctx context.Context, filePath string, artifactCache cac }, nil } -// initializeRemoteDockerScanner is for container image scanning in client/server mode +// initializeRemoteImageScanner is for container image scanning in client/server mode // e.g. dockerd, container registry, podman, etc. -func initializeRemoteDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, imageOpt types.ImageOptions, artifactOption artifact.Option) (scanner.Scanner, func(), error) { +func initializeRemoteImageScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, imageOpt types.ImageOptions, artifactOption artifact.Option) (scanner.Scanner, func(), error) { v := _wireValue clientScanner := client.NewScanner(remoteScanOptions, v...) typesImage, cleanup, err := image.NewContainerImage(ctx, imageName, imageOpt) diff --git a/pkg/fanal/image/image.go b/pkg/fanal/image/image.go index 0194dff6b217..fc8e14ab37e1 100644 --- a/pkg/fanal/image/image.go +++ b/pkg/fanal/image/image.go @@ -2,6 +2,7 @@ package image import ( "context" + "fmt" "strings" "github.com/google/go-containerregistry/pkg/name" @@ -50,6 +51,7 @@ func NewContainerImage(ctx context.Context, imageName string, opt types.ImageOpt // Return v1.Image if the image is found return img, cleanup, nil } + err = multierror.Prefix(err, fmt.Sprintf("%s error:", src)) errs = multierror.Append(errs, err) } From 65351d4f2ac1e7ece32c565a6008d684f78ae39c Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Wed, 22 Nov 2023 09:23:56 +0800 Subject: [PATCH 008/108] docs: Update Arch Linux package URL in installation.md (#5619) --- docs/getting-started/installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index d142931fd462..21cdf321e49a 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -59,15 +59,15 @@ brew install trivy ### Arch Linux (Community) -Arch Community Package Manager. +Arch Linux Package Repository. ```bash pacman -S trivy ``` References: -- -- +- +- ### MacPorts (Community) From b1dc60b88523cd4bddc25d5fb77c47e69198cc43 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 22 Nov 2023 07:43:59 +0600 Subject: [PATCH 009/108] fix(secret): exclude upper case before secret for `alibaba-access-key-id` (#5618) --- pkg/fanal/secret/builtin-rules.go | 2 +- pkg/fanal/secret/testdata/alibaba-access-key-id.txt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index 16be5ff66595..fa9b622eb492 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -279,7 +279,7 @@ var builtinRules = []Rule{ Category: CategoryAlibaba, Title: "Alibaba AccessKey ID", Severity: "HIGH", - Regex: MustCompile(`([^0-9a-z]|^)(?P(LTAI)(?i)[a-z0-9]{20})([^0-9a-z]|$)`), + Regex: MustCompile(`([^0-9A-Za-z]|^)(?P(LTAI)(?i)[a-z0-9]{20})([^0-9A-Za-z]|$)`), SecretGroupName: "secret", Keywords: []string{"LTAI"}, }, diff --git a/pkg/fanal/secret/testdata/alibaba-access-key-id.txt b/pkg/fanal/secret/testdata/alibaba-access-key-id.txt index 949f3d51ecd5..f7d92c446ea9 100644 --- a/pkg/fanal/secret/testdata/alibaba-access-key-id.txt +++ b/pkg/fanal/secret/testdata/alibaba-access-key-id.txt @@ -1,3 +1,6 @@ key : LTAI1234567890ABCDEFG123asd key = LTAI1234567890ABCDEFG123, -asdLTAI1234567890ABCDEFG123 \ No newline at end of file +asdLTAI1234567890ABCDEFG123 +asDLTAI1234567890ABCDEFG123 +as1LTAI1234567890ABCDEFG123 +key : LTAI1234567890ABCDEFG123Asd \ No newline at end of file From ad977a4256920d6269e84c82e4f42bbe244a2c5a Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 22 Nov 2023 07:44:45 +0600 Subject: [PATCH 010/108] fix(nodejs): support protocols for dependency section in yarn.lock files (#5612) --- go.mod | 14 +++++++------- go.sum | 30 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 47594ca087d4..b31d0f1b5744 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898 - github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39 + github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 @@ -103,10 +103,10 @@ require ( go.etcd.io/bbolt v1.3.7 go.uber.org/zap v1.26.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/mod v0.13.0 + golang.org/x/mod v0.14.0 golang.org/x/sync v0.3.0 - golang.org/x/term v0.13.0 - golang.org/x/text v0.13.0 + golang.org/x/term v0.14.0 + golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 @@ -365,10 +365,10 @@ require ( go.opentelemetry.io/otel/trace v1.16.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/crypto v0.15.0 // indirect + golang.org/x/net v0.18.0 // indirect golang.org/x/oauth2 v0.11.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/api v0.138.0 // indirect diff --git a/go.sum b/go.sum index 0b350edd0a19..0bd9e6aceb22 100644 --- a/go.sum +++ b/go.sum @@ -322,8 +322,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898 h1:gu7XQvv2CswgzOdOFHg/AmtR4vBonG35XvGxHHvcIr4= github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898/go.mod h1:J30VViSgmoW2Ic/6aqVJO2qvuADsmZ3MYuNxPcU6Vt0= -github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39 h1:5yB6PHCaU4yZzN1mMFnrpBerz2pgqYdDRRVSOj4EjVo= -github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39/go.mod h1:RpdbxLhxxvWmv83HWNEiv+reFkmnV+GqHqr66mIU8nU= +github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf h1:kweQrNMfarPfjZGI1537GtuujhpzhsuT/MvmW2FwaBE= +github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8= @@ -1103,7 +1103,7 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1: github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= +github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= @@ -1776,8 +1776,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1817,8 +1817,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1887,8 +1887,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2062,8 +2062,8 @@ 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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2071,8 +2071,8 @@ golang.org/x/term v0.1.0/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.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= 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= @@ -2086,8 +2086,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 8ff574e3f732e5b94651431591bf18d6d497cf02 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:12:06 +0600 Subject: [PATCH 011/108] fix(secret): add `sec` and space to secret prefix for `aws-secret-access-key` (#5647) --- pkg/fanal/secret/builtin-rules.go | 4 +-- pkg/fanal/secret/scanner_test.go | 33 ++++++++++++++++++++++- pkg/fanal/secret/testdata/aws-secrets.txt | 3 ++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index fa9b622eb492..b868967b6696 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -73,7 +73,7 @@ var ( // Reusable regex patterns const ( quote = `["']?` - connect = `\s*(:|=>|=)\s*` + connect = `\s*(:|=>|=)?\s*` startSecret = `(^|\s+)` endSecret = `(\s+|$)` @@ -105,7 +105,7 @@ var builtinRules = []Rule{ Category: CategoryAWS, Severity: "CRITICAL", Title: "AWS Secret Access Key", - Regex: MustCompile(fmt.Sprintf(`(?i)%s%s%s(secret)?_?(access)?_?key%s%s%s(?P[A-Za-z0-9\/\+=]{40})%s%s`, startSecret, quote, aws, quote, connect, quote, quote, endSecret)), + Regex: MustCompile(fmt.Sprintf(`(?i)%s%s%s(sec(ret)?)?_?(access)?_?key%s%s%s(?P[A-Za-z0-9\/\+=]{40})%s%s`, startSecret, quote, aws, quote, connect, quote, quote, endSecret)), SecretGroupName: "secret", Keywords: []string{"key"}, }, diff --git a/pkg/fanal/secret/scanner_test.go b/pkg/fanal/secret/scanner_test.go index 4cde82f2aee1..659b1f91a179 100644 --- a/pkg/fanal/secret/scanner_test.go +++ b/pkg/fanal/secret/scanner_test.go @@ -401,6 +401,37 @@ func TestSecretScanner(t *testing.T) { }, }, } + wantFinding10 := types.SecretFinding{ + RuleID: "aws-secret-access-key", + Category: secret.CategoryAWS, + Title: "AWS Secret Access Key", + Severity: "CRITICAL", + StartLine: 5, + EndLine: 5, + Match: `aws_sec_key "****************************************"`, + Code: types.Code{ + Lines: []types.Line{ + { + Number: 3, + Content: "\"aws_account_ID\":'1234-5678-9123'", + Highlighted: "\"aws_account_ID\":'1234-5678-9123'", + }, + { + Number: 4, + Content: "AWS_example=AKIAIOSFODNN7EXAMPLE", + Highlighted: "AWS_example=AKIAIOSFODNN7EXAMPLE", + }, + { + Number: 5, + Content: "aws_sec_key \"****************************************\"", + Highlighted: "aws_sec_key \"****************************************\"", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + }, + }, + } wantFindingAsymmetricPrivateKeyJson := types.SecretFinding{ RuleID: "private-key", Category: secret.CategoryAsymmetricPrivateKey, @@ -548,7 +579,7 @@ func TestSecretScanner(t *testing.T) { inputFilePath: filepath.Join("testdata", "aws-secrets.txt"), want: types.Secret{ FilePath: filepath.Join("testdata", "aws-secrets.txt"), - Findings: []types.SecretFinding{wantFinding5, wantFinding9}, + Findings: []types.SecretFinding{wantFinding5, wantFinding9, wantFinding10}, }, }, { diff --git a/pkg/fanal/secret/testdata/aws-secrets.txt b/pkg/fanal/secret/testdata/aws-secrets.txt index c0f387ecb8ce..7739ce9bfb79 100644 --- a/pkg/fanal/secret/testdata/aws-secrets.txt +++ b/pkg/fanal/secret/testdata/aws-secrets.txt @@ -1,4 +1,5 @@ 'AWS_secret_KEY'="12ASD34qwe56CXZ78tyH10Tna543VBokN85RHCas" AWS_ACCESS_KEY_ID=AKIA0123456789ABCDEF "aws_account_ID":'1234-5678-9123' -AWS_example=AKIAIOSFODNN7EXAMPLE \ No newline at end of file +AWS_example=AKIAIOSFODNN7EXAMPLE +aws_sec_key "KEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYK" \ No newline at end of file From ed9d34030d6c0f392a6061fd3295da2dcfacdfd2 Mon Sep 17 00:00:00 2001 From: Kyle Davies <98526301+kderck@users.noreply.github.com> Date: Mon, 27 Nov 2023 01:29:22 +0000 Subject: [PATCH 012/108] docs: terraform tutorial links updated to point to correct loc (#5661) --- docs/tutorials/misconfiguration/terraform.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/misconfiguration/terraform.md b/docs/tutorials/misconfiguration/terraform.md index 49d5156a191e..53ad9ec9e755 100644 --- a/docs/tutorials/misconfiguration/terraform.md +++ b/docs/tutorials/misconfiguration/terraform.md @@ -9,7 +9,7 @@ We have been consolidating all of our scanning-related efforts in one place, and ## Trivy Config Command -Terraform configuration scanning is available as part of the `trivy config` command. This command scans all configuration files for misconfiguration issues. You can find the details within [misconfiguration scans in the Trivy documentation.](https://aquasecurity.github.io/trivy/latest/docs/misconfiguration/scanning/) +Terraform configuration scanning is available as part of the `trivy config` command. This command scans all configuration files for misconfiguration issues. You can find the details within [misconfiguration scans in the Trivy documentation.](https://aquasecurity.github.io/trivy/latest/docs/scanner/misconfiguration/) Command structure: ``` @@ -83,14 +83,14 @@ trivy config --severity CRITICAL, MEDIUM terraform-infra ### Passing tf.tfvars files into `trivy config` scans -You can pass terraform values to Trivy to override default values found in the Terraform HCL code. More information are provided [in the documentation.](https://aquasecurity.github.io/trivy/latest/docs/misconfiguration/options/values/) +You can pass terraform values to Trivy to override default values found in the Terraform HCL code. More information are provided [in the documentation.](https://aquasecurity.github.io/trivy/latest/docs/coverage/iac/terraform/#value-overrides) ``` trivy conf --tf-vars terraform.tfvars ./ ``` ### Custom Checks -We have lots of examples in the [documentation](https://aquasecurity.github.io/trivy/latest/docs/misconfiguration/custom/) on how you can write and pass custom Rego policies into terraform misconfiguration scans. +We have lots of examples in the [documentation](https://aquasecurity.github.io/trivy/latest/docs/scanner/misconfiguration/custom/) on how you can write and pass custom Rego policies into terraform misconfiguration scans. ## Secret and vulnerability scans From edad5f69020b8c6c16d82d151ec8019e5d95fd13 Mon Sep 17 00:00:00 2001 From: Anais Urlichs <33576047+AnaisUrlichs@users.noreply.github.com> Date: Mon, 27 Nov 2023 01:29:32 +0000 Subject: [PATCH 013/108] docs: update adopters discussion template (#5632) Signed-off-by: AnaisUrlichs --- .github/DISCUSSION_TEMPLATE/adopters.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/DISCUSSION_TEMPLATE/adopters.yml b/.github/DISCUSSION_TEMPLATE/adopters.yml index c9eff61a98e6..03008a4df4f0 100644 --- a/.github/DISCUSSION_TEMPLATE/adopters.yml +++ b/.github/DISCUSSION_TEMPLATE/adopters.yml @@ -7,6 +7,12 @@ body: label: "[Optional] How do you use Trivy?" validations: required: false + - type: textarea + id: info + attributes: + label: "[Optional] Can you provide us with a quote on your favourite part of Trivy? This may be used on the trivy.dev website, posted on Twitter (@AquaTrivy) or similar marketing material." + validations: + required: false - type: checkboxes attributes: label: "[Optional] Which targets are you scanning with Trivy?" @@ -29,3 +35,13 @@ body: - label: "IaC issues and misconfigurations" - label: "Sensitive information and secrets" - label: "Software licenses" + - type: markdown + attributes: + value: | + ## Get in touch + We are always looking for + * User feedback + * Collaboration with other companies and organisations + * Or just to have a chat with you about trivy. + If any of this interests you or your marketing team, please reach out at: oss@aquasec.com + We would love to hear from you! From 372efc9ec786b05010a255320bf2f94e21af00b5 Mon Sep 17 00:00:00 2001 From: simar7 <1254783+simar7@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:47:23 -0700 Subject: [PATCH 014/108] chore(deps): Bump up trivy misconf deps (#5656) --- go.mod | 8 +- go.sum | 16 +- .../fixtures/repo/helm/testchart.tar.gz | Bin 3780 -> 419 bytes integration/testdata/helm.json.golden | 808 ++++++++++++++---- 4 files changed, 664 insertions(+), 168 deletions(-) diff --git a/go.mod b/go.mod index b31d0f1b5744..97cac16fe685 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NYTimes/gziphandler v1.1.1 github.com/alicebob/miniredis/v2 v2.30.4 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 - github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898 + github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 @@ -23,12 +23,12 @@ require ( github.com/aquasecurity/table v1.8.0 github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da github.com/aquasecurity/tml v0.6.1 - github.com/aquasecurity/trivy-aws v0.4.0 + github.com/aquasecurity/trivy-aws v0.5.0 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d - github.com/aquasecurity/trivy-iac v0.5.2 + github.com/aquasecurity/trivy-iac v0.7.0 github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163 - github.com/aquasecurity/trivy-policies v0.5.0 + github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.22.1 github.com/aws/aws-sdk-go-v2/config v1.18.45 github.com/aws/aws-sdk-go-v2/credentials v1.13.43 diff --git a/go.sum b/go.sum index 0bd9e6aceb22..f914d8ebadfe 100644 --- a/go.sum +++ b/go.sum @@ -320,8 +320,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= -github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898 h1:gu7XQvv2CswgzOdOFHg/AmtR4vBonG35XvGxHHvcIr4= -github.com/aquasecurity/defsec v0.93.2-0.20231024055158-015ab97ce898/go.mod h1:J30VViSgmoW2Ic/6aqVJO2qvuADsmZ3MYuNxPcU6Vt0= +github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 h1:w/Sm2fVtb0Rv1bcLLwsW9j37mNUya8MwzKMcjG9OW/Q= +github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8/go.mod h1:J30VViSgmoW2Ic/6aqVJO2qvuADsmZ3MYuNxPcU6Vt0= github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf h1:kweQrNMfarPfjZGI1537GtuujhpzhsuT/MvmW2FwaBE= github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= @@ -342,18 +342,18 @@ github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da h1:pj/adfN github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da/go.mod h1:852lbQLpK2nCwlR4ZLYIccxYCfoQao6q9Nl6tjz54v8= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= -github.com/aquasecurity/trivy-aws v0.4.0 h1:vrpL9Gx3+33D8TvRCDFJxEIHR3AA+TcnTr0rzRI62OI= -github.com/aquasecurity/trivy-aws v0.4.0/go.mod h1:dPx0xRElmFrVXBxeYqEAl5NejJ2kHb51ybFPzBMxWow= +github.com/aquasecurity/trivy-aws v0.5.0 h1:6RJrw+QHeVn2MH7bI7bsVIiqRyhDCPvdEqkNn54Ui4I= +github.com/aquasecurity/trivy-aws v0.5.0/go.mod h1:dPx0xRElmFrVXBxeYqEAl5NejJ2kHb51ybFPzBMxWow= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= -github.com/aquasecurity/trivy-iac v0.5.2 h1:cqeSDEfQtM3l4ceiQ+IUD2K/ZBhyz443xe+S2TkBdE0= -github.com/aquasecurity/trivy-iac v0.5.2/go.mod h1:dHoaIzm4niotuaEiSM40HelhcL8m/2MHzT3uHcQYUh8= +github.com/aquasecurity/trivy-iac v0.7.0 h1:L2/mqQJD1iwY4xOr1un5Prg51epYBQgM34JVZtkp4Gg= +github.com/aquasecurity/trivy-iac v0.7.0/go.mod h1:GG9Y2YylH3e16PoJ0RUZ+C0Xw93Gic/5fwdkKjKwwqU= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163 h1:6TsI0lQN7H/d3pM5vK1/taYbWMgnNYEOk+V2ydBdg0s= github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163/go.mod h1:u+rEg3lTLpv3EJVSC7HOhWWlUwuuxlfczMncYPMqTPI= -github.com/aquasecurity/trivy-policies v0.5.0 h1:7GukJhiEQpKg8VQH3PkwZOyFqO0J6hGmUbt7jne5mhU= -github.com/aquasecurity/trivy-policies v0.5.0/go.mod h1:YPefENNCAcbPxMDgKBWxjLmhyzYnlAY/HIH89VFaogY= +github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= +github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842/go.mod h1:BmEeSFgmBjo3avCli71736sy0veGcSUzGATupp1MCgA= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= diff --git a/integration/testdata/fixtures/repo/helm/testchart.tar.gz b/integration/testdata/fixtures/repo/helm/testchart.tar.gz index 38ec18cf0a8b5b04498cfff8a9b6e567ff6dc7ce..e36b2b474f3e54d8048b61ca6f9bc5a47afda833 100644 GIT binary patch literal 419 zcmV;U0bKqciwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PK{_Zq+alg}wGu%nKyfPTUrGhhTvO3s&r>$p9`&G!Bo=J7p^-@)s zkljt!GY}WAbVMk$-%HJm$+F|Mz&mDjD{Bjq8PSmwR=@QJL0 zd1T;wNbvdLmXfDJnR|4kVHqf1rbrqvMr#JF(fqt*7OiXr|KF`2FveE@7jn^Jp?r#A zyzD*jC;wk{YUh8YRCoCQU$FH*#+XlM$$uC>YWPUehRKmH+)=?13u+GV=yHE&{Lf~5 zmH=41C7Y`RYNjU*&yj|@nP|QUvWA`mWU@4rkRIg@%W(f?6aOLuz%rXp>P9Surk1T#ZMS}lA(hQ(&2!SPAr%epUd_KhI5>FQ{0aa7 N|NoRUvhx58002m6!sGw| literal 3780 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 diff --git a/integration/testdata/helm.json.golden b/integration/testdata/helm.json.golden index 037d02a8c26a..5899f2a52bc4 100644 --- a/integration/testdata/helm.json.golden +++ b/integration/testdata/helm.json.golden @@ -17,12 +17,12 @@ }, "Results": [ { - "Target": "testchart.tar.gz:templates/deployment.yaml", + "Target": "testchart.tar.gz:templates/pod.yaml", "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 151, - "Failures": 5, + "Successes": 141, + "Failures": 15, "Exceptions": 0 }, "Misconfigurations": [ @@ -32,7 +32,7 @@ "AVDID": "AVD-KSV-0001", "Title": "Can elevate its own privileges", "Description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.", - "Message": "Container 'testchart' of Deployment 'testchart' should set 'securityContext.allowPrivilegeEscalation' to false", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.allowPrivilegeEscalation' to false", "Namespace": "builtin.kubernetes.KSV001", "Query": "data.builtin.kubernetes.KSV001.deny", "Resolution": "Set 'set containers[].securityContext.allowPrivilegeEscalation' to 'false'.", @@ -47,108 +47,256 @@ "CauseMetadata": { "Provider": "Kubernetes", "Service": "general", - "StartLine": 28, - "EndLine": 57, + "StartLine": 19, + "EndLine": 22, "Code": { "Lines": [ { - "Number": 28, - "Content": " - name: testchart", + "Number": 19, + "Content": " - name: nginx", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " - \u001b[38;5;33mname\u001b[0m: testchart", + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", "FirstCause": true, "LastCause": false }, { - "Number": 29, - "Content": " securityContext:", + "Number": 20, + "Content": " image: nginx:1.14.2", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33msecurityContext\u001b[0m:", + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false }, { - "Number": 30, - "Content": " capabilities:", + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mcapabilities\u001b[0m:", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 31, - "Content": " drop:", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mdrop\u001b[0m:", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV003", + "AVDID": "AVD-KSV-0003", + "Title": "Default capabilities: some containers do not drop all", + "Description": "The container should drop all default capabilities and add only those that are needed for its execution.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should add 'ALL' to 'securityContext.capabilities.drop'", + "Namespace": "builtin.kubernetes.KSV003", + "Query": "data.builtin.kubernetes.KSV003.deny", + "Resolution": "Add 'ALL' to containers[].securityContext.capabilities.drop.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv003", + "References": [ + "https://kubesec.io/basics/containers-securitycontext-capabilities-drop-index-all/", + "https://avd.aquasec.com/misconfig/ksv003" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false }, { - "Number": 32, - "Content": " - ALL", + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " - ALL", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 33, - "Content": " readOnlyRootFilesystem: true", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mreadOnlyRootFilesystem\u001b[0m: \u001b[38;5;166mtrue", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", "FirstCause": false, + "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV011", + "AVDID": "AVD-KSV-0011", + "Title": "CPU not limited", + "Description": "Enforcing CPU limits prevents DoS via resource exhaustion.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.limits.cpu'", + "Namespace": "builtin.kubernetes.KSV011", + "Query": "data.builtin.kubernetes.KSV011.deny", + "Resolution": "Set a limit value under 'containers[].resources.limits.cpu'.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv011", + "References": [ + "https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits", + "https://avd.aquasec.com/misconfig/ksv011" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, "LastCause": false }, { - "Number": 34, - "Content": " runAsGroup: 10001", + "Number": 20, + "Content": " image: nginx:1.14.2", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsGroup\u001b[0m: \u001b[38;5;37m10001", + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false }, { - "Number": 35, - "Content": " runAsNonRoot: true", + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsNonRoot\u001b[0m: \u001b[38;5;166mtrue", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 36, - "Content": " runAsUser: 10001", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsUser\u001b[0m: \u001b[38;5;37m10001", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", "FirstCause": false, "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV012", + "AVDID": "AVD-KSV-0012", + "Title": "Runs as root user", + "Description": "Force the running image to run as a non-root user to ensure least privileges.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsNonRoot' to true", + "Namespace": "builtin.kubernetes.KSV012", + "Query": "data.builtin.kubernetes.KSV012.deny", + "Resolution": "Set 'containers[].securityContext.runAsNonRoot' to true.", + "Severity": "MEDIUM", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv012", + "References": [ + "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted", + "https://avd.aquasec.com/misconfig/ksv012" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false }, { - "Number": 37, - "Content": "", - "IsCause": false, + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, "Annotation": "", - "Truncated": true, + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true } ] } @@ -156,127 +304,275 @@ }, { "Type": "Helm Security Check", - "ID": "KSV030", - "AVDID": "AVD-KSV-0030", - "Title": "Runtime/Default Seccomp profile not set", - "Description": "According to pod security standard 'Seccomp', the RuntimeDefault seccomp profile must be required, or allow specific additional profiles.", - "Message": "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'", - "Namespace": "builtin.kubernetes.KSV030", - "Query": "data.builtin.kubernetes.KSV030.deny", - "Resolution": "Set 'spec.securityContext.seccompProfile.type', 'spec.containers[*].securityContext.seccompProfile' and 'spec.initContainers[*].securityContext.seccompProfile' to 'RuntimeDefault' or undefined.", + "ID": "KSV014", + "AVDID": "AVD-KSV-0014", + "Title": "Root file system is not read-only", + "Description": "An immutable root file system prevents applications from writing to their local disk. This can limit intrusions, as attackers will not be able to tamper with the file system or write foreign executables to disk.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.readOnlyRootFilesystem' to true", + "Namespace": "builtin.kubernetes.KSV014", + "Query": "data.builtin.kubernetes.KSV014.deny", + "Resolution": "Change 'containers[].securityContext.readOnlyRootFilesystem' to 'true'.", "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv030", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv014", "References": [ - "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted", - "https://avd.aquasec.com/misconfig/ksv030" + "https://kubesec.io/basics/containers-securitycontext-readonlyrootfilesystem-true/", + "https://avd.aquasec.com/misconfig/ksv014" ], "Status": "FAIL", "Layer": {}, "CauseMetadata": { "Provider": "Kubernetes", "Service": "general", - "StartLine": 28, - "EndLine": 57, + "StartLine": 19, + "EndLine": 22, "Code": { "Lines": [ { - "Number": 28, - "Content": " - name: testchart", + "Number": 19, + "Content": " - name: nginx", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " - \u001b[38;5;33mname\u001b[0m: testchart", + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", "FirstCause": true, "LastCause": false }, { - "Number": 29, - "Content": " securityContext:", + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33msecurityContext\u001b[0m:", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 30, - "Content": " capabilities:", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mcapabilities\u001b[0m:", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", "FirstCause": false, + "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV015", + "AVDID": "AVD-KSV-0015", + "Title": "CPU requests not specified", + "Description": "When containers have resource requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.requests.cpu'", + "Namespace": "builtin.kubernetes.KSV015", + "Query": "data.builtin.kubernetes.KSV015.deny", + "Resolution": "Set 'containers[].resources.requests.cpu'.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv015", + "References": [ + "https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits", + "https://avd.aquasec.com/misconfig/ksv015" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, "LastCause": false }, { - "Number": 31, - "Content": " drop:", + "Number": 20, + "Content": " image: nginx:1.14.2", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mdrop\u001b[0m:", + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false }, { - "Number": 32, - "Content": " - ALL", + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " - ALL", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 33, - "Content": " readOnlyRootFilesystem: true", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": " \u001b[38;5;33mreadOnlyRootFilesystem\u001b[0m: \u001b[38;5;166mtrue", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", "FirstCause": false, + "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV016", + "AVDID": "AVD-KSV-0016", + "Title": "Memory requests not specified", + "Description": "When containers have memory requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.requests.memory'", + "Namespace": "builtin.kubernetes.KSV016", + "Query": "data.builtin.kubernetes.KSV016.deny", + "Resolution": "Set 'containers[].resources.requests.memory'.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv016", + "References": [ + "https://kubesec.io/basics/containers-resources-limits-memory/", + "https://avd.aquasec.com/misconfig/ksv016" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, "LastCause": false }, { - "Number": 34, - "Content": " runAsGroup: 10001", + "Number": 20, + "Content": " image: nginx:1.14.2", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsGroup\u001b[0m: \u001b[38;5;37m10001", + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", "FirstCause": false, "LastCause": false }, { - "Number": 35, - "Content": " runAsNonRoot: true", + "Number": 21, + "Content": " ports:", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsNonRoot\u001b[0m: \u001b[38;5;166mtrue", + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false }, { - "Number": 36, - "Content": " runAsUser: 10001", + "Number": 22, + "Content": " - containerPort: 80", "IsCause": true, "Annotation": "", "Truncated": false, - "Highlighted": "\u001b[0m \u001b[38;5;33mrunAsUser\u001b[0m: \u001b[38;5;37m10001", + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", "FirstCause": false, "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV018", + "AVDID": "AVD-KSV-0018", + "Title": "Memory not limited", + "Description": "Enforcing memory limits prevents DoS via resource exhaustion.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'resources.limits.memory'", + "Namespace": "builtin.kubernetes.KSV018", + "Query": "data.builtin.kubernetes.KSV018.deny", + "Resolution": "Set a limit value under 'containers[].resources.limits.memory'.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv018", + "References": [ + "https://kubesec.io/basics/containers-resources-limits-memory/", + "https://avd.aquasec.com/misconfig/ksv018" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false }, { - "Number": 37, - "Content": "", - "IsCause": false, + "Number": 21, + "Content": " ports:", + "IsCause": true, "Annotation": "", - "Truncated": true, + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", "FirstCause": false, "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true } ] } @@ -284,71 +580,226 @@ }, { "Type": "Helm Security Check", - "ID": "KSV104", - "AVDID": "AVD-KSV-0104", - "Title": "Seccomp policies disabled", - "Description": "A program inside the container can bypass Seccomp protection policies.", - "Message": "container testchart of deployment testchart in default namespace should specify a seccomp profile", - "Namespace": "builtin.kubernetes.KSV104", - "Query": "data.builtin.kubernetes.KSV104.deny", - "Resolution": "Specify seccomp either by annotation or by seccomp profile type having allowed values as per pod security standards", - "Severity": "MEDIUM", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv104", + "ID": "KSV020", + "AVDID": "AVD-KSV-0020", + "Title": "Runs with UID \u003c= 10000", + "Description": "Force the container to run with user ID \u003e 10000 to avoid conflicts with the host’s user table.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsUser' \u003e 10000", + "Namespace": "builtin.kubernetes.KSV020", + "Query": "data.builtin.kubernetes.KSV020.deny", + "Resolution": "Set 'containers[].securityContext.runAsUser' to an integer \u003e 10000.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv020", "References": [ - "https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline", - "https://avd.aquasec.com/misconfig/ksv104" + "https://kubesec.io/basics/containers-securitycontext-runasuser/", + "https://avd.aquasec.com/misconfig/ksv020" ], "Status": "FAIL", "Layer": {}, "CauseMetadata": { "Provider": "Kubernetes", "Service": "general", + "StartLine": 19, + "EndLine": 22, "Code": { - "Lines": null + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true + } + ] } } }, { "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "deployment testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", + "ID": "KSV021", + "AVDID": "AVD-KSV-0021", + "Title": "Runs with GID \u003c= 10000", + "Description": "Force the container to run with group ID \u003e 10000 to avoid conflicts with the host’s user table.", + "Message": "Container 'nginx' of Deployment 'nginx-deployment' should set 'securityContext.runAsGroup' \u003e 10000", + "Namespace": "builtin.kubernetes.KSV021", + "Query": "data.builtin.kubernetes.KSV021.deny", + "Resolution": "Set 'containers[].securityContext.runAsGroup' to an integer \u003e 10000.", "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv021", "References": [ "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" + "https://avd.aquasec.com/misconfig/ksv021" ], "Status": "FAIL", "Layer": {}, "CauseMetadata": { "Provider": "Kubernetes", "Service": "general", + "StartLine": 19, + "EndLine": 22, "Code": { - "Lines": null + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true + } + ] } } }, { "Type": "Helm Security Check", - "ID": "KSV117", - "AVDID": "AVD-KSV-0117", - "Title": "Prevent binding to privileged ports", - "Description": "The ports which are lower than 1024 receive and transmit various sensitive and privileged data. Allowing containers to use them can bring serious implications.", - "Message": "deployment testchart in default namespace should not set spec.template.spec.containers.ports.containerPort to less than 1024", - "Namespace": "builtin.kubernetes.KSV117", - "Query": "data.builtin.kubernetes.KSV117.deny", - "Resolution": "Do not map the container ports to privileged host ports when starting a container.", - "Severity": "HIGH", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv117", + "ID": "KSV030", + "AVDID": "AVD-KSV-0030", + "Title": "Runtime/Default Seccomp profile not set", + "Description": "According to pod security standard 'Seccomp', the RuntimeDefault seccomp profile must be required, or allow specific additional profiles.", + "Message": "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'", + "Namespace": "builtin.kubernetes.KSV030", + "Query": "data.builtin.kubernetes.KSV030.deny", + "Resolution": "Set 'spec.securityContext.seccompProfile.type', 'spec.containers[*].securityContext.seccompProfile' and 'spec.initContainers[*].securityContext.seccompProfile' to 'RuntimeDefault' or undefined.", + "Severity": "LOW", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv030", "References": [ - "https://kubernetes.io/docs/concepts/security/pod-security-standards/", - "https://avd.aquasec.com/misconfig/ksv117" + "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted", + "https://avd.aquasec.com/misconfig/ksv030" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "StartLine": 19, + "EndLine": 22, + "Code": { + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true + } + ] + } + } + }, + { + "Type": "Helm Security Check", + "ID": "KSV104", + "AVDID": "AVD-KSV-0104", + "Title": "Seccomp policies disabled", + "Description": "A program inside the container can bypass Seccomp protection policies.", + "Message": "container nginx of deployment nginx-deployment in default namespace should specify a seccomp profile", + "Namespace": "builtin.kubernetes.KSV104", + "Query": "data.builtin.kubernetes.KSV104.deny", + "Resolution": "Specify seccomp either by annotation or by seccomp profile type having allowed values as per pod security standards", + "Severity": "MEDIUM", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv104", + "References": [ + "https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline", + "https://avd.aquasec.com/misconfig/ksv104" ], "Status": "FAIL", "Layer": {}, @@ -359,64 +810,83 @@ "Lines": null } } - } - ] - }, - { - "Target": "testchart.tar.gz:templates/service.yaml", - "Class": "config", - "Type": "helm", - "MisconfSummary": { - "Successes": 155, - "Failures": 1, - "Exceptions": 0 - }, - "Misconfigurations": [ + }, { "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "service testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", + "ID": "KSV106", + "AVDID": "AVD-KSV-0106", + "Title": "Container capabilities must only include NET_BIND_SERVICE", + "Description": "Containers must drop ALL capabilities, and are only permitted to add back the NET_BIND_SERVICE capability.", + "Message": "container should drop all", + "Namespace": "builtin.kubernetes.KSV106", + "Query": "data.builtin.kubernetes.KSV106.deny", + "Resolution": "Set 'spec.containers[*].securityContext.capabilities.drop' to 'ALL' and only add 'NET_BIND_SERVICE' to 'spec.containers[*].securityContext.capabilities.add'.", "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv106", "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" + "https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted", + "https://avd.aquasec.com/misconfig/ksv106" ], "Status": "FAIL", "Layer": {}, "CauseMetadata": { "Provider": "Kubernetes", "Service": "general", + "StartLine": 19, + "EndLine": 22, "Code": { - "Lines": null + "Lines": [ + { + "Number": 19, + "Content": " - name: nginx", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mname\u001b[0m: nginx", + "FirstCause": true, + "LastCause": false + }, + { + "Number": 20, + "Content": " image: nginx:1.14.2", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mimage\u001b[0m: nginx:1.14.2", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 21, + "Content": " ports:", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " \u001b[38;5;33mports\u001b[0m:", + "FirstCause": false, + "LastCause": false + }, + { + "Number": 22, + "Content": " - containerPort: 80", + "IsCause": true, + "Annotation": "", + "Truncated": false, + "Highlighted": " - \u001b[38;5;33mcontainerPort\u001b[0m: \u001b[38;5;37m80\u001b[0m", + "FirstCause": false, + "LastCause": true + } + ] } } - } - ] - }, - { - "Target": "testchart.tar.gz:templates/serviceaccount.yaml", - "Class": "config", - "Type": "helm", - "MisconfSummary": { - "Successes": 155, - "Failures": 1, - "Exceptions": 0 - }, - "Misconfigurations": [ + }, { "Type": "Helm Security Check", "ID": "KSV116", "AVDID": "AVD-KSV-0116", "Title": "Runs with a root primary or supplementary GID", "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "serviceaccount testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", + "Message": "deployment nginx-deployment in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", "Namespace": "builtin.kubernetes.KSV116", "Query": "data.builtin.kubernetes.KSV116.deny", "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", @@ -435,6 +905,32 @@ "Lines": null } } + }, + { + "Type": "Helm Security Check", + "ID": "KSV117", + "AVDID": "AVD-KSV-0117", + "Title": "Prevent binding to privileged ports", + "Description": "The ports which are lower than 1024 receive and transmit various sensitive and privileged data. Allowing containers to use them can bring serious implications.", + "Message": "deployment nginx-deployment in default namespace should not set spec.template.spec.containers.ports.containerPort to less than 1024", + "Namespace": "builtin.kubernetes.KSV117", + "Query": "data.builtin.kubernetes.KSV117.deny", + "Resolution": "Do not map the container ports to privileged host ports when starting a container.", + "Severity": "HIGH", + "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv117", + "References": [ + "https://kubernetes.io/docs/concepts/security/pod-security-standards/", + "https://avd.aquasec.com/misconfig/ksv117" + ], + "Status": "FAIL", + "Layer": {}, + "CauseMetadata": { + "Provider": "Kubernetes", + "Service": "general", + "Code": { + "Lines": null + } + } } ] } From 16b757d180426809bba126690fe73c9472e37dcb Mon Sep 17 00:00:00 2001 From: yuriShafet <5830215+yuriShafet@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:23:47 -0500 Subject: [PATCH 015/108] feat: Packagesprops support (#5605) Co-authored-by: DmitriyLewen --- docs/docs/coverage/language/dotnet.md | 4 + docs/docs/coverage/language/index.md | 2 + integration/repo_test.go | 9 ++ .../packagesprops/Directory.Packages.props | 8 ++ .../testdata/packagesprops.json.golden | 69 +++++++++ pkg/detector/library/driver.go | 2 +- pkg/fanal/analyzer/all/import.go | 1 + pkg/fanal/analyzer/const.go | 6 +- .../dotnet/packagesprops/packagesprops.go | 49 +++++++ .../packagesprops/packagesprops_test.go | 134 ++++++++++++++++++ .../testdata/Directory.Packages.props | 7 + .../packagesprops/testdata/Packages.props | 9 ++ .../dotnet/packagesprops/testdata/invalid.txt | 1 + pkg/fanal/types/const.go | 57 ++++---- pkg/purl/purl.go | 2 +- pkg/purl/purl_test.go | 16 +++ 16 files changed, 344 insertions(+), 32 deletions(-) create mode 100644 integration/testdata/fixtures/repo/packagesprops/Directory.Packages.props create mode 100644 integration/testdata/packagesprops.json.golden create mode 100644 pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops.go create mode 100644 pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops_test.go create mode 100644 pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Directory.Packages.props create mode 100644 pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Packages.props create mode 100644 pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/invalid.txt diff --git a/docs/docs/coverage/language/dotnet.md b/docs/docs/coverage/language/dotnet.md index c5251b4ab20e..0a05454365e9 100644 --- a/docs/docs/coverage/language/dotnet.md +++ b/docs/docs/coverage/language/dotnet.md @@ -15,6 +15,7 @@ The following table provides an outline of the features Trivy offers. |:---------------:|--------------------|:-----------------------:|:----------------:|:------------------------------------:|:--------:| | .Net Core | *.deps.json | ✓ | Excluded | - | ✓ | | NuGet | packages.config | ✓ | Excluded | - | - | +| NuGet | *Packages.props | - | Excluded | - | - | | NuGet | packages.lock.json | ✓ | Included | ✓ | ✓ | ## *.deps.json @@ -23,6 +24,9 @@ Trivy parses `*.deps.json` files. Trivy currently excludes dev dependencies from ## packages.config Trivy only finds dependency names and versions from `packages.config` files. To build dependency graph, it is better to use `packages.lock.json` files. +## *Packages.props +Trivy parses `*Packages.props` files. Both legacy `Packages.props` and modern `Directory.Packages.props` are supported. + ### license detection `packages.config` files don't have information about the licenses used. Trivy uses [*.nuspec][nuspec] files from [global packages folder][global-packages] to detect licenses. diff --git a/docs/docs/coverage/language/index.md b/docs/docs/coverage/language/index.md index 18c3aa1f3909..470250216eea 100644 --- a/docs/docs/coverage/language/index.md +++ b/docs/docs/coverage/language/index.md @@ -34,6 +34,7 @@ On the other hand, when the target is a post-build artifact, like a container im | [.NET](dotnet.md) | packages.lock.json | ✅ | ✅ | ✅ | ✅ | | | packages.config | ✅ | ✅ | ✅ | ✅ | | | .deps.json | ✅ | ✅ | ✅ | ✅ | +| | *Packages.props[^11] | ✅ | ✅ | ✅ | ✅ | | [Java](java.md) | JAR/WAR/PAR/EAR[^4] | ✅ | ✅ | - | - | | | pom.xml | - | - | ✅ | ✅ | | | *gradle.lockfile | - | - | ✅ | ✅ | @@ -65,3 +66,4 @@ Example: [Dockerfile](https://github.com/aquasecurity/trivy-ci-test/blob/main/Do [^8]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning [^9]: ✅ means that Trivy detects line numbers where each dependency is declared in the scanned file. Only supported in [json](../../configuration/reporting.md#json) and [sarif](../../configuration/reporting.md#sarif) formats. SARIF uses `startline == 1 and endline == 1` for unsupported file types [^10]: To scan a filename other than the default filename use [file-patterns](../../configuration/skipping.md#file-patterns) +[^11]: `Directory.Packages.props` and legacy `Packages.props` file names are supported diff --git a/integration/repo_test.go b/integration/repo_test.go index 35aa58ac0784..dbf9c9bcbdab 100644 --- a/integration/repo_test.go +++ b/integration/repo_test.go @@ -186,6 +186,15 @@ func TestRepository(t *testing.T) { }, golden: "testdata/dotnet.json.golden", }, + { + name: "packages-props", + args: args{ + scanner: types.VulnerabilityScanner, + listAllPkgs: true, + input: "testdata/fixtures/repo/packagesprops", + }, + golden: "testdata/packagesprops.json.golden", + }, { name: "swift", args: args{ diff --git a/integration/testdata/fixtures/repo/packagesprops/Directory.Packages.props b/integration/testdata/fixtures/repo/packagesprops/Directory.Packages.props new file mode 100644 index 000000000000..daa6f7ccdc4f --- /dev/null +++ b/integration/testdata/fixtures/repo/packagesprops/Directory.Packages.props @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/integration/testdata/packagesprops.json.golden b/integration/testdata/packagesprops.json.golden new file mode 100644 index 000000000000..132152aaf744 --- /dev/null +++ b/integration/testdata/packagesprops.json.golden @@ -0,0 +1,69 @@ +{ + "SchemaVersion": 2, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", + "ArtifactName": "testdata/fixtures/repo/packagesprops", + "ArtifactType": "repository", + "Metadata": { + "ImageConfig": { + "architecture": "", + "created": "0001-01-01T00:00:00Z", + "os": "", + "rootfs": { + "type": "", + "diff_ids": null + }, + "config": {} + } + }, + "Results": [ + { + "Target": "Directory.Packages.props", + "Class": "lang-pkgs", + "Type": "packages-props", + "Packages": [ + { + "ID": "Newtonsoft.Json@9.0.1", + "Name": "Newtonsoft.Json", + "Version": "9.0.1", + "Layer": {} + } + ], + "Vulnerabilities": [ + { + "VulnerabilityID": "GHSA-5crp-9r3c-p9vr", + "PkgID": "Newtonsoft.Json@9.0.1", + "PkgName": "Newtonsoft.Json", + "InstalledVersion": "9.0.1", + "FixedVersion": "13.0.1", + "Status": "fixed", + "Layer": {}, + "SeveritySource": "ghsa", + "PrimaryURL": "https://github.com/advisories/GHSA-5crp-9r3c-p9vr", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory Nuget", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anuget" + }, + "Title": "Improper Handling of Exceptional Conditions in Newtonsoft.Json", + "Description": "Newtonsoft.Json prior to version 13.0.1 is vulnerable to Insecure Defaults due to improper handling of expressions with high nesting level that lead to StackOverFlow exception or high CPU and RAM usage.", + "Severity": "HIGH", + "CweIDs": [ + "CWE-755" + ], + "CVSS": { + "ghsa": { + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V3Score": 7.5 + } + }, + "References": [ + "https://alephsecurity.com/2018/10/22/StackOverflowException/", + "https://alephsecurity.com/vulns/aleph-2018004" + ], + "PublishedDate": "2022-06-22T15:08:47Z", + "LastModifiedDate": "2022-06-27T18:37:23Z" + } + ] + } + ] +} diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index bea534ba0727..c22d1f7c5ac5 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -43,7 +43,7 @@ func NewDriver(libType ftypes.LangType) (Driver, bool) { case ftypes.Npm, ftypes.Yarn, ftypes.Pnpm, ftypes.NodePkg, ftypes.JavaScript: ecosystem = vulnerability.Npm comparer = npm.Comparer{} - case ftypes.NuGet, ftypes.DotNetCore: + case ftypes.NuGet, ftypes.DotNetCore, ftypes.PackagesProps: ecosystem = vulnerability.NuGet comparer = compare.GenericComparer{} case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg: diff --git a/pkg/fanal/analyzer/all/import.go b/pkg/fanal/analyzer/all/import.go index 743ae833771e..443ebc6bdfb8 100644 --- a/pkg/fanal/analyzer/all/import.go +++ b/pkg/fanal/analyzer/all/import.go @@ -12,6 +12,7 @@ import ( _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dart/pub" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/deps" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget" + _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/packagesprops" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/elixir/mix" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary" _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod" diff --git a/pkg/fanal/analyzer/const.go b/pkg/fanal/analyzer/const.go index 0720dcc78a24..88774ac15cbc 100644 --- a/pkg/fanal/analyzer/const.go +++ b/pkg/fanal/analyzer/const.go @@ -61,8 +61,9 @@ const ( TypePnpm Type = "pnpm" // .NET - TypeNuget Type = "nuget" - TypeDotNetCore Type = "dotnet-core" + TypeNuget Type = "nuget" + TypeDotNetCore Type = "dotnet-core" + TypePackagesProps Type = "packages-props" // Conda TypeCondaPkg Type = "conda-pkg" @@ -171,6 +172,7 @@ var ( TypePnpm, TypeNuget, TypeDotNetCore, + TypePackagesProps, TypeCondaPkg, TypePythonPkg, TypePip, diff --git a/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops.go b/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops.go new file mode 100644 index 000000000000..25cc85b8b416 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops.go @@ -0,0 +1,49 @@ +package packagesprops + +import ( + "context" + "os" + "strings" + + "golang.org/x/xerrors" + + props "github.com/aquasecurity/go-dep-parser/pkg/nuget/packagesprops" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language" + "github.com/aquasecurity/trivy/pkg/fanal/types" +) + +func init() { + analyzer.RegisterAnalyzer(&packagesPropsAnalyzer{}) +} + +const ( + version = 1 + packagesPropsSuffix = "packages.props" // https://github.com/dotnet/roslyn-tools/blob/b4c5220f5dfc4278847b6d38eff91cc1188f8066/src/RoslynInsertionTool/RoslynInsertionTool/CoreXT.cs#L39-L40 +) + +type packagesPropsAnalyzer struct{} + +func (a packagesPropsAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) { + parser := props.NewParser() + res, err := language.Analyze(types.PackagesProps, input.FilePath, input.Content, parser) + if err != nil { + return nil, xerrors.Errorf("*Packages.props dependencies analysis error: %w", err) + } + + return res, nil +} + +func (a packagesPropsAnalyzer) Required(filePath string, _ os.FileInfo) bool { + // There is no information about this in the documentation, + // but NuGet works correctly with lowercase filenames + return strings.HasSuffix(strings.ToLower(filePath), packagesPropsSuffix) +} + +func (a packagesPropsAnalyzer) Type() analyzer.Type { + return analyzer.TypePackagesProps +} + +func (a packagesPropsAnalyzer) Version() int { + return version +} diff --git a/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops_test.go b/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops_test.go new file mode 100644 index 000000000000..0fb12d4ba837 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/packagesprops/packagesprops_test.go @@ -0,0 +1,134 @@ +package packagesprops + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" + "github.com/aquasecurity/trivy/pkg/fanal/types" +) + +func Test_packagesPropsAnalyzer_Analyze(t *testing.T) { + tests := []struct { + name string + inputFile string + want *analyzer.AnalysisResult + wantErr string + }{ + { + name: "happy path packages props", + inputFile: "testdata/Packages.props", + want: &analyzer.AnalysisResult{ + Applications: []types.Application{ + { + Type: types.PackagesProps, + FilePath: "testdata/Packages.props", + Libraries: types.Packages{ + { + ID: "Package1@22.1.4", + Name: "Package1", + Version: "22.1.4", + }, + { + ID: "Package2@2.3.0", + Name: "Package2", + Version: "2.3.0", + }, + }, + }, + }, + }, + }, + { + name: "happy path directory packages props", + inputFile: "testdata/Directory.Packages.props", + want: &analyzer.AnalysisResult{ + Applications: []types.Application{ + { + Type: types.PackagesProps, + FilePath: "testdata/Directory.Packages.props", + Libraries: types.Packages{ + { + ID: "Package1@4.2.1", + Name: "Package1", + Version: "4.2.1", + }, + { + ID: "Package2@8.2.0", + Name: "Package2", + Version: "8.2.0", + }, + }, + }, + }, + }, + }, + { + name: "sad path", + inputFile: "testdata/invalid.txt", + wantErr: "*Packages.props dependencies analysis error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.inputFile) + require.NoError(t, err) + defer f.Close() + + a := packagesPropsAnalyzer{} + ctx := context.Background() + got, err := a.Analyze(ctx, analyzer.AnalysisInput{ + FilePath: tt.inputFile, + Content: f, + }) + + if tt.wantErr != "" { + assert.ErrorContains(t, err, tt.wantErr) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_packagesPropsAnalyzer_Required(t *testing.T) { + tests := []struct { + name string + filePath string + want bool + }{ + { + name: "directory packages props", + filePath: "test/Directory.Packages.props", + want: true, + }, + { + name: "packages props", + filePath: "test/Packages.props", + want: true, + }, + { + name: "packages props lower case", + filePath: "test/packages.props", + want: true, + }, + { + name: "zip", + filePath: "test.zip", + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := packagesPropsAnalyzer{} + got := a.Required(tt.filePath, nil) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Directory.Packages.props b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Directory.Packages.props new file mode 100644 index 000000000000..90adf042fde1 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Directory.Packages.props @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Packages.props b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Packages.props new file mode 100644 index 000000000000..2532bf1b1dc0 --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/Packages.props @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/invalid.txt b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/invalid.txt new file mode 100644 index 000000000000..9daeafb9864c --- /dev/null +++ b/pkg/fanal/analyzer/language/dotnet/packagesprops/testdata/invalid.txt @@ -0,0 +1 @@ +test diff --git a/pkg/fanal/types/const.go b/pkg/fanal/types/const.go index 28e11d55beb9..fca6a6b5d00a 100644 --- a/pkg/fanal/types/const.go +++ b/pkg/fanal/types/const.go @@ -43,34 +43,35 @@ const ( // Programming language dependencies const ( - Bundler LangType = "bundler" - GemSpec LangType = "gemspec" - Cargo LangType = "cargo" - Composer LangType = "composer" - Npm LangType = "npm" - NuGet LangType = "nuget" - DotNetCore LangType = "dotnet-core" - Pip LangType = "pip" - Pipenv LangType = "pipenv" - Poetry LangType = "poetry" - CondaPkg LangType = "conda-pkg" - PythonPkg LangType = "python-pkg" - NodePkg LangType = "node-pkg" - Yarn LangType = "yarn" - Pnpm LangType = "pnpm" - Jar LangType = "jar" - Pom LangType = "pom" - Gradle LangType = "gradle" - GoBinary LangType = "gobinary" - GoModule LangType = "gomod" - JavaScript LangType = "javascript" - RustBinary LangType = "rustbinary" - Conan LangType = "conan" - Cocoapods LangType = "cocoapods" - Swift LangType = "swift" - Pub LangType = "pub" - Hex LangType = "hex" - Bitnami LangType = "bitnami" + Bundler LangType = "bundler" + GemSpec LangType = "gemspec" + Cargo LangType = "cargo" + Composer LangType = "composer" + Npm LangType = "npm" + NuGet LangType = "nuget" + DotNetCore LangType = "dotnet-core" + PackagesProps LangType = "packages-props" + Pip LangType = "pip" + Pipenv LangType = "pipenv" + Poetry LangType = "poetry" + CondaPkg LangType = "conda-pkg" + PythonPkg LangType = "python-pkg" + NodePkg LangType = "node-pkg" + Yarn LangType = "yarn" + Pnpm LangType = "pnpm" + Jar LangType = "jar" + Pom LangType = "pom" + Gradle LangType = "gradle" + GoBinary LangType = "gobinary" + GoModule LangType = "gomod" + JavaScript LangType = "javascript" + RustBinary LangType = "rustbinary" + Conan LangType = "conan" + Cocoapods LangType = "cocoapods" + Swift LangType = "swift" + Pub LangType = "pub" + Hex LangType = "hex" + Bitnami LangType = "bitnami" K8sUpstream LangType = "kubernetes" EKS LangType = "eks" // Amazon Elastic Kubernetes Service diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 947c6eb696be..5c4441bad3bc 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -413,7 +413,7 @@ func purlType(t ftypes.TargetType) string { return packageurl.TypeMaven case ftypes.Bundler, ftypes.GemSpec: return packageurl.TypeGem - case ftypes.NuGet, ftypes.DotNetCore: + case ftypes.NuGet, ftypes.DotNetCore, ftypes.PackagesProps: return packageurl.TypeNuget case ftypes.CondaPkg: return packageurl.TypeConda diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index c6195d003a77..d1fc9ab0d5a4 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -275,6 +275,22 @@ func TestNewPackageURL(t *testing.T) { }, }, }, + { + name: "dotnet Packages.props", + typ: ftypes.PackagesProps, + pkg: ftypes.Package{ + ID: "Newtonsoft.Json@9.0.1", + Name: "Newtonsoft.Json", + Version: "9.0.1", + }, + want: &purl.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNuget, + Name: "Newtonsoft.Json", + Version: "9.0.1", + }, + }, + }, { name: "os package", typ: ftypes.RedHat, From 075d8f62862cb344c7c316b6e317dfe71e0b1908 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Tue, 28 Nov 2023 13:01:54 +0900 Subject: [PATCH 016/108] chore: bump Go to 1.21 (#5662) Signed-off-by: knqyf263 --- .github/workflows/check-go-versions.yaml | 31 ------------ .github/workflows/test.yaml | 2 +- .golangci.yaml | 2 +- Dockerfile.protoc | 2 +- go.mod | 2 +- go.sum | 64 ++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 35 deletions(-) delete mode 100644 .github/workflows/check-go-versions.yaml diff --git a/.github/workflows/check-go-versions.yaml b/.github/workflows/check-go-versions.yaml deleted file mode 100644 index dd975536b09e..000000000000 --- a/.github/workflows/check-go-versions.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Check Go versions of dependencies -on: - pull_request: - paths: - - 'go.mod' - workflow_dispatch: - -jobs: - check-go-versions: - name: Check Go versions of dependencies - runs-on: ubuntu-latest - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v4.1.1 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: stable - - # This workflow is a workaround before the "old stable" version becomes Go 1.21. - # To avoid updating dependencies that require Go 1.21, we use this workflow - # Example of wrong update: - # https://github.com/aquasecurity/trivy/discussions/5323#discussioncomment-7186321 - - name: Check that dependencies doesn't require Go 1.21 - run: | - go mod tidy - if grep -q "go 1.21" go.mod; then - echo "One of new dependencies requires Go '1.21'. Use 'go get go@1.20' to fix this." - exit 1 - fi \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b000f9dace39..055a7ce46324 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: oldstable + go-version-file: go.mod - name: go mod tidy run: | diff --git a/.golangci.yaml b/.golangci.yaml index 40b3a997031a..bc8a0c66b786 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -87,7 +87,7 @@ linters: - gocritic run: - go: '1.20' + go: '1.21' skip-files: - ".*_mock.go$" - ".*_test.go$" diff --git a/Dockerfile.protoc b/Dockerfile.protoc index 69f56a31c530..1ee880f8fa5c 100644 --- a/Dockerfile.protoc +++ b/Dockerfile.protoc @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.20 +FROM --platform=linux/amd64 golang:1.21 # Set environment variable for protoc ENV PROTOC_ZIP=protoc-3.19.4-linux-x86_64.zip diff --git a/go.mod b/go.mod index 97cac16fe685..df4ae1efd7f1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/aquasecurity/trivy -go 1.20 +go 1.21 require ( github.com/Azure/azure-sdk-for-go v68.0.0+incompatible diff --git a/go.sum b/go.sum index f914d8ebadfe..8f7d341932c4 100644 --- a/go.sum +++ b/go.sum @@ -239,6 +239,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBIdfux8gnQ= github.com/CycloneDX/cyclonedx-go v0.7.2/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -311,6 +312,7 @@ github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= @@ -327,6 +329,7 @@ github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8= +github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060/go.mod h1:QAMVTITMGE8AY3qkAIhYCNuQV2tTxzdmt7ZOP0SZwZs= github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 h1:eveqE9ivrt30CJ7dOajOfBavhZ4zPqHcZe/4tKp0alc= github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798/go.mod h1:hxbJZtKlO4P8sZ9nztizR6XLoE33O+BkPmuYQ4ACyz0= github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 h1:vmXNl+HDfqqXgr0uY1UgK1GAhps8nbAAtqHNBcgyf+4= @@ -361,6 +364,7 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -513,10 +517,12 @@ github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvz github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= @@ -526,6 +532,7 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXe github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= +github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= @@ -565,6 +572,7 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= +github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -689,6 +697,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -702,7 +711,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= +github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -711,10 +722,12 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -752,6 +765,7 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= @@ -778,11 +792,15 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= +github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -792,7 +810,9 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4= +github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -800,6 +820,7 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -867,15 +888,19 @@ github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9F github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -894,14 +919,17 @@ github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSC github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= @@ -934,6 +962,7 @@ github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJ github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -973,12 +1002,15 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1013,6 +1045,7 @@ github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIG github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -1029,6 +1062,7 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg= github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -1066,6 +1100,7 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -1086,6 +1121,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -1104,6 +1140,7 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= +github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= @@ -1119,6 +1156,7 @@ github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.6 h1:3xi/Cafd1NaoEnS/yDssIiuVeDVywU0QdFGl3aQaQHM= github.com/hashicorp/golang-lru/v2 v2.0.6/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -1174,6 +1212,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -1209,6 +1248,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -1222,6 +1262,7 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/liamg/iamgo v0.0.9 h1:tADGm3xVotyRJmuKKaH4+zsBn7LOcvgdpuF3WsSKW3c= github.com/liamg/iamgo v0.0.9/go.mod h1:Kk6ZxBF/GQqG9nnaUjIi6jf+WXNpeOTyhwc6gnguaZQ= github.com/liamg/jfather v0.0.7 h1:Xf78zS263yfT+xr2VSo6+kyAy4ROlCacRqJG7s5jt4k= @@ -1248,8 +1289,10 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -1289,6 +1332,7 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -1369,6 +1413,7 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -1382,13 +1427,16 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/open-policy-agent/opa v0.57.0 h1:DftxYfOEHOheXvO2Q6HCIM2ZVdKrvnF4cZlU9C64MIQ= github.com/open-policy-agent/opa v0.57.0/go.mod h1:3FY6GNSbUqOhjCdvTXCBJ2rNuh66p/XrIc2owr/hSwo= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1443,6 +1491,7 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= @@ -1458,6 +1507,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= +github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1511,6 +1561,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1622,6 +1673,7 @@ github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo= +github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw= github.com/testcontainers/testcontainers-go v0.23.0 h1:ERYTSikX01QczBLPZpqsETTBO7lInqEP349phDOVJVs= github.com/testcontainers/testcontainers-go v0.23.0/go.mod h1:3gzuZfb7T9qfcH2pHpV4RLlWrPjeWNQah6XlYQ32c4I= github.com/testcontainers/testcontainers-go/modules/localstack v0.26.0 h1:lpL04dHA9mGFBQLFcV+aEEh1Tf4ohXdIGgoj3J0bacM= @@ -1630,6 +1682,7 @@ github.com/tetratelabs/wazero v1.2.1 h1:J4X2hrGzJvt+wqltuvcSjHQ7ujQxA9gb6PeMs4ql github.com/tetratelabs/wazero v1.2.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twitchtv/twirp v8.1.2+incompatible h1:0O6TfzZW09ZP5r+ORA90XQEE3PTgA6C7MBbl2KxvVgE= @@ -1722,11 +1775,15 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= @@ -1735,12 +1792,14 @@ go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZE go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -2460,6 +2519,7 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= helm.sh/helm/v3 v3.13.0 h1:XPJKIU30K4JTQ6VX/6e0hFAmEIonYa8E7wx5aqv4xOc= helm.sh/helm/v3 v3.13.0/go.mod h1:2PBEKsMWKLVZTojUOqMS3Eadv5mP43FBWrRgLNkNm9Y= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2523,7 +2583,9 @@ modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= @@ -2537,9 +2599,11 @@ modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= +modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= +modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af h1:FX1C64cT+tNHJpuaHqbu48DEUp8gqtu6eBXtoP7CPyM= oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af/go.mod h1:++wPJC5xFFsYYfzn2+q/LsbLVQZDwg/CrR3mcLFn40w= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= From b5874e3ad38e77ac86eedd7a65785b2933f3685f Mon Sep 17 00:00:00 2001 From: simar7 <1254783+simar7@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:59:17 -0700 Subject: [PATCH 017/108] feat(misconf): Add `--misconfig-scanners` option (#5670) --- .../references/configuration/cli/trivy_aws.md | 1 + .../configuration/cli/trivy_config.md | 1 + .../configuration/cli/trivy_filesystem.md | 1 + .../configuration/cli/trivy_image.md | 1 + .../configuration/cli/trivy_kubernetes.md | 1 + .../configuration/cli/trivy_repository.md | 1 + .../configuration/cli/trivy_rootfs.md | 1 + .../references/configuration/cli/trivy_vm.md | 1 + .../references/configuration/config-file.md | 6 ++++++ docs/docs/scanner/misconfiguration/index.md | 9 +++++++++ pkg/commands/artifact/run.go | 19 +++++++++++++++++++ pkg/flag/misconf_flags.go | 13 +++++++++++++ 12 files changed, 55 insertions(+) diff --git a/docs/docs/references/configuration/cli/trivy_aws.md b/docs/docs/references/configuration/cli/trivy_aws.md index 590162972b39..46a8296dbb80 100644 --- a/docs/docs/references/configuration/cli/trivy_aws.md +++ b/docs/docs/references/configuration/cli/trivy_aws.md @@ -86,6 +86,7 @@ trivy aws [flags] --include-non-failures include successes and exceptions, available with '--scanners misconfig' --list-all-pkgs enabling the option will output all packages regardless of vulnerability --max-cache-age duration The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this. (default 24h0m0s) + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) -o, --output string output file name --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") --policy-namespaces strings Rego namespaces diff --git a/docs/docs/references/configuration/cli/trivy_config.md b/docs/docs/references/configuration/cli/trivy_config.md index 0d26452a10b1..19a8983c1784 100644 --- a/docs/docs/references/configuration/cli/trivy_config.md +++ b/docs/docs/references/configuration/cli/trivy_config.md @@ -29,6 +29,7 @@ trivy config [flags] DIR --ignorefile string specify .trivyignore file (default ".trivyignore") --include-non-failures include successes and exceptions, available with '--scanners misconfig' --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") -o, --output string output file name --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index 89d034caaa4d..ccc12a1475a8 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -51,6 +51,7 @@ trivy filesystem [flags] PATH --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index 10ac0518944b..27264628eac0 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -69,6 +69,7 @@ trivy image [flags] IMAGE_NAME --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 93d44ad04c3e..5ba76eb26d7d 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -60,6 +60,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0) --kubeconfig string specify the kubeconfig file path to use --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) -n, --namespace string specify a namespace to scan --no-progress suppress progress bar --node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp") diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index a88e9be5bf30..339064883224 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -51,6 +51,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL) --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index d04ee44ba113..5d5f88451afd 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -53,6 +53,7 @@ trivy rootfs [flags] ROOTDIR --license-confidence-level float specify license classifier's confidence level (default 0.9) --license-full eagerly look for licenses in source code headers and license files --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index eb6506c7585d..0fc813ade0ca 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -47,6 +47,7 @@ trivy vm [flags] VM_IMAGE --include-non-failures include successes and exceptions, available with '--scanners misconfig' --java-db-repository string OCI repository to retrieve trivy-java-db from (default "ghcr.io/aquasecurity/trivy-java-db") --list-all-pkgs enabling the option will output all packages regardless of vulnerability + --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies diff --git a/docs/docs/references/configuration/config-file.md b/docs/docs/references/configuration/config-file.md index b85cfded4667..23b5a3778345 100644 --- a/docs/docs/references/configuration/config-file.md +++ b/docs/docs/references/configuration/config-file.md @@ -266,6 +266,12 @@ misconfiguration: # Same as '--include-non-failures' # Default is false include-non-failures: false + + # Same as '--miconfig-scanners' + # Default is all scanners + scanners: + - dockerfile + - terraform # helm value override configurations # set individual values diff --git a/docs/docs/scanner/misconfiguration/index.md b/docs/docs/scanner/misconfiguration/index.md index 8a2606a31a4e..23c883a70ab1 100644 --- a/docs/docs/scanner/misconfiguration/index.md +++ b/docs/docs/scanner/misconfiguration/index.md @@ -315,6 +315,15 @@ Failures: 2 (MEDIUM: 2, HIGH: 0, CRITICAL: 0) This section describes misconfiguration-specific configuration. Other common options are documented [here](../../configuration/index.md). +### Enabling a subset of misconfiguration scanners +It's possible to only enable certain misconfiguration scanners if you prefer. You can do so by passing the `--misconfig-scanners` option. +This flag takes a comma-separated list of configuration scanner types. +```bash +trivy config --misconfig-scanners=terraform,dockerfile . +``` + +Will only scan for misconfigurations that pertain to Terraform and Dockerfiles. + ### Pass custom policies You can pass policy files or directories including your custom policies through `--policy` option. This can be repeated for specifying multiple files or directories. diff --git a/pkg/commands/artifact/run.go b/pkg/commands/artifact/run.go index 0d935f86e016..2370cc6c1de9 100644 --- a/pkg/commands/artifact/run.go +++ b/pkg/commands/artifact/run.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/hashicorp/go-multierror" + "github.com/samber/lo" "github.com/spf13/viper" "golang.org/x/exp/slices" "golang.org/x/xerrors" @@ -480,6 +481,14 @@ func disabledAnalyzers(opts flag.Options) []analyzer.Type { analyzers = append(analyzers, analyzer.TypeSecret) } + // Filter only enabled misconfiguration scanners + ma, err := filterMisconfigAnalyzers(opts.MisconfigScanners, analyzer.TypeConfigFiles) + if err != nil { + log.Logger.Errorf("Invalid misconfig scanners specified: %s defaulting to use all misconfig scanners", opts.MisconfigScanners) + } else { + analyzers = append(analyzers, ma...) + } + // Do not perform misconfiguration scanning when it is not specified. if !opts.Scanners.AnyEnabled(types.MisconfigScanner, types.RBACScanner) { analyzers = append(analyzers, analyzer.TypeConfigFiles...) @@ -512,6 +521,16 @@ func disabledAnalyzers(opts flag.Options) []analyzer.Type { return analyzers } +func filterMisconfigAnalyzers(included, all []analyzer.Type) ([]analyzer.Type, error) { + _, missing := lo.Difference(all, included) + if len(missing) > 0 { + return nil, xerrors.Errorf("invalid misconfiguration scanner specified %s valid scanners: %s", missing, all) + } + + log.Logger.Debugf("Enabling misconfiguration scanners: %s", included) + return lo.Without(all, included...), nil +} + func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfig, types.ScanOptions, error) { target := opts.Target if opts.Input != "" { diff --git a/pkg/flag/misconf_flags.go b/pkg/flag/misconf_flags.go index 38f8c837fa4a..10db4bb81421 100644 --- a/pkg/flag/misconf_flags.go +++ b/pkg/flag/misconf_flags.go @@ -3,7 +3,9 @@ package flag import ( "fmt" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/policy" + xstrings "github.com/aquasecurity/trivy/pkg/x/strings" ) // e.g. config yaml: @@ -73,6 +75,12 @@ var ( Default: fmt.Sprintf("%s:%d", policy.BundleRepository, policy.BundleVersion), Usage: "OCI registry URL to retrieve policy bundle from", } + MisconfigScannersFlag = Flag{ + Name: "misconfig-scanners", + ConfigName: "misconfiguration.scanners", + Default: xstrings.ToStringSlice(analyzer.TypeConfigFiles), + Usage: "comma-separated list of misconfig scanners to use for misconfiguration scanning", + } ) // MisconfFlagGroup composes common printer flag structs used for commands providing misconfiguration scanning. @@ -89,6 +97,7 @@ type MisconfFlagGroup struct { TerraformTFVars *Flag CloudformationParamVars *Flag TerraformExcludeDownloaded *Flag + MisconfigScanners *Flag } type MisconfOptions struct { @@ -104,6 +113,7 @@ type MisconfOptions struct { TerraformTFVars []string CloudFormationParamVars []string TfExcludeDownloaded bool + MisconfigScanners []analyzer.Type } func NewMisconfFlagGroup() *MisconfFlagGroup { @@ -119,6 +129,7 @@ func NewMisconfFlagGroup() *MisconfFlagGroup { TerraformTFVars: &TfVarsFlag, CloudformationParamVars: &CfParamsFlag, TerraformExcludeDownloaded: &TerraformExcludeDownloaded, + MisconfigScanners: &MisconfigScannersFlag, } } @@ -138,6 +149,7 @@ func (f *MisconfFlagGroup) Flags() []*Flag { f.TerraformTFVars, f.TerraformExcludeDownloaded, f.CloudformationParamVars, + f.MisconfigScanners, } } @@ -153,5 +165,6 @@ func (f *MisconfFlagGroup) ToOptions() (MisconfOptions, error) { TerraformTFVars: getStringSlice(f.TerraformTFVars), CloudFormationParamVars: getStringSlice(f.CloudformationParamVars), TfExcludeDownloaded: getBool(f.TerraformExcludeDownloaded), + MisconfigScanners: getUnderlyingStringSlice[analyzer.Type](f.MisconfigScanners), }, nil } From e018b9c423129beb9e3cfe05d785276218c6763f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 07:37:58 +0400 Subject: [PATCH 018/108] chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/azidentity from 1.3.1 to 1.4.0 (#5706) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index df4ae1efd7f1..3cba284dfa18 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.21 require ( github.com/Azure/azure-sdk-for-go v68.0.0+incompatible - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/BurntSushi/toml v1.3.2 github.com/CycloneDX/cyclonedx-go v0.7.2 github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible diff --git a/go.sum b/go.sum index 8f7d341932c4..843d31500852 100644 --- a/go.sum +++ b/go.sum @@ -199,10 +199,10 @@ github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 h1:LNHhpdK7hzUcx/k1LIcuh5k7k1LGIWLQfCjaneSj7Fc= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1/go.mod h1:uE9zaUfEQT/nbQjVi2IblCG9iaLtZsuYZ8ne+PuQ02M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= From aedbd85d6e3f3fa26ccf47827cfa9aacf1c7c834 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:38:34 +0000 Subject: [PATCH 019/108] chore(deps): bump github.com/alicebob/miniredis/v2 from 2.30.4 to 2.31.0 (#5698) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3cba284dfa18..9dd286ca7a52 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible github.com/Masterminds/sprig/v3 v3.2.3 github.com/NYTimes/gziphandler v1.1.1 - github.com/alicebob/miniredis/v2 v2.30.4 + github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf diff --git a/go.sum b/go.sum index 843d31500852..7bd6acf4a105 100644 --- a/go.sum +++ b/go.sum @@ -240,6 +240,7 @@ github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBId github.com/CycloneDX/cyclonedx-go v0.7.2/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= @@ -307,8 +308,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo= -github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= +github.com/alicebob/miniredis/v2 v2.31.0 h1:ObEFUNlJwoIiyjxdrYF0QIDE7qXcLc7D3WpSH4c22PU= +github.com/alicebob/miniredis/v2 v2.31.0/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= From c0610097a60acc3dcc7717ac25aa98c991b183f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 13:46:51 +0400 Subject: [PATCH 020/108] chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/azcore from 1.7.1 to 1.9.0 (#5702) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9dd286ca7a52..6f0020a482b9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/Azure/azure-sdk-for-go v68.0.0+incompatible - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/BurntSushi/toml v1.3.2 github.com/CycloneDX/cyclonedx-go v0.7.2 @@ -124,7 +124,7 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect diff --git a/go.sum b/go.sum index 7bd6acf4a105..48637a9523cd 100644 --- a/go.sum +++ b/go.sum @@ -199,12 +199,12 @@ github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 h1:d81/ng9rET2YqdVkVwkb6EXeRrLJIwyGnJcAlAWKwhs= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= From 256957523a9b4565f814f7e3f349fb76aeda10a4 Mon Sep 17 00:00:00 2001 From: chenk Date: Mon, 4 Dec 2023 12:25:12 +0200 Subject: [PATCH 021/108] feat: Add flag to configure node-collector image ref (#5710) Signed-off-by: chenk --- .../configuration/cli/trivy_kubernetes.md | 1 + go.mod | 16 ++++----- go.sum | 33 +++++++++---------- pkg/flag/kubernetes_flags.go | 11 +++++++ pkg/k8s/commands/cluster.go | 8 +++-- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 5ba76eb26d7d..35f6fe6a231a 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -63,6 +63,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) -n, --namespace string specify a namespace to scan --no-progress suppress progress bar + --node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.0.9") --node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp") --offline-scan do not issue API requests to identify dependencies -o, --output string output file name diff --git a/go.mod b/go.mod index 6f0020a482b9..257c3c7d9bac 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-iac v0.7.0 github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 - github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163 + github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.22.1 github.com/aws/aws-sdk-go-v2/config v1.18.45 @@ -110,7 +110,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.28.3 + k8s.io/api v0.28.4 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 modernc.org/sqlite v1.23.1 ) @@ -153,7 +153,7 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.46.1 // indirect + github.com/aws/aws-sdk-go v1.48.4 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.1 // indirect @@ -239,7 +239,7 @@ require ( github.com/go-git/go-billy/v5 v5.4.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect @@ -384,12 +384,12 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect helm.sh/helm/v3 v3.13.0 // indirect k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/apimachinery v0.28.3 // indirect + k8s.io/apimachinery v0.28.4 // indirect k8s.io/apiserver v0.28.2 // indirect - k8s.io/cli-runtime v0.28.3 // indirect - k8s.io/client-go v0.28.3 // indirect + k8s.io/cli-runtime v0.28.4 // indirect + k8s.io/client-go v0.28.4 // indirect k8s.io/component-base v0.28.3 // indirect - k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/kubectl v0.28.3 // indirect lukechampine.com/uint128 v1.2.0 // indirect diff --git a/go.sum b/go.sum index 48637a9523cd..65f4207f9e57 100644 --- a/go.sum +++ b/go.sum @@ -354,8 +354,8 @@ github.com/aquasecurity/trivy-iac v0.7.0 h1:L2/mqQJD1iwY4xOr1un5Prg51epYBQgM34JV github.com/aquasecurity/trivy-iac v0.7.0/go.mod h1:GG9Y2YylH3e16PoJ0RUZ+C0Xw93Gic/5fwdkKjKwwqU= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= -github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163 h1:6TsI0lQN7H/d3pM5vK1/taYbWMgnNYEOk+V2ydBdg0s= -github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231115100645-921512b4d163/go.mod h1:u+rEg3lTLpv3EJVSC7HOhWWlUwuuxlfczMncYPMqTPI= +github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 h1:OTJMSbvKQYxbQ2NQ8Nht2NSL1bL36YfBCrlsGGxHPlI= +github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091/go.mod h1:Yh+tmpPtbqVWYONrAuapImHfD1ghZgnZHLlMBA6Ukfg= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842/go.mod h1:BmEeSFgmBjo3avCli71736sy0veGcSUzGATupp1MCgA= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -372,8 +372,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.46.1 h1:U26quvBWFZMQuultLw5tloW4GnmWaChEwMZNq8uYatw= -github.com/aws/aws-sdk-go v1.46.1/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.48.4 h1:HS2L7ynVhkcRrQRro9CLJZ/xLRb4UOzDEfPzgevZwXM= +github.com/aws/aws-sdk-go v1.48.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4= github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= @@ -838,10 +838,9 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= @@ -2533,27 +2532,27 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= -k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= +k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= -k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= +k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI= k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E= -k8s.io/cli-runtime v0.28.3 h1:lvuJYVkwCqHEvpS6KuTZsUVwPePFjBfSGvuaLl2SxzA= -k8s.io/cli-runtime v0.28.3/go.mod h1:jeX37ZPjIcENVuXDDTskG3+FnVuZms5D9omDXS/2Jjc= +k8s.io/cli-runtime v0.28.4 h1:IW3aqSNFXiGDllJF4KVYM90YX4cXPGxuCxCVqCD8X+Q= +k8s.io/cli-runtime v0.28.4/go.mod h1:MLGRB7LWTIYyYR3d/DOgtUC8ihsAPA3P8K8FDNIqJ0k= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= -k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= +k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= +k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= @@ -2566,8 +2565,8 @@ k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index 3bd3ac25d496..5ba74c7de919 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -82,6 +82,12 @@ var ( Default: []string{}, Usage: "indicate the node labels that the node-collector job should exclude from scanning (example: kubernetes.io/arch:arm64,team:dev)", } + NodeCollectorImageRef = Flag{ + Name: "node-collector-imageref", + ConfigName: "node.collector.imageref", + Default: "ghcr.io/aquasecurity/node-collector:0.0.9", + Usage: "indicate the image reference for the node-collector scan job", + } ) type K8sFlagGroup struct { @@ -91,6 +97,7 @@ type K8sFlagGroup struct { Components *Flag K8sVersion *Flag Tolerations *Flag + NodeCollectorImageRef *Flag AllNamespaces *Flag NodeCollectorNamespace *Flag ExcludeOwned *Flag @@ -104,6 +111,7 @@ type K8sOptions struct { Components []string K8sVersion string Tolerations []corev1.Toleration + NodeCollectorImageRef string AllNamespaces bool NodeCollectorNamespace string ExcludeOwned bool @@ -122,6 +130,7 @@ func NewK8sFlagGroup() *K8sFlagGroup { NodeCollectorNamespace: &NodeCollectorNamespace, ExcludeOwned: &ExcludeOwned, ExcludeNodes: &ExcludeNodes, + NodeCollectorImageRef: &NodeCollectorImageRef, } } @@ -141,6 +150,7 @@ func (f *K8sFlagGroup) Flags() []*Flag { f.NodeCollectorNamespace, f.ExcludeOwned, f.ExcludeNodes, + f.NodeCollectorImageRef, } } @@ -171,6 +181,7 @@ func (f *K8sFlagGroup) ToOptions() (K8sOptions, error) { NodeCollectorNamespace: getString(f.NodeCollectorNamespace), ExcludeOwned: getBool(f.ExcludeOwned), ExcludeNodes: exludeNodeLabels, + NodeCollectorImageRef: getString(f.NodeCollectorImageRef), }, nil } diff --git a/pkg/k8s/commands/cluster.go b/pkg/k8s/commands/cluster.go index 1fec319e6449..bf28f26f5d7f 100644 --- a/pkg/k8s/commands/cluster.go +++ b/pkg/k8s/commands/cluster.go @@ -23,13 +23,17 @@ func clusterRun(ctx context.Context, opts flag.Options, cluster k8s.Cluster) err var err error switch opts.Format { case types.FormatCycloneDX: - artifacts, err = trivyk8s.New(cluster, log.Logger).ListBomInfo(ctx) + artifacts, err = trivyk8s.New(cluster, log.Logger).ListClusterBomInfo(ctx) if err != nil { return xerrors.Errorf("get k8s artifacts with node info error: %w", err) } case types.FormatJSON, types.FormatTable: if opts.Scanners.AnyEnabled(types.MisconfigScanner) && slices.Contains(opts.Components, "infra") { - artifacts, err = trivyk8s.New(cluster, log.Logger).ListArtifactAndNodeInfo(ctx, opts.NodeCollectorNamespace, opts.ExcludeNodes, opts.Tolerations...) + artifacts, err = trivyk8s.New(cluster, log.Logger, trivyk8s.WithExcludeOwned(opts.ExcludeOwned)).ListArtifactAndNodeInfo(ctx, + trivyk8s.WithScanJobNamespace(opts.NodeCollectorNamespace), + trivyk8s.WithIgnoreLabels(opts.ExcludeNodes), + trivyk8s.WithScanJobImageRef(opts.NodeCollectorImageRef), + trivyk8s.WithTolerations(opts.Tolerations)) if err != nil { return xerrors.Errorf("get k8s artifacts with node info error: %w", err) } From 654147fc603f9258fff70e0113cdfcd1121c6030 Mon Sep 17 00:00:00 2001 From: Reo Uehara <47747828+uh-zz@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:25:18 +0900 Subject: [PATCH 022/108] docs: typo in modules.md (#5712) --- docs/docs/advanced/modules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/advanced/modules.md b/docs/docs/advanced/modules.md index 71a56a0cdc32..f12d87b8df79 100644 --- a/docs/docs/advanced/modules.md +++ b/docs/docs/advanced/modules.md @@ -328,7 +328,7 @@ Put the built binary to the module directory that is under the home directory by ```bash $ mkdir -p ~/.trivy/modules -$ cp spring4shell.wasm ~/.trivy/modules +$ cp wordpress.wasm ~/.trivy/modules ``` ## Distribute Your Module From 7ee854767ee5748add5a9bf1fe51b52c016c3def Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:28:13 +0400 Subject: [PATCH 023/108] chore(deps): bump easimon/maximize-build-space from 8 to 9 (#5695) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-release.yaml | 2 +- .github/workflows/test.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reusable-release.yaml b/.github/workflows/reusable-release.yaml index 4844ba19ae54..4850a45ad96c 100644 --- a/.github/workflows/reusable-release.yaml +++ b/.github/workflows/reusable-release.yaml @@ -27,7 +27,7 @@ jobs: contents: read # Not required for public repositories, but for clarity steps: - name: Maximize build space - uses: easimon/maximize-build-space@v8 + uses: easimon/maximize-build-space@v9 with: root-reserve-mb: 35840 # The Go cache (`~/.cache/go-build` and `~/go/pkg`) requires a lot of storage space. remove-android: 'true' diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 055a7ce46324..e2552b0d2566 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -89,7 +89,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Maximize build space - uses: easimon/maximize-build-space@v8 + uses: easimon/maximize-build-space@v9 with: root-reserve-mb: 35840 # The Go cache (`~/.cache/go-build` and `~/go/pkg`) requires a lot of storage space. remove-android: "true" @@ -140,7 +140,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Maximize build space - uses: easimon/maximize-build-space@v8 + uses: easimon/maximize-build-space@v9 with: root-reserve-mb: 35840 # The Go cache (`~/.cache/go-build` and `~/go/pkg`) requires a lot of storage space. remove-android: 'true' @@ -173,7 +173,7 @@ jobs: DOCKER_CLI_EXPERIMENTAL: "enabled" steps: - name: Maximize build space - uses: easimon/maximize-build-space@v8 + uses: easimon/maximize-build-space@v9 with: root-reserve-mb: 35840 # The Go cache (`~/.cache/go-build` and `~/go/pkg`) requires a lot of storage space. remove-android: 'true' From 176627192fb5534d16841f1c99ba76380a0f08cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:29:43 +0400 Subject: [PATCH 024/108] chore(deps): bump actions/github-script from 6 to 7 (#5697) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/auto-close-issue.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-close-issue.yaml b/.github/workflows/auto-close-issue.yaml index 679b34bb1232..88495a3b7058 100644 --- a/.github/workflows/auto-close-issue.yaml +++ b/.github/workflows/auto-close-issue.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Close issue if user does not have write or admin permissions - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | // Get the issue creator's username From af32cb310a5a70e9f9971216870bfe1a4b192b48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:32:05 +0400 Subject: [PATCH 025/108] chore(deps): bump github.com/go-git/go-git/v5 from 5.8.1 to 5.10.1 (#5699) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 9 ++++----- go.sum | 36 ++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 257c3c7d9bac..eed9d12ff913 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/color v1.15.0 - github.com/go-git/go-git/v5 v5.8.1 + github.com/go-git/go-git/v5 v5.10.1 github.com/go-openapi/runtime v0.26.0 github.com/go-openapi/strfmt v0.21.7 github.com/go-redis/redis/v8 v8.11.5 @@ -141,9 +141,8 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/VividCortex/ewma v1.2.0 // indirect - github.com/acomagu/bufpipe v1.0.4 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alecthomas/chroma v0.10.0 // indirect @@ -236,7 +235,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.4.1 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.3.0 // indirect @@ -342,7 +341,7 @@ require ( github.com/sergi/go-diff v1.2.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/skeema/knownhosts v1.2.0 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/stretchr/objx v0.5.0 // indirect diff --git a/go.sum b/go.sum index 65f4207f9e57..7c3fa4671413 100644 --- a/go.sum +++ b/go.sum @@ -285,16 +285,14 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= -github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= @@ -765,8 +763,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= -github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= @@ -818,12 +816,12 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= +github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -1308,8 +1306,6 @@ github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd h1:Y30E github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd/go.mod h1:5f7mCJGW9cJb8SDn3z8qodGxpMCOo8d/2nls/tiwRrw= github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70 h1:X6W6raTo07X0q4pvSI/68Pj/Ic4iIU2CfQU65OH0Zhc= github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70/go.mod h1:QKBZqdn6teT0LK3QhAf3K6xakItd1LonOShOEC44idQ= -github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -1435,8 +1431,8 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/open-policy-agent/opa v0.57.0 h1:DftxYfOEHOheXvO2Q6HCIM2ZVdKrvnF4cZlU9C64MIQ= github.com/open-policy-agent/opa v0.57.0/go.mod h1:3FY6GNSbUqOhjCdvTXCBJ2rNuh66p/XrIc2owr/hSwo= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1560,8 +1556,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1602,8 +1598,8 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= From 49e83a6ad21ce595b26df012a9d9bbd90ba9badb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 10:36:06 +0000 Subject: [PATCH 026/108] chore(deps): bump github.com/google/go-containerregistry from 0.16.1 to 0.17.0 (#5704) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index eed9d12ff913..6e27ea8c9462 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/go-redis/redis/v8 v8.11.5 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.3 - github.com/google/go-containerregistry v0.16.1 + github.com/google/go-containerregistry v0.17.0 github.com/google/licenseclassifier/v2 v2.0.0 github.com/google/uuid v1.3.1 github.com/google/wire v0.5.0 diff --git a/go.sum b/go.sum index 7c3fa4671413..541b28e875b8 100644 --- a/go.sum +++ b/go.sum @@ -1029,8 +1029,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= -github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= -github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= +github.com/google/go-containerregistry v0.17.0 h1:5p+zYs/R4VGHkhyvgWurWrpJ2hW4Vv9fQI+GzdcwXLk= +github.com/google/go-containerregistry v0.17.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= From 70078b9c0eb4f6eaadb11cbc425f10761ae0e2c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 10:37:26 +0000 Subject: [PATCH 027/108] chore(deps): bump alpine from 3.18.4 to 3.18.5 (#5700) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.canary | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 43d6ddeeb0ed..f8a548e2af86 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.18.4 +FROM alpine:3.18.5 RUN apk --no-cache add ca-certificates git COPY trivy /usr/local/bin/trivy COPY contrib/*.tpl contrib/ diff --git a/Dockerfile.canary b/Dockerfile.canary index 1ef0d0307810..93a38cbc5138 100644 --- a/Dockerfile.canary +++ b/Dockerfile.canary @@ -1,4 +1,4 @@ -FROM alpine:3.18.4 +FROM alpine:3.18.5 RUN apk --no-cache add ca-certificates git # binaries were created with GoReleaser From 99c04c438372a486d2365c6052d20016fc484771 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Mon, 4 Dec 2023 15:04:43 +0400 Subject: [PATCH 028/108] feat(report): output plugin (#4863) Signed-off-by: knqyf263 Co-authored-by: DmitriyLewen --- cmd/trivy/main.go | 2 +- docs/docs/advanced/plugins.md | 45 ++++++- docs/docs/configuration/reporting.md | 29 ++++- .../references/configuration/cli/trivy_aws.md | 1 + .../configuration/cli/trivy_config.md | 1 + .../configuration/cli/trivy_convert.md | 27 ++-- .../configuration/cli/trivy_filesystem.md | 1 + .../configuration/cli/trivy_image.md | 1 + .../configuration/cli/trivy_kubernetes.md | 1 + .../configuration/cli/trivy_repository.md | 1 + .../configuration/cli/trivy_rootfs.md | 1 + .../configuration/cli/trivy_sbom.md | 1 + .../references/configuration/cli/trivy_vm.md | 1 + go.mod | 1 + go.sum | 2 + pkg/cloud/aws/commands/run.go | 3 +- pkg/cloud/report/report.go | 8 +- pkg/cloud/report/resource_test.go | 3 +- pkg/cloud/report/result_test.go | 3 +- pkg/cloud/report/service_test.go | 3 +- pkg/commands/app.go | 4 +- pkg/commands/artifact/run.go | 8 +- pkg/commands/convert/run.go | 5 +- pkg/flag/options.go | 47 +++++-- pkg/flag/report_flags.go | 116 ++++++++++-------- pkg/flag/report_flags_test.go | 75 ++++++----- pkg/k8s/commands/run.go | 2 +- pkg/plugin/plugin.go | 113 ++++++++++++----- pkg/plugin/plugin_test.go | 9 +- pkg/report/writer.go | 15 ++- 30 files changed, 366 insertions(+), 163 deletions(-) diff --git a/cmd/trivy/main.go b/cmd/trivy/main.go index d07ec31e817e..e2c545975315 100644 --- a/cmd/trivy/main.go +++ b/cmd/trivy/main.go @@ -25,7 +25,7 @@ func run() error { if !plugin.IsPredefined(runAsPlugin) { return xerrors.Errorf("unknown plugin: %s", runAsPlugin) } - if err := plugin.RunWithArgs(context.Background(), runAsPlugin, os.Args[1:]); err != nil { + if err := plugin.RunWithURL(context.Background(), runAsPlugin, plugin.RunOptions{Args: os.Args[1:]}); err != nil { return xerrors.Errorf("plugin error: %w", err) } return nil diff --git a/docs/docs/advanced/plugins.md b/docs/docs/advanced/plugins.md index 390b9cfa565e..dfdfb31d8c0d 100644 --- a/docs/docs/advanced/plugins.md +++ b/docs/docs/advanced/plugins.md @@ -182,8 +182,51 @@ $ trivy myplugin Hello from Trivy demo plugin! ``` +## Plugin Types +Plugins are typically intended to be used as subcommands of Trivy, +but some plugins can be invoked as part of Trivy's built-in commands. +Currently, the following type of plugin is experimentally supported: + +- Output plugins + +### Output Plugins + +!!! warning "EXPERIMENTAL" + This feature might change without preserving backwards compatibility. + +Trivy supports "output plugins" which process Trivy's output, +such as by transforming the output format or sending it elsewhere. +For instance, in the case of image scanning, the output plugin can be called as follows: + +```shell +$ trivy image --format json --output plugin= [--output-plugin-arg ] +``` + +Since scan results are passed to the plugin via standard input, plugins must be capable of handling standard input. + +!!! warning + To avoid Trivy hanging, you need to read all data from `Stdin` before the plugin exits successfully or stops with an error. + +While the example passes JSON to the plugin, other formats like SBOM can also be passed (e.g., `--format cyclonedx`). + +If a plugin requires flags or other arguments, they can be passed using `--output-plugin-arg`. +This is directly forwarded as arguments to the plugin. +For example, `--output plugin=myplugin --output-plugin-arg "--foo --bar=baz"` translates to `myplugin --foo --bar=baz` in execution. + +An example of the output plugin is available [here](https://github.com/aquasecurity/trivy-output-plugin-count). +It can be used as below: + +```shell +# Install the plugin first +$ trivy plugin install github.com/aquasecurity/trivy-output-plugin-count + +# Call the output plugin in image scanning +$ trivy image --format json --output plugin=count --output-plugin-arg "--published-after 2023-10-01" debian:12 +``` + ## Example -https://github.com/aquasecurity/trivy-plugin-kubectl +- https://github.com/aquasecurity/trivy-plugin-kubectl +- https://github.com/aquasecurity/trivy-output-plugin-count [kubectl]: https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/ [helm]: https://helm.sh/docs/topics/plugins/ diff --git a/docs/docs/configuration/reporting.md b/docs/docs/configuration/reporting.md index 17aa6fd973ec..93468222e99b 100644 --- a/docs/docs/configuration/reporting.md +++ b/docs/docs/configuration/reporting.md @@ -1,6 +1,6 @@ # Reporting -## Supported Formats +## Format Trivy supports the following formats: - Table @@ -373,6 +373,33 @@ $ trivy image --format template --template "@/usr/local/share/trivy/templates/ht ### SBOM See [here](../supply-chain/sbom.md) for details. +## Output +Trivy supports the following output destinations: + +- File +- Plugin + +### File +By specifying `--output `, you can output the results to a file. +Here is an example: + +``` +$ trivy image --format json --output result.json debian:12 +``` + +### Plugin +!!! warning "EXPERIMENTAL" + This feature might change without preserving backwards compatibility. + +Plugins capable of receiving Trivy's results via standard input, called "output plugin", can be seamlessly invoked using the `--output` flag. + +``` +$ trivy [--format ] --output plugin= [--output-plugin-arg ] +``` + +This is useful for cases where you want to convert the output into a custom format, or when you want to send the output somewhere. +For more details, please check [here](../advanced/plugins.md#output-plugins). + ## Converting To generate multiple reports, you can generate the JSON report first and convert it to other formats with the `convert` subcommand. diff --git a/docs/docs/references/configuration/cli/trivy_aws.md b/docs/docs/references/configuration/cli/trivy_aws.md index 46a8296dbb80..0218ccb1e987 100644 --- a/docs/docs/references/configuration/cli/trivy_aws.md +++ b/docs/docs/references/configuration/cli/trivy_aws.md @@ -88,6 +88,7 @@ trivy aws [flags] --max-cache-age duration The maximum age of the cloud cache. Cached data will be requeried from the cloud provider if it is older than this. (default 24h0m0s) --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") --policy-namespaces strings Rego namespaces --region string AWS Region to scan diff --git a/docs/docs/references/configuration/cli/trivy_config.md b/docs/docs/references/configuration/cli/trivy_config.md index 19a8983c1784..79d99cad7331 100644 --- a/docs/docs/references/configuration/cli/trivy_config.md +++ b/docs/docs/references/configuration/cli/trivy_config.md @@ -32,6 +32,7 @@ trivy config [flags] DIR --misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan]) --module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules") -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") --policy-namespaces strings Rego namespaces diff --git a/docs/docs/references/configuration/cli/trivy_convert.md b/docs/docs/references/configuration/cli/trivy_convert.md index 9ef4cc5583b0..409e1009951d 100644 --- a/docs/docs/references/configuration/cli/trivy_convert.md +++ b/docs/docs/references/configuration/cli/trivy_convert.md @@ -18,19 +18,20 @@ trivy convert [flags] RESULT_JSON ### Options ``` - --compliance string compliance report to generate - --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages - --exit-code int specify exit code when any security issues are found - --exit-on-eol int exit with the specified code when the OS reaches end of service/life - -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") - -h, --help help for convert - --ignore-policy string specify the Rego file path to evaluate each vulnerability - --ignorefile string specify .trivyignore file (default ".trivyignore") - --list-all-pkgs enabling the option will output all packages regardless of vulnerability - -o, --output string output file name - --report string specify a report format for the output (all,summary) (default "all") - -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) - -t, --template string output template + --compliance string compliance report to generate + --dependency-tree [EXPERIMENTAL] show dependency origin tree of vulnerable packages + --exit-code int specify exit code when any security issues are found + --exit-on-eol int exit with the specified code when the OS reaches end of service/life + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") + -h, --help help for convert + --ignore-policy string specify the Rego file path to evaluate each vulnerability + --ignorefile string specify .trivyignore file (default ".trivyignore") + --list-all-pkgs enabling the option will output all packages regardless of vulnerability + -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments + --report string specify a report format for the output (all,summary) (default "all") + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) + -t, --template string output template ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index ccc12a1475a8..c09c46f69575 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -56,6 +56,7 @@ trivy filesystem [flags] PATH --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index 27264628eac0..c08206a51a5b 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -74,6 +74,7 @@ trivy image [flags] IMAGE_NAME --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --platform string set platform in the form os/arch if image is multi-platform capable diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 35f6fe6a231a..9599ca493d84 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -67,6 +67,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp") --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index 339064883224..4f2a9f65d30b 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -56,6 +56,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL) --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index 5d5f88451afd..aaa120285021 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -58,6 +58,7 @@ trivy rootfs [flags] ROOTDIR --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") diff --git a/docs/docs/references/configuration/cli/trivy_sbom.md b/docs/docs/references/configuration/cli/trivy_sbom.md index 9f899ac977cb..b0fd202863b0 100644 --- a/docs/docs/references/configuration/cli/trivy_sbom.md +++ b/docs/docs/references/configuration/cli/trivy_sbom.md @@ -42,6 +42,7 @@ trivy sbom [flags] SBOM_PATH --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index 0fc813ade0ca..2b004b6992e9 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -52,6 +52,7 @@ trivy vm [flags] VM_IMAGE --no-progress suppress progress bar --offline-scan do not issue API requests to identify dependencies -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments --parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5) --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") --redis-ca string redis ca file location, if using redis as cache backend diff --git a/go.mod b/go.mod index 6e27ea8c9462..2251df877847 100644 --- a/go.mod +++ b/go.mod @@ -72,6 +72,7 @@ require ( github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70 + github.com/mattn/go-shellwords v1.0.12 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 github.com/moby/buildkit v0.11.6 diff --git a/go.sum b/go.sum index 541b28e875b8..25c06c78abbd 100644 --- a/go.sum +++ b/go.sum @@ -1326,6 +1326,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= diff --git a/pkg/cloud/aws/commands/run.go b/pkg/cloud/aws/commands/run.go index 0562dbf72e21..a4541e9f0544 100644 --- a/pkg/cloud/aws/commands/run.go +++ b/pkg/cloud/aws/commands/run.go @@ -129,7 +129,6 @@ func filterServices(opt *flag.Options) error { } func Run(ctx context.Context, opt flag.Options) error { - ctx, cancel := context.WithTimeout(ctx, opt.GlobalOptions.Timeout) defer cancel() @@ -168,7 +167,7 @@ func Run(ctx context.Context, opt flag.Options) error { } r := report.New(cloud.ProviderAWS, opt.Account, opt.Region, res, opt.Services) - if err := report.Write(r, opt, cached); err != nil { + if err := report.Write(ctx, r, opt, cached); err != nil { return xerrors.Errorf("unable to write results: %w", err) } diff --git a/pkg/cloud/report/report.go b/pkg/cloud/report/report.go index 6c7b1ac6d874..8c4fa3861b8e 100644 --- a/pkg/cloud/report/report.go +++ b/pkg/cloud/report/report.go @@ -59,8 +59,8 @@ func (r *Report) Failed() bool { } // Write writes the results in the give format -func Write(rep *Report, opt flag.Options, fromCache bool) error { - output, cleanup, err := opt.OutputWriter() +func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) error { + output, cleanup, err := opt.OutputWriter(ctx) if err != nil { return xerrors.Errorf("failed to create output file: %w", err) } @@ -72,8 +72,6 @@ func Write(rep *Report, opt flag.Options, fromCache bool) error { var filtered []types.Result - ctx := context.Background() - // filter results for _, resultsAtTime := range rep.Results { for _, res := range resultsAtTime.Results { @@ -137,7 +135,7 @@ func Write(rep *Report, opt flag.Options, fromCache bool) error { return nil default: - return pkgReport.Write(base, opt) + return pkgReport.Write(ctx, base, opt) } } diff --git a/pkg/cloud/report/resource_test.go b/pkg/cloud/report/resource_test.go index cb17c2658d57..3f909b8d3b3f 100644 --- a/pkg/cloud/report/resource_test.go +++ b/pkg/cloud/report/resource_test.go @@ -2,6 +2,7 @@ package report import ( "bytes" + "context" "testing" "github.com/stretchr/testify/assert" @@ -111,7 +112,7 @@ No problems detected. output := bytes.NewBuffer(nil) tt.options.SetOutputWriter(output) - require.NoError(t, Write(report, tt.options, tt.fromCache)) + require.NoError(t, Write(context.Background(), report, tt.options, tt.fromCache)) assert.Equal(t, "AWS", report.Provider) assert.Equal(t, tt.options.AWSOptions.Account, report.AccountID) diff --git a/pkg/cloud/report/result_test.go b/pkg/cloud/report/result_test.go index f0ef85d4d564..6afc67305c4f 100644 --- a/pkg/cloud/report/result_test.go +++ b/pkg/cloud/report/result_test.go @@ -2,6 +2,7 @@ package report import ( "bytes" + "context" "strings" "testing" @@ -70,7 +71,7 @@ See https://avd.aquasec.com/misconfig/avd-aws-9999 output := bytes.NewBuffer(nil) tt.options.SetOutputWriter(output) - require.NoError(t, Write(report, tt.options, tt.fromCache)) + require.NoError(t, Write(context.Background(), report, tt.options, tt.fromCache)) assert.Equal(t, "AWS", report.Provider) assert.Equal(t, tt.options.AWSOptions.Account, report.AccountID) diff --git a/pkg/cloud/report/service_test.go b/pkg/cloud/report/service_test.go index b60e6f37c7ce..507f3ff31466 100644 --- a/pkg/cloud/report/service_test.go +++ b/pkg/cloud/report/service_test.go @@ -2,6 +2,7 @@ package report import ( "bytes" + "context" "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" @@ -322,7 +323,7 @@ Scan Overview for AWS Account output := bytes.NewBuffer(nil) tt.options.SetOutputWriter(output) - require.NoError(t, Write(report, tt.options, tt.fromCache)) + require.NoError(t, Write(context.Background(), report, tt.options, tt.fromCache)) assert.Equal(t, "AWS", report.Provider) assert.Equal(t, tt.options.AWSOptions.Account, report.AccountID) diff --git a/pkg/commands/app.go b/pkg/commands/app.go index fe39fb57925c..dac78354075b 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -124,7 +124,7 @@ func loadPluginCommands() []*cobra.Command { Short: p.Usage, GroupID: groupPlugin, RunE: func(cmd *cobra.Command, args []string) error { - if err = p.Run(cmd.Context(), args); err != nil { + if err = p.Run(cmd.Context(), plugin.RunOptions{Args: args}); err != nil { return xerrors.Errorf("plugin error: %w", err) } return nil @@ -773,7 +773,7 @@ func NewPluginCommand() *cobra.Command { Short: "Run a plugin on the fly", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - return plugin.RunWithArgs(cmd.Context(), args[0], args[1:]) + return plugin.RunWithURL(cmd.Context(), args[0], plugin.RunOptions{Args: args[1:]}) }, }, &cobra.Command{ diff --git a/pkg/commands/artifact/run.go b/pkg/commands/artifact/run.go index 2370cc6c1de9..5c32c6d2b250 100644 --- a/pkg/commands/artifact/run.go +++ b/pkg/commands/artifact/run.go @@ -91,7 +91,7 @@ type Runner interface { // Filter filter a report Filter(ctx context.Context, opts flag.Options, report types.Report) (types.Report, error) // Report a writes a report - Report(opts flag.Options, report types.Report) error + Report(ctx context.Context, opts flag.Options, report types.Report) error // Close closes runner Close(ctx context.Context) error } @@ -280,8 +280,8 @@ func (r *runner) Filter(ctx context.Context, opts flag.Options, report types.Rep return report, nil } -func (r *runner) Report(opts flag.Options, report types.Report) error { - if err := pkgReport.Write(report, opts); err != nil { +func (r *runner) Report(ctx context.Context, opts flag.Options, report types.Report) error { + if err := pkgReport.Write(ctx, report, opts); err != nil { return xerrors.Errorf("unable to write results: %w", err) } @@ -451,7 +451,7 @@ func Run(ctx context.Context, opts flag.Options, targetKind TargetKind) (err err return xerrors.Errorf("filter error: %w", err) } - if err = r.Report(opts, report); err != nil { + if err = r.Report(ctx, opts, report); err != nil { return xerrors.Errorf("report error: %w", err) } diff --git a/pkg/commands/convert/run.go b/pkg/commands/convert/run.go index 490864a14bdd..9045e54bfa3d 100644 --- a/pkg/commands/convert/run.go +++ b/pkg/commands/convert/run.go @@ -16,6 +16,9 @@ import ( ) func Run(ctx context.Context, opts flag.Options) (err error) { + ctx, cancel := context.WithTimeout(ctx, opts.Timeout) + defer cancel() + f, err := os.Open(opts.Target) if err != nil { return xerrors.Errorf("file open error: %w", err) @@ -37,7 +40,7 @@ func Run(ctx context.Context, opts flag.Options) (err error) { } log.Logger.Debug("Writing report to output...") - if err = report.Write(r, opts); err != nil { + if err = report.Write(ctx, r, opts); err != nil { return xerrors.Errorf("unable to write results: %w", err) } diff --git a/pkg/flag/options.go b/pkg/flag/options.go index b231705f50da..fb3d69eaa396 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -1,6 +1,7 @@ package flag import ( + "context" "fmt" "io" "os" @@ -17,6 +18,7 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/analyzer" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/plugin" "github.com/aquasecurity/trivy/pkg/result" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/version" @@ -173,19 +175,46 @@ func (o *Options) SetOutputWriter(w io.Writer) { // OutputWriter returns an output writer. // If the output file is not specified, it returns os.Stdout. -func (o *Options) OutputWriter() (io.Writer, func(), error) { - if o.outputWriter != nil { - return o.outputWriter, func() {}, nil +func (o *Options) OutputWriter(ctx context.Context) (io.Writer, func() error, error) { + cleanup := func() error { return nil } + switch { + case o.outputWriter != nil: + return o.outputWriter, cleanup, nil + case o.Output == "": + return os.Stdout, cleanup, nil + case strings.HasPrefix(o.Output, "plugin="): + return o.outputPluginWriter(ctx) } - if o.Output != "" { - f, err := os.Create(o.Output) - if err != nil { - return nil, nil, xerrors.Errorf("failed to create output file: %w", err) + f, err := os.Create(o.Output) + if err != nil { + return nil, nil, xerrors.Errorf("failed to create output file: %w", err) + } + return f, f.Close, nil +} + +func (o *Options) outputPluginWriter(ctx context.Context) (io.Writer, func() error, error) { + pluginName := strings.TrimPrefix(o.Output, "plugin=") + + pr, pw := io.Pipe() + wait, err := plugin.Start(ctx, pluginName, plugin.RunOptions{ + Args: o.OutputPluginArgs, + Stdin: pr, + }) + if err != nil { + return nil, nil, xerrors.Errorf("plugin start: %w", err) + } + + cleanup := func() error { + if err = pw.Close(); err != nil { + return xerrors.Errorf("failed to close pipe: %w", err) } - return f, func() { _ = f.Close() }, nil + if err = wait(); err != nil { + return xerrors.Errorf("plugin error: %w", err) + } + return nil } - return os.Stdout, func() {}, nil + return pw, cleanup, nil } func addFlag(cmd *cobra.Command, flag *Flag) { diff --git a/pkg/flag/report_flags.go b/pkg/flag/report_flags.go index 50304f5d7883..54554be3d126 100644 --- a/pkg/flag/report_flags.go +++ b/pkg/flag/report_flags.go @@ -3,6 +3,7 @@ package flag import ( "strings" + "github.com/mattn/go-shellwords" "github.com/samber/lo" "golang.org/x/exp/slices" "golang.org/x/xerrors" @@ -86,6 +87,12 @@ var ( Default: "", Usage: "output file name", } + OutputPluginArgFlag = Flag{ + Name: "output-plugin-arg", + ConfigName: "output-plugin-arg", + Default: "", + Usage: "[EXPERIMENTAL] output plugin arguments", + } SeverityFlag = Flag{ Name: "severity", ConfigName: "severity", @@ -105,49 +112,52 @@ var ( // ReportFlagGroup composes common printer flag structs // used for commands requiring reporting logic. type ReportFlagGroup struct { - Format *Flag - ReportFormat *Flag - Template *Flag - DependencyTree *Flag - ListAllPkgs *Flag - IgnoreFile *Flag - IgnorePolicy *Flag - ExitCode *Flag - ExitOnEOL *Flag - Output *Flag - Severity *Flag - Compliance *Flag + Format *Flag + ReportFormat *Flag + Template *Flag + DependencyTree *Flag + ListAllPkgs *Flag + IgnoreFile *Flag + IgnorePolicy *Flag + ExitCode *Flag + ExitOnEOL *Flag + Output *Flag + OutputPluginArg *Flag + Severity *Flag + Compliance *Flag } type ReportOptions struct { - Format types.Format - ReportFormat string - Template string - DependencyTree bool - ListAllPkgs bool - IgnoreFile string - ExitCode int - ExitOnEOL int - IgnorePolicy string - Output string - Severities []dbTypes.Severity - Compliance spec.ComplianceSpec + Format types.Format + ReportFormat string + Template string + DependencyTree bool + ListAllPkgs bool + IgnoreFile string + ExitCode int + ExitOnEOL int + IgnorePolicy string + Output string + OutputPluginArgs []string + Severities []dbTypes.Severity + Compliance spec.ComplianceSpec } func NewReportFlagGroup() *ReportFlagGroup { return &ReportFlagGroup{ - Format: &FormatFlag, - ReportFormat: &ReportFormatFlag, - Template: &TemplateFlag, - DependencyTree: &DependencyTreeFlag, - ListAllPkgs: &ListAllPkgsFlag, - IgnoreFile: &IgnoreFileFlag, - IgnorePolicy: &IgnorePolicyFlag, - ExitCode: &ExitCodeFlag, - ExitOnEOL: &ExitOnEOLFlag, - Output: &OutputFlag, - Severity: &SeverityFlag, - Compliance: &ComplianceFlag, + Format: &FormatFlag, + ReportFormat: &ReportFormatFlag, + Template: &TemplateFlag, + DependencyTree: &DependencyTreeFlag, + ListAllPkgs: &ListAllPkgsFlag, + IgnoreFile: &IgnoreFileFlag, + IgnorePolicy: &IgnorePolicyFlag, + ExitCode: &ExitCodeFlag, + ExitOnEOL: &ExitOnEOLFlag, + Output: &OutputFlag, + OutputPluginArg: &OutputPluginArgFlag, + Severity: &SeverityFlag, + Compliance: &ComplianceFlag, } } @@ -167,6 +177,7 @@ func (f *ReportFlagGroup) Flags() []*Flag { f.ExitCode, f.ExitOnEOL, f.Output, + f.OutputPluginArg, f.Severity, f.Compliance, } @@ -216,19 +227,28 @@ func (f *ReportFlagGroup) ToOptions() (ReportOptions, error) { return ReportOptions{}, xerrors.Errorf("unable to load compliance spec: %w", err) } + var outputPluginArgs []string + if arg := getString(f.OutputPluginArg); arg != "" { + outputPluginArgs, err = shellwords.Parse(arg) + if err != nil { + return ReportOptions{}, xerrors.Errorf("unable to parse output plugin argument: %w", err) + } + } + return ReportOptions{ - Format: format, - ReportFormat: getString(f.ReportFormat), - Template: template, - DependencyTree: dependencyTree, - ListAllPkgs: listAllPkgs, - IgnoreFile: getString(f.IgnoreFile), - ExitCode: getInt(f.ExitCode), - ExitOnEOL: getInt(f.ExitOnEOL), - IgnorePolicy: getString(f.IgnorePolicy), - Output: getString(f.Output), - Severities: toSeverity(getStringSlice(f.Severity)), - Compliance: cs, + Format: format, + ReportFormat: getString(f.ReportFormat), + Template: template, + DependencyTree: dependencyTree, + ListAllPkgs: listAllPkgs, + IgnoreFile: getString(f.IgnoreFile), + ExitCode: getInt(f.ExitCode), + ExitOnEOL: getInt(f.ExitOnEOL), + IgnorePolicy: getString(f.IgnorePolicy), + Output: getString(f.Output), + OutputPluginArgs: outputPluginArgs, + Severities: toSeverity(getStringSlice(f.Severity)), + Compliance: cs, }, nil } diff --git a/pkg/flag/report_flags_test.go b/pkg/flag/report_flags_test.go index 9155addbbe64..c2e92fc5fcbd 100644 --- a/pkg/flag/report_flags_test.go +++ b/pkg/flag/report_flags_test.go @@ -18,20 +18,20 @@ import ( func TestReportFlagGroup_ToOptions(t *testing.T) { type fields struct { - format types.Format - template string - dependencyTree bool - listAllPkgs bool - ignoreUnfixed bool - ignoreFile string - exitCode int - exitOnEOSL bool - ignorePolicy string - output string - severities string - compliane string - - debug bool + format types.Format + template string + dependencyTree bool + listAllPkgs bool + ignoreUnfixed bool + ignoreFile string + exitCode int + exitOnEOSL bool + ignorePolicy string + output string + outputPluginArgs string + severities string + compliance string + debug bool } tests := []struct { name string @@ -63,8 +63,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { severities: "CRITICAL", format: "cyclonedx", listAllPkgs: false, - - debug: true, + debug: true, }, wantLogs: []string{ `["cyclonedx" "spdx" "spdx-json" "github"] automatically enables '--list-all-pkgs'.`, @@ -138,10 +137,26 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { ListAllPkgs: true, }, }, + { + name: "happy path with output plugin args", + fields: fields{ + output: "plugin=count", + outputPluginArgs: "--publish-after 2023-10-01 --publish-before 2023-10-02", + }, + want: flag.ReportOptions{ + Output: "plugin=count", + OutputPluginArgs: []string{ + "--publish-after", + "2023-10-01", + "--publish-before", + "2023-10-02", + }, + }, + }, { name: "happy path with compliance", fields: fields{ - compliane: "@testdata/example-spec.yaml", + compliance: "@testdata/example-spec.yaml", severities: dbTypes.SeverityLow.String(), }, want: flag.ReportOptions{ @@ -187,22 +202,24 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { viper.Set(flag.ExitCodeFlag.ConfigName, tt.fields.exitCode) viper.Set(flag.ExitOnEOLFlag.ConfigName, tt.fields.exitOnEOSL) viper.Set(flag.OutputFlag.ConfigName, tt.fields.output) + viper.Set(flag.OutputPluginArgFlag.ConfigName, tt.fields.outputPluginArgs) viper.Set(flag.SeverityFlag.ConfigName, tt.fields.severities) - viper.Set(flag.ComplianceFlag.ConfigName, tt.fields.compliane) + viper.Set(flag.ComplianceFlag.ConfigName, tt.fields.compliance) // Assert options f := &flag.ReportFlagGroup{ - Format: &flag.FormatFlag, - Template: &flag.TemplateFlag, - DependencyTree: &flag.DependencyTreeFlag, - ListAllPkgs: &flag.ListAllPkgsFlag, - IgnoreFile: &flag.IgnoreFileFlag, - IgnorePolicy: &flag.IgnorePolicyFlag, - ExitCode: &flag.ExitCodeFlag, - ExitOnEOL: &flag.ExitOnEOLFlag, - Output: &flag.OutputFlag, - Severity: &flag.SeverityFlag, - Compliance: &flag.ComplianceFlag, + Format: &flag.FormatFlag, + Template: &flag.TemplateFlag, + DependencyTree: &flag.DependencyTreeFlag, + ListAllPkgs: &flag.ListAllPkgsFlag, + IgnoreFile: &flag.IgnoreFileFlag, + IgnorePolicy: &flag.IgnorePolicyFlag, + ExitCode: &flag.ExitCodeFlag, + ExitOnEOL: &flag.ExitOnEOLFlag, + Output: &flag.OutputFlag, + OutputPluginArg: &flag.OutputPluginArgFlag, + Severity: &flag.SeverityFlag, + Compliance: &flag.ComplianceFlag, } got, err := f.ToOptions() diff --git a/pkg/k8s/commands/run.go b/pkg/k8s/commands/run.go index 9207363342c6..ec3e61385c65 100644 --- a/pkg/k8s/commands/run.go +++ b/pkg/k8s/commands/run.go @@ -101,7 +101,7 @@ func (r *runner) run(ctx context.Context, artifacts []*k8sArtifacts.Artifact) er return xerrors.Errorf("k8s scan error: %w", err) } - output, cleanup, err := r.flagOpts.OutputWriter() + output, cleanup, err := r.flagOpts.OutputWriter(ctx) if err != nil { return xerrors.Errorf("failed to create output file: %w", err) } diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index 34eeb7eb3e1d..f96f02a80c00 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -3,6 +3,7 @@ package plugin import ( "context" "fmt" + "io" "os" "os/exec" "path/filepath" @@ -57,21 +58,55 @@ type Selector struct { Arch string } -// Run runs the plugin -func (p Plugin) Run(ctx context.Context, args []string) error { +type RunOptions struct { + Args []string + Stdin io.Reader +} + +func (p Plugin) Cmd(ctx context.Context, opts RunOptions) (*exec.Cmd, error) { platform, err := p.selectPlatform() if err != nil { - return xerrors.Errorf("platform selection error: %w", err) + return nil, xerrors.Errorf("platform selection error: %w", err) } execFile := filepath.Join(dir(), p.Name, platform.Bin) - cmd := exec.CommandContext(ctx, execFile, args...) + cmd := exec.CommandContext(ctx, execFile, opts.Args...) cmd.Stdin = os.Stdin + if opts.Stdin != nil { + cmd.Stdin = opts.Stdin + } cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = os.Environ() + return cmd, nil +} + +type Wait func() error + +// Start starts the plugin +// +// After a successful call to Start the Wait method must be called. +func (p Plugin) Start(ctx context.Context, opts RunOptions) (Wait, error) { + cmd, err := p.Cmd(ctx, opts) + if err != nil { + return nil, xerrors.Errorf("cmd: %w", err) + } + + if err = cmd.Start(); err != nil { + return nil, xerrors.Errorf("plugin start: %w", err) + } + return cmd.Wait, nil +} + +// Run runs the plugin +func (p Plugin) Run(ctx context.Context, opts RunOptions) error { + cmd, err := p.Cmd(ctx, opts) + if err != nil { + return xerrors.Errorf("cmd: %w", err) + } + // If an error is found during the execution of the plugin, figure // out if the error was from not being able to execute the plugin or // an error set by the plugin itself. @@ -79,10 +114,8 @@ func (p Plugin) Run(ctx context.Context, args []string) error { if _, ok := err.(*exec.ExitError); !ok { return xerrors.Errorf("exit: %w", err) } - return xerrors.Errorf("plugin exec: %w", err) } - return nil } @@ -186,18 +219,9 @@ func Uninstall(name string) error { // Information gets the information about an installed plugin func Information(name string) (string, error) { - pluginDir := filepath.Join(dir(), name) - - if _, err := os.Stat(pluginDir); err != nil { - if os.IsNotExist(err) { - return "", xerrors.Errorf("could not find a plugin called '%s', did you install it?", name) - } - return "", xerrors.Errorf("stat error: %w", err) - } - - plugin, err := loadMetadata(pluginDir) + plugin, err := load(name) if err != nil { - return "", xerrors.Errorf("unable to load metadata: %w", err) + return "", xerrors.Errorf("plugin load error: %w", err) } return fmt.Sprintf(` @@ -230,19 +254,11 @@ func List() (string, error) { // Update updates an existing plugin func Update(name string) error { - pluginDir := filepath.Join(dir(), name) - - if _, err := os.Stat(pluginDir); err != nil { - if os.IsNotExist(err) { - return xerrors.Errorf("could not find a plugin called '%s' to update: %w", name, err) - } - return err - } - - plugin, err := loadMetadata(pluginDir) + plugin, err := load(name) if err != nil { - return err + return xerrors.Errorf("plugin load error: %w", err) } + log.Logger.Infof("Updating plugin '%s'", name) updated, err := Install(nil, plugin.Repository, true) if err != nil { @@ -280,15 +296,29 @@ func LoadAll() ([]Plugin, error) { return plugins, nil } -// RunWithArgs runs the plugin with arguments -func RunWithArgs(ctx context.Context, url string, args []string) error { - pl, err := Install(ctx, url, false) +// Start starts the plugin +func Start(ctx context.Context, name string, opts RunOptions) (Wait, error) { + plugin, err := load(name) + if err != nil { + return nil, xerrors.Errorf("plugin load error: %w", err) + } + + wait, err := plugin.Start(ctx, opts) + if err != nil { + return nil, xerrors.Errorf("unable to run %s plugin: %w", plugin.Name, err) + } + return wait, nil +} + +// RunWithURL runs the plugin with URL +func RunWithURL(ctx context.Context, url string, opts RunOptions) error { + plugin, err := Install(ctx, url, false) if err != nil { return xerrors.Errorf("plugin install error: %w", err) } - if err = pl.Run(ctx, args); err != nil { - return xerrors.Errorf("unable to run %s plugin: %w", pl.Name, err) + if err = plugin.Run(ctx, opts); err != nil { + return xerrors.Errorf("unable to run %s plugin: %w", plugin.Name, err) } return nil } @@ -298,6 +328,23 @@ func IsPredefined(name string) bool { return ok } +func load(name string) (Plugin, error) { + pluginDir := filepath.Join(dir(), name) + if _, err := os.Stat(pluginDir); err != nil { + if os.IsNotExist(err) { + return Plugin{}, xerrors.Errorf("could not find a plugin called '%s', did you install it?", name) + } + return Plugin{}, xerrors.Errorf("plugin stat error: %w", err) + } + + plugin, err := loadMetadata(pluginDir) + if err != nil { + return Plugin{}, xerrors.Errorf("unable to load plugin metadata: %w", err) + } + + return plugin, nil +} + func loadMetadata(dir string) (Plugin, error) { filePath := filepath.Join(dir, configFile) f, err := os.Open(filePath) diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go index 6839d7eb7c9d..f9ee7aac2b89 100644 --- a/pkg/plugin/plugin_test.go +++ b/pkg/plugin/plugin_test.go @@ -29,13 +29,10 @@ func TestPlugin_Run(t *testing.T) { GOOS string GOARCH string } - type args struct { - args []string - } tests := []struct { name string fields fields - args args + opts plugin.RunOptions wantErr string }{ { @@ -162,7 +159,7 @@ func TestPlugin_Run(t *testing.T) { GOARCH: tt.fields.GOARCH, } - err := p.Run(context.Background(), tt.args.args) + err := p.Run(context.Background(), tt.opts) if tt.wantErr != "" { require.NotNil(t, err) assert.Contains(t, err.Error(), tt.wantErr) @@ -338,7 +335,7 @@ description: A simple test plugin` // Get Information for unknown plugin info, err = plugin.Information("unknown") require.Error(t, err) - assert.Equal(t, "could not find a plugin called 'unknown', did you install it?", err.Error()) + assert.ErrorContains(t, err, "could not find a plugin called 'unknown', did you install it?") } func TestLoadAll1(t *testing.T) { diff --git a/pkg/report/writer.go b/pkg/report/writer.go index 648a9372f534..e53cad0e0463 100644 --- a/pkg/report/writer.go +++ b/pkg/report/writer.go @@ -1,6 +1,8 @@ package report import ( + "context" + "errors" "io" "strings" "sync" @@ -24,12 +26,16 @@ const ( ) // Write writes the result to output, format as passed in argument -func Write(report types.Report, option flag.Options) error { - output, cleanup, err := option.OutputWriter() +func Write(ctx context.Context, report types.Report, option flag.Options) (err error) { + output, cleanup, err := option.OutputWriter(ctx) if err != nil { return xerrors.Errorf("failed to create a file: %w", err) } - defer cleanup() + defer func() { + if cerr := cleanup(); cerr != nil { + err = errors.Join(err, cerr) + } + }() // Compliance report if option.Compliance.Spec.ID != "" { @@ -91,9 +97,10 @@ func Write(report types.Report, option flag.Options) error { return xerrors.Errorf("unknown format: %v", option.Format) } - if err := writer.Write(report); err != nil { + if err = writer.Write(report); err != nil { return xerrors.Errorf("failed to write results: %w", err) } + return nil } From a54d1e95fdfa1eaff0b854c6017035001ef4fef0 Mon Sep 17 00:00:00 2001 From: Andrea Scarpino Date: Mon, 4 Dec 2023 16:29:14 +0000 Subject: [PATCH 029/108] feat(vuln): remove duplicates in Fixed Version (#5596) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- pkg/detector/library/driver.go | 9 +++++-- pkg/detector/library/driver_test.go | 25 +++++++++++++++++++ .../testdata/fixtures/data-source.yaml | 5 ++++ .../library/testdata/fixtures/pip.yaml | 18 +++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 pkg/detector/library/testdata/fixtures/pip.yaml diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index c22d1f7c5ac5..e18f926a3964 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/samber/lo" "golang.org/x/xerrors" "github.com/aquasecurity/trivy-db/pkg/db" @@ -136,7 +137,7 @@ func (d *Driver) DetectVulnerabilities(pkgID, pkgName, pkgVer string) ([]types.D func createFixedVersions(advisory dbTypes.Advisory) string { if len(advisory.PatchedVersions) != 0 { - return strings.Join(advisory.PatchedVersions, ", ") + return joinFixedVersions(advisory.PatchedVersions) } var fixedVersions []string @@ -149,5 +150,9 @@ func createFixedVersions(advisory dbTypes.Advisory) string { } } } - return strings.Join(fixedVersions, ", ") + return joinFixedVersions(fixedVersions) +} + +func joinFixedVersions(fixedVersions []string) string { + return strings.Join(lo.Uniq(fixedVersions), ", ") } diff --git a/pkg/detector/library/driver_test.go b/pkg/detector/library/driver_test.go index 9bfa6ade777d..b7b94153c6a1 100644 --- a/pkg/detector/library/driver_test.go +++ b/pkg/detector/library/driver_test.go @@ -157,6 +157,31 @@ func TestDriver_Detect(t *testing.T) { }, wantErr: "failed to unmarshal advisory JSON", }, + { + name: "duplicated version in advisory", + fixtures: []string{ + "testdata/fixtures/pip.yaml", + "testdata/fixtures/data-source.yaml", + }, + libType: ftypes.PythonPkg, + args: args{ + pkgName: "Django", + pkgVer: "4.2.1", + }, + want: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2023-36053", + PkgName: "Django", + InstalledVersion: "4.2.1", + FixedVersion: "4.2.3", + DataSource: &dbTypes.DataSource{ + ID: vulnerability.GHSA, + Name: "GitHub Security Advisory Pip", + URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip", + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/detector/library/testdata/fixtures/data-source.yaml b/pkg/detector/library/testdata/fixtures/data-source.yaml index 26d88adf8309..eeb4a57e9637 100644 --- a/pkg/detector/library/testdata/fixtures/data-source.yaml +++ b/pkg/detector/library/testdata/fixtures/data-source.yaml @@ -20,3 +20,8 @@ ID: "ruby-advisory-db" Name: "Ruby Advisory Database" URL: "https://github.com/rubysec/ruby-advisory-db" + - key: "pip::GitHub Security Advisory Pip" + value: + ID: "ghsa" + Name: "GitHub Security Advisory Pip" + URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Apip" diff --git a/pkg/detector/library/testdata/fixtures/pip.yaml b/pkg/detector/library/testdata/fixtures/pip.yaml new file mode 100644 index 000000000000..f39357e16fb6 --- /dev/null +++ b/pkg/detector/library/testdata/fixtures/pip.yaml @@ -0,0 +1,18 @@ +- bucket: "pip::GitHub Security Advisory Pip" + pairs: + - bucket: Django + pairs: + - key: CVE-2023-36053 + value: + PatchedVersions: + - 4.2.3 + VulnerableVersions: + - < 4.2.3 + - bucket: django + pairs: + - key: CVE-2023-36053 + value: + PatchedVersions: + - 4.2.3 + VulnerableVersions: + - < 4.2.3 From 0ff5f96bb76ed9bec438f73ade2b1249a9025b16 Mon Sep 17 00:00:00 2001 From: chenk Date: Tue, 5 Dec 2023 09:17:51 +0200 Subject: [PATCH 030/108] feat: filter k8s core components vuln results (#5713) Signed-off-by: chenk --- pkg/k8s/report/report.go | 4 ++-- pkg/k8s/scanner/scanner.go | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/k8s/report/report.go b/pkg/k8s/report/report.go index bf0d0aaf8626..df68e7d5ad0c 100644 --- a/pkg/k8s/report/report.go +++ b/pkg/k8s/report/report.go @@ -222,7 +222,7 @@ func infraResource(misConfig Resource) bool { } func CreateResource(artifact *artifacts.Artifact, report types.Report, err error) Resource { - r := CreateK8sResource(artifact, report.Results) + r := createK8sResource(artifact, report.Results) r.Metadata = report.Metadata r.Report = report @@ -234,7 +234,7 @@ func CreateResource(artifact *artifacts.Artifact, report types.Report, err error return r } -func CreateK8sResource(artifact *artifacts.Artifact, scanResults types.Results) Resource { +func createK8sResource(artifact *artifacts.Artifact, scanResults types.Results) Resource { results := make([]types.Result, 0, len(scanResults)) // fix target name for _, result := range scanResults { diff --git a/pkg/k8s/scanner/scanner.go b/pkg/k8s/scanner/scanner.go index 35b9003fabf3..8e624dd4a9a6 100644 --- a/pkg/k8s/scanner/scanner.go +++ b/pkg/k8s/scanner/scanner.go @@ -262,7 +262,14 @@ func (s *Scanner) scanK8sVulns(ctx context.Context, artifactsData []*artifacts.A return nil, err } if results != nil { - resources = append(resources, report.CreateK8sResource(artifact, results)) + resource, err := s.filter(ctx, types.Report{ + Results: results, + ArtifactName: artifact.Name, + }, artifact) + if err != nil { + return nil, err + } + resources = append(resources, resource) } case nodeComponents: var nf bom.NodeInfo @@ -301,7 +308,14 @@ func (s *Scanner) scanK8sVulns(ctx context.Context, artifactsData []*artifacts.A return nil, err } if results != nil { - resources = append(resources, report.CreateK8sResource(artifact, results)) + resource, err := s.filter(ctx, types.Report{ + Results: results, + ArtifactName: artifact.Name, + }, artifact) + if err != nil { + return nil, err + } + resources = append(resources, resource) } case clusterInfo: var cf bom.ClusterInfo @@ -329,7 +343,14 @@ func (s *Scanner) scanK8sVulns(ctx context.Context, artifactsData []*artifacts.A return nil, err } if results != nil { - resources = append(resources, report.CreateK8sResource(artifact, results)) + resource, err := s.filter(ctx, types.Report{ + Results: results, + ArtifactName: artifact.Name, + }, artifact) + if err != nil { + return nil, err + } + resources = append(resources, resource) } } } From 6d7e2f8116937913fe913977cecce7b1eb9e4eb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:18:17 +0400 Subject: [PATCH 031/108] chore(deps): bump helm/chart-testing-action from 2.4.0 to 2.6.1 (#5694) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-chart.yaml b/.github/workflows/publish-chart.yaml index 197945f35117..349ae1f47202 100644 --- a/.github/workflows/publish-chart.yaml +++ b/.github/workflows/publish-chart.yaml @@ -35,7 +35,7 @@ jobs: python-version: 3.7 - name: Setup Chart Linting id: lint - uses: helm/chart-testing-action@e8788873172cb653a90ca2e819d79d65a66d4e76 + uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 - name: Setup Kubernetes cluster (KIND) uses: helm/kind-action@dda0770415bac9fc20092cacbc54aa298604d140 with: From f2aa9bf3eb31468921491a071be60e9de8fd10bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:18:38 +0400 Subject: [PATCH 032/108] chore(deps): bump sigstore/cosign-installer from 4a861528be5e691840a69536975ada1d4c30349d to 1fc5bd396d372bee37d608f955b336615edf79c8 (#5696) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-release.yaml b/.github/workflows/reusable-release.yaml index 4850a45ad96c..4943da9522e7 100644 --- a/.github/workflows/reusable-release.yaml +++ b/.github/workflows/reusable-release.yaml @@ -36,7 +36,7 @@ jobs: remove-haskell: 'true' - name: Cosign install - uses: sigstore/cosign-installer@4a861528be5e691840a69536975ada1d4c30349d + uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 - name: Set up QEMU uses: docker/setup-qemu-action@v3 From e27ec3261e7c639b29d1f20c0f78518824f153a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:52:06 +0400 Subject: [PATCH 033/108] chore(deps): bump github.com/aws/aws-sdk-go-v2/service/ecr from 1.21.0 to 1.24.1 (#5701) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 2251df877847..bdb464eedd5d 100644 --- a/go.mod +++ b/go.mod @@ -29,12 +29,12 @@ require ( github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 - github.com/aws/aws-sdk-go-v2 v1.22.1 + github.com/aws/aws-sdk-go-v2 v1.23.4 github.com/aws/aws-sdk-go-v2/config v1.18.45 github.com/aws/aws-sdk-go-v2/credentials v1.13.43 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0 - github.com/aws/aws-sdk-go-v2/service/ecr v1.21.0 + github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 github.com/aws/aws-sdk-go-v2/service/sts v1.25.0 github.com/bmatcuk/doublestar/v4 v4.6.0 @@ -156,8 +156,8 @@ require ( github.com/aws/aws-sdk-go v1.48.4 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 // indirect @@ -199,7 +199,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 // indirect - github.com/aws/smithy-go v1.16.0 // indirect + github.com/aws/smithy-go v1.18.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/briandowns/spinner v1.23.0 // indirect diff --git a/go.sum b/go.sum index 25c06c78abbd..da3b164dc392 100644 --- a/go.sum +++ b/go.sum @@ -376,8 +376,8 @@ github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDL github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.22.1 h1:sjnni/AuoTXxHitsIdT0FwmqUuNUuHtufcVDErVFT9U= -github.com/aws/aws-sdk-go-v2 v1.22.1/go.mod h1:Kd0OJtkW3Q0M0lUWGszapWjEvrXDzRW+D21JNsroB+c= +github.com/aws/aws-sdk-go-v2 v1.23.4 h1:2P20ZjH0ouSAu/6yZep8oCmTReathLuEu6dwoqEgjts= +github.com/aws/aws-sdk-go-v2 v1.23.4/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 h1:Sc82v7tDQ/vdU1WtuSyzZ1I7y/68j//HJ6uozND1IDs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= @@ -393,14 +393,14 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42/go.mod h1:oDfgXoBBmj+kXnqxDDnIDnC56QBosglKp8ftRCTxR+0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.1 h1:fi1ga6WysOyYb5PAf3Exd6B5GiSNpnZim4h1rhlBqx0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.1/go.mod h1:V5CY8wNurvPUibTi9mwqUqpiFZ5LnioKWIFUDtIzdI8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7 h1:eMqD7ku6WGdmcWWXPYun9m6yk6feSULLhJlAtN6rYG4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7/go.mod h1:0oBIfcDV6LScxEW0VgOqxT3e4aqKRp+SYhB9wAd5E3Q= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36/go.mod h1:rwr4WnmFi3RJO0M4dxbJtgi9BPLMpVBMX1nUte5ha9U= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.1 h1:ZpaV/j48RlPc4AmOZuPv22pJliXjXq8/reL63YzyFnw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.1/go.mod h1:R8aXraabD2e3qv1csxM14/X9WF4wFMIY0kH4YEtYD5M= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7 h1:+XYhWhgWs5F3Zx8oa49CXzNvfXrItaDjZB/M172fcHQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7/go.mod h1:L6tcSRyCGxcKfDWUrmv2jv8G1cLDU7d0FUpEFpG9bVE= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 h1:wmGLw2i8ZTlHLw7a9ULGfQbuccw8uIiNr6sol5bFzc8= @@ -431,8 +431,8 @@ github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 h1:iUgGXA8fg41B4Of0F+BS766SRQ7c github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1/go.mod h1:9n0SC5yHomD8IjsR37+/txpdfNdpGSgV1RzmsTHrbWg= github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0 h1:knbx9D59itE07Ihbx+1Po8jPDfo2M/8vDQn/4oUtTxk= github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0/go.mod h1:0FhI2Rzcv5BNM3dNnbcCx2qa2naFZoAidJi11cQgzL0= -github.com/aws/aws-sdk-go-v2/service/ecr v1.21.0 h1:S0uAQWwpl6Di64Z+6zDfXnyiO4o7ZmLByNdPfIP9iHY= -github.com/aws/aws-sdk-go-v2/service/ecr v1.21.0/go.mod h1:q94FTlrkHQjYo/2aOYimhPXhwrkZsjreFYPn6Cdh0/4= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 h1:zqXEIhuR7RcHob2gxB/Xf1X4XuMS0vapn7xr+wCPrpg= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1/go.mod h1:+rWYJfms9p+D/wUN599tx3FtWvxoXCP25b8Porlrxcc= github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1 h1:bOS7hAfvd8+glVAG88WnvRITe5N1vopGFHh10ORe/BI= github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1/go.mod h1:cxbA26Kf4UlTb40f5FON22ZPNMyEVmMS82KUJZC1E1w= github.com/aws/aws-sdk-go-v2/service/efs v1.21.6 h1:Hk/hIxTQ2OcLqG/rThJSwawnXwNftGUyYMNq3Dmrl0E= @@ -498,8 +498,8 @@ github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1/go.mod h1:56TIMTOeThR8Ep github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.16.0 h1:gJZEH/Fqh+RsvlJ1Zt4tVAtV6bKkp3cC+R6FCZMNzik= -github.com/aws/smithy-go v1.16.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= +github.com/aws/smithy-go v1.18.1 h1:pOdBTUfXNazOlxLrgeYalVnuTpKreACHtc62xLwIB3c= +github.com/aws/smithy-go v1.18.1/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= From 6080e245ce86695f7070cb6db394d05bf6e59351 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 09:38:17 +0000 Subject: [PATCH 034/108] chore(deps): bump github.com/aws/aws-sdk-go-v2/config from 1.18.45 to 1.25.11 (#5717) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 24 ++++++++++++------------ go.sum | 41 ++++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index bdb464eedd5d..ea65d56a2f41 100644 --- a/go.mod +++ b/go.mod @@ -29,14 +29,14 @@ require ( github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 - github.com/aws/aws-sdk-go-v2 v1.23.4 - github.com/aws/aws-sdk-go-v2/config v1.18.45 - github.com/aws/aws-sdk-go-v2/credentials v1.13.43 + github.com/aws/aws-sdk-go-v2 v1.23.5 + github.com/aws/aws-sdk-go-v2/config v1.25.11 + github.com/aws/aws-sdk-go-v2/credentials v1.16.9 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0 github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 - github.com/aws/aws-sdk-go-v2/service/sts v1.25.0 + github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cheggaaa/pb/v3 v3.1.4 @@ -155,10 +155,10 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go v1.48.4 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 // indirect github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0 // indirect @@ -180,10 +180,10 @@ require ( github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.20.6 // indirect github.com/aws/aws-sdk-go-v2/service/emr v1.28.7 // indirect github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 // indirect github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 // indirect github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 // indirect github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.5 // indirect @@ -196,8 +196,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.21.3 // indirect github.com/aws/aws-sdk-go-v2/service/sns v1.21.5 // indirect github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 // indirect github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 // indirect github.com/aws/smithy-go v1.18.1 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index da3b164dc392..ebf176383970 100644 --- a/go.sum +++ b/go.sum @@ -376,33 +376,37 @@ github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDL github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.23.4 h1:2P20ZjH0ouSAu/6yZep8oCmTReathLuEu6dwoqEgjts= -github.com/aws/aws-sdk-go-v2 v1.23.4/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= +github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg= +github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 h1:Sc82v7tDQ/vdU1WtuSyzZ1I7y/68j//HJ6uozND1IDs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= -github.com/aws/aws-sdk-go-v2/config v1.18.45 h1:Aka9bI7n8ysuwPeFdm77nfbyHCAKQ3z9ghB3S/38zes= github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= -github.com/aws/aws-sdk-go-v2/credentials v1.13.43 h1:LU8vo40zBlo3R7bAvBVy/ku4nxGEyZe9N8MqAeFTzF8= +github.com/aws/aws-sdk-go-v2/config v1.25.11 h1:RWzp7jhPRliIcACefGkKp03L0Yofmd2p8M25kbiyvno= +github.com/aws/aws-sdk-go-v2/config v1.25.11/go.mod h1:BVUs0chMdygHsQtvaMyEOpW2GIW+ubrxJLgIz/JU29s= github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 h1:PIktER+hwIG286DqXyvVENjgLTAwGgoeriLDD5C+YlQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.9 h1:LQo3MUIOzod9JdUK+wxmSdgzLVYUbII3jXn3S/HJZU0= +github.com/aws/aws-sdk-go-v2/credentials v1.16.9/go.mod h1:R7mDuIJoCjH6TxGUc/cylE7Lp/o0bhKVoxdBThsjqCM= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 h1:FZVFahMyZle6WcogZCOxo6D/lkDA2lqKIn4/ueUmVXw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9/go.mod h1:kjq7REMIkxdtcEC9/4BVXjOsNY5isz6jQbEgk6osRTU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 h1:mtJRt80k1oGw7QQPluAx8AZ6u16MyCA2di/lMhagZ7I= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90/go.mod h1:lYwZTkeMQWPvNU+u7oYArdNhQ8EKiSGU76jVv0w2GH4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49Kk6+82spO3Tu5gSeQXRsxo56ePPQAvFiA= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42/go.mod h1:oDfgXoBBmj+kXnqxDDnIDnC56QBosglKp8ftRCTxR+0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7 h1:eMqD7ku6WGdmcWWXPYun9m6yk6feSULLhJlAtN6rYG4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.7/go.mod h1:0oBIfcDV6LScxEW0VgOqxT3e4aqKRp+SYhB9wAd5E3Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36/go.mod h1:rwr4WnmFi3RJO0M4dxbJtgi9BPLMpVBMX1nUte5ha9U= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7 h1:+XYhWhgWs5F3Zx8oa49CXzNvfXrItaDjZB/M172fcHQ= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.7/go.mod h1:L6tcSRyCGxcKfDWUrmv2jv8G1cLDU7d0FUpEFpG9bVE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 h1:wmGLw2i8ZTlHLw7a9ULGfQbuccw8uIiNr6sol5bFzc8= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6/go.mod h1:Q0Hq2X/NuL7z8b1Dww8rmOFl+jzusKEcyvkKspwdpyc= github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 h1:3fWAJsw4dLG4eYKHL9lygUWbE0lD+/gkqQC1zmmdAig= @@ -450,16 +454,17 @@ github.com/aws/aws-sdk-go-v2/service/emr v1.28.7/go.mod h1:NjDlvuvjuHi3uh3r4mXnS github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 h1:qGv+oW4uV1T3kbE9uSYEfdZbo38OqxgRxxfStfDr4BU= github.com/aws/aws-sdk-go-v2/service/iam v1.22.5/go.mod h1:8lyPrjQczmx72ac9s82zTjf9xLqs7uuFMG9TVEZ07XU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15 h1:7R8uRYyXzdD71KWVCL78lJZltah6VVznXBazvKjfH58= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15/go.mod h1:26SQUPcTNgV1Tapwdt4a1rOsYRsnBsJHLMPoxK2b0d8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 h1:e3PCNeEaev/ZF01cQyNZgmYE9oYYePIMJs2mWSKG514= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3/go.mod h1:gIeeNyaL8tIEqZrzAnTeyhHcE0yysCtcaP+N9kxLZ+E= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 h1:skaFGzv+3kA+v2BPKhuekeb1Hbb105+44r8ASC+q5SE= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38/go.mod h1:epIZoRSSbRIwLPJU5F+OldHhwZPBdpDeQkRdCeY3+00= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 h1:UKjpIDLVF90RfV88XurdduMoTxPqtGHZMIDYZQM7RO4= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35/go.mod h1:B3dUg0V6eJesUTi+m27NUkj7n8hdDKYUpxj8f4+TqaQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.1 h1:2OXw3ppu1XsB6rqKEMV4tnecTjIY3PRV2U6IP6KPJQo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.1/go.mod h1:FZB4AdakIqW/yERVdGJA6Z9jraax1beXfhBBnK2wwR8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 h1:EamsKe+ZjkOQjDdHd86/JCEucjFKQ9T0atWKO4s2Lgs= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8/go.mod h1:Q0vV3/csTpbkfKLI5Sb56cJQTCTtJ0ixdb7P+Wedqiw= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 h1:9ulSU5ClouoPIYhDQdg9tpl83d5Yb91PXTKK+17q+ow= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6/go.mod h1:lnc2taBsR9nTlz9meD+lhFZZ9EWY712QHrRflWpTcOA= github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 h1:DyJVI9uQB+mO4IuKEE4AloqOvo9XFg7olhZkwWZJ7wc= @@ -486,13 +491,15 @@ github.com/aws/aws-sdk-go-v2/service/sns v1.21.5 h1:KI6xffjUcP3KgpJEtKefQL8B7AXF github.com/aws/aws-sdk-go-v2/service/sns v1.21.5/go.mod h1:eEjNDG7Y1BH7Ci9qKVH2L02se84z5GPCqXKcqEUpnXg= github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5 h1:RyDpTOMEJO6ycxw1vU/6s0KLFaH3M0z/z9gXHSndPTk= github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5/go.mod h1:RZBu4jmYz3Nikzpu/VuVvRnTEJ5a+kf36WT2fcl5Q+Q= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 h1:HFiiRkf1SdaAmV3/BHOFZ9DjFynPHj8G/UIO1lQS+fk= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 h1:xJPydhNm0Hiqct5TVKEuHG7weC0+sOs4MUnd7A5n5F4= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.2/go.mod h1:zxk6y1X2KXThESWMS5CrKRvISD8mbIMab6nZrCGxDG0= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 h1:8dU9zqA77C5egbU6yd4hFLaiIdPv3rU+6cp7sz5FjCU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2/go.mod h1:7Lt5mjQ8x5rVdKqg+sKKDeuwoszDJIIPmkd8BVsEdS0= github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.0 h1:sYIFy8tm1xQwRvVQ4CRuBGXKIg9sHNuG6+3UAQuoujk= -github.com/aws/aws-sdk-go-v2/service/sts v1.25.0/go.mod h1:S/LOQUeYDfJeJpFCIJDMjy7dwL4aA33HUdVi+i7uH8k= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 h1:fFrLsy08wEbAisqW3KDl/cPHrF43GmV79zXB9EwJiZw= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.2/go.mod h1:7Ld9eTqocTvJqqJ5K/orbSDwmGcpRdlDiLjz2DO+SL8= github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 h1:+gN/oR6jT53ggl+jd/7wO4A7u9r1GLCpMiRiatD79WQ= github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1/go.mod h1:56TIMTOeThR8Ep+O82yxpTuGzCOzZuo3XmsJXxukgUo= github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= From 108a5b05ced7967ad9fcbfc3768f57d0c45ef7de Mon Sep 17 00:00:00 2001 From: Sourav Patnaik <30291806+sourav977@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:34:19 +0530 Subject: [PATCH 035/108] feat(secret): added support of Docker registry credentials (#5720) Co-authored-by: DmitriyLewen --- pkg/fanal/secret/builtin-rules.go | 10 +++ pkg/fanal/secret/scanner_test.go | 71 ++++++++++++++++++++ pkg/fanal/secret/testdata/docker-secrets.txt | 4 ++ 3 files changed, 85 insertions(+) create mode 100644 pkg/fanal/secret/testdata/docker-secrets.txt diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index b868967b6696..4c434e89253d 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -68,6 +68,7 @@ var ( CategoryLinkedIn = types.SecretRuleCategory("LinkedIn") CategoryTwitch = types.SecretRuleCategory("Twitch") CategoryTypeform = types.SecretRuleCategory("Typeform") + CategoryDocker = types.SecretRuleCategory("Docker") ) // Reusable regex patterns @@ -792,4 +793,13 @@ var builtinRules = []Rule{ SecretGroupName: "secret", Keywords: []string{"typeform"}, }, + { + ID: "dockerconfig-secret", + Category: CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + Regex: MustCompile(`(?i)(\.(dockerconfigjson|dockercfg):\s*\|*\s*(?P(ey|ew)+[A-Za-z0-9\/\+=]+))`), + SecretGroupName: "secret", + Keywords: []string{"dockerc"}, + }, } diff --git a/pkg/fanal/secret/scanner_test.go b/pkg/fanal/secret/scanner_test.go index 659b1f91a179..2fe6c7736345 100644 --- a/pkg/fanal/secret/scanner_test.go +++ b/pkg/fanal/secret/scanner_test.go @@ -526,6 +526,68 @@ func TestSecretScanner(t *testing.T) { }, }, } + wantFindingDockerKey1 := types.SecretFinding{ + RuleID: "dockerconfig-secret", + Category: secret.CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + StartLine: 4, + EndLine: 4, + Match: " .dockercfg: ************", + Code: types.Code{ + Lines: []types.Line{ + { + Number: 2, + Content: " .dockerconfigjson: ************", + Highlighted: " .dockerconfigjson: ************", + }, + { + Number: 3, + Content: "data2:", + Highlighted: "data2:", + }, + { + Number: 4, + Content: " .dockercfg: ************", + Highlighted: " .dockercfg: ************", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + }, + }, + } + wantFindingDockerKey2 := types.SecretFinding{ + RuleID: "dockerconfig-secret", + Category: secret.CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + StartLine: 2, + EndLine: 2, + Match: " .dockerconfigjson: ************", + Code: types.Code{ + Lines: []types.Line{ + { + Number: 1, + Content: "data1:", + Highlighted: "data1:", + }, + { + Number: 2, + Content: " .dockerconfigjson: ************", + Highlighted: " .dockerconfigjson: ************", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + { + Number: 3, + Content: "data2:", + Highlighted: "data2:", + }, + }, + }, + } wantMultiLine := types.SecretFinding{ RuleID: "multi-line-secret", Category: "general", @@ -609,6 +671,15 @@ func TestSecretScanner(t *testing.T) { Findings: []types.SecretFinding{wantFindingAsymmetricPrivateKeyJson}, }, }, + { + name: "find Docker registry credentials", + configPath: filepath.Join("testdata", "skip-test.yaml"), + inputFilePath: filepath.Join("testdata", "docker-secrets.txt"), + want: types.Secret{ + FilePath: filepath.Join("testdata", "docker-secrets.txt"), + Findings: []types.SecretFinding{wantFindingDockerKey1, wantFindingDockerKey2}, + }, + }, { name: "include when keyword found", configPath: filepath.Join("testdata", "config-happy-keywords.yaml"), diff --git a/pkg/fanal/secret/testdata/docker-secrets.txt b/pkg/fanal/secret/testdata/docker-secrets.txt new file mode 100644 index 000000000000..9bd5b12cfd38 --- /dev/null +++ b/pkg/fanal/secret/testdata/docker-secrets.txt @@ -0,0 +1,4 @@ +data1: + .dockerconfigjson: eyE1x2a3MpLe +data2: + .dockercfg: ewE1x2a3MpLe \ No newline at end of file From a5342da0670589f580e8b59a0c2bd42b778df76d Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Wed, 6 Dec 2023 10:07:31 +0300 Subject: [PATCH 036/108] fix(misconf): add an image misconf to result (#5731) --- pkg/scanner/local/scan.go | 3 +- pkg/scanner/local/scan_test.go | 126 +++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index 63822852cb71..edb39b15ae8f 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -211,7 +211,8 @@ func (s Scanner) fillPkgsInVulns(pkgResults, vulnResults types.Results) types.Re } func (s Scanner) misconfsToResults(misconfs []ftypes.Misconfiguration, options types.ScanOptions) types.Results { - if !ShouldScanMisconfigOrRbac(options.Scanners) { + if !ShouldScanMisconfigOrRbac(options.Scanners) && + !options.ImageConfigScanners.Enabled(types.MisconfigScanner) { return nil } diff --git a/pkg/scanner/local/scan_test.go b/pkg/scanner/local/scan_test.go index 5b5b8e9fd5d3..2cee7311f73f 100644 --- a/pkg/scanner/local/scan_test.go +++ b/pkg/scanner/local/scan_test.go @@ -1111,6 +1111,132 @@ func TestScanner_Scan(t *testing.T) { }, wantErr: "failed to scan application libraries", }, + { + name: "scan image history", + args: args{ + target: "alpine:latest", + layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, + options: types.ScanOptions{ + ImageConfigScanners: types.Scanners{types.MisconfigScanner}, + }, + }, + fixtures: []string{"testdata/fixtures/happy.yaml"}, + applyLayersExpectation: ApplierApplyLayersExpectation{ + Args: ApplierApplyLayersArgs{ + BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, + }, + Returns: ApplierApplyLayersReturns{ + Detail: ftypes.ArtifactDetail{ + OS: ftypes.OS{ + Family: ftypes.Alpine, + Name: "3.11", + }, + Misconfigurations: []ftypes.Misconfiguration{ + { + FileType: ftypes.Dockerfile, + FilePath: "Dockerfile", + Successes: ftypes.MisconfResults{ + { + Namespace: "builtin.dockerfile.DS001", + Query: "data.builtin.dockerfile.DS001.deny", + Message: "", + PolicyMetadata: ftypes.PolicyMetadata{ + ID: "DS001", + AVDID: "AVD-DS-0001", + Type: "Dockerfile Security Check", + Title: "':latest' tag used", + Description: "When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.", + Severity: "MEDIUM", + RecommendedActions: "Add a tag to the image in the 'FROM' statement", + }, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + }, + Failures: ftypes.MisconfResults{ + { + Namespace: "builtin.dockerfile.DS002", + Query: "data.builtin.dockerfile.DS002.deny", + Message: "Specify at least 1 USER command in Dockerfile with non-root user as argument", + PolicyMetadata: ftypes.PolicyMetadata{ + ID: "DS002", + AVDID: "AVD-DS-0002", + Type: "Dockerfile Security Check", + Title: "Image user should not be 'root'", + Description: "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", + Severity: "HIGH", + RecommendedActions: "Add 'USER ' line to the Dockerfile", + }, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + }, + }, + }, + }, + }, + }, + wantResults: types.Results{ + { + Target: "Dockerfile", + Class: types.ClassConfig, + Type: ftypes.Dockerfile, + Misconfigurations: []types.DetectedMisconfiguration{ + { + Namespace: "builtin.dockerfile.DS002", + Query: "data.builtin.dockerfile.DS002.deny", + Message: "Specify at least 1 USER command in Dockerfile with non-root user as argument", + Type: "Dockerfile Security Check", + ID: "DS002", + AVDID: "AVD-DS-0002", + Title: "Image user should not be 'root'", + Description: "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", + Severity: "HIGH", + Resolution: "Add 'USER ' line to the Dockerfile", + Status: types.StatusFailure, + PrimaryURL: "https://avd.aquasec.com/misconfig/ds002", + References: []string{"https://avd.aquasec.com/misconfig/ds002"}, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + }, + { + Namespace: "builtin.dockerfile.DS001", + Query: "data.builtin.dockerfile.DS001.deny", + Message: "No issues found", + Type: "Dockerfile Security Check", + ID: "DS001", + AVDID: "AVD-DS-0001", + Title: "':latest' tag used", + Description: "When using a 'FROM' statement you should use a specific tag to avoid uncontrolled behavior when the image is updated.", + Severity: "MEDIUM", + Resolution: "Add a tag to the image in the 'FROM' statement", + Status: types.StatusPassed, + CauseMetadata: ftypes.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + Code: ftypes.Code{}, + }, + PrimaryURL: "https://avd.aquasec.com/misconfig/ds001", + References: []string{"https://avd.aquasec.com/misconfig/ds001"}, + }, + }, + }, + }, + wantOS: ftypes.OS{ + Family: "alpine", + Name: "3.11", + Eosl: false, + }, + }, } for _, tt := range tests { From be1c55497f863c13dd92e6b8ca3980678ddf707a Mon Sep 17 00:00:00 2001 From: Sourav Patnaik <30291806+sourav977@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:15:22 +0530 Subject: [PATCH 037/108] feat(secret): add support of GitHub fine-grained tokens (#5740) Co-authored-by: DmitriyLewen --- pkg/fanal/secret/builtin-rules.go | 8 ++++++ pkg/fanal/secret/scanner_test.go | 30 ++++++++++++++++++++++ pkg/fanal/secret/testdata/github-token.txt | 1 + 3 files changed, 39 insertions(+) create mode 100644 pkg/fanal/secret/testdata/github-token.txt diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index 4c434e89253d..ce6baa99a245 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -142,6 +142,14 @@ var builtinRules = []Rule{ Regex: MustCompile(`ghr_[0-9a-zA-Z]{76}`), Keywords: []string{"ghr_"}, }, + { + ID: "github-fine-grained-pat", + Category: CategoryGitHub, + Title: "GitHub Fine-grained personal access tokens", + Severity: "CRITICAL", + Regex: MustCompile(`github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}`), + Keywords: []string{"github_pat_"}, + }, { ID: "gitlab-pat", Category: CategoryGitLab, diff --git a/pkg/fanal/secret/scanner_test.go b/pkg/fanal/secret/scanner_test.go index 2fe6c7736345..7f11c6731ac5 100644 --- a/pkg/fanal/secret/scanner_test.go +++ b/pkg/fanal/secret/scanner_test.go @@ -297,6 +297,27 @@ func TestSecretScanner(t *testing.T) { }, }, } + wantFindingGitHubPAT := types.SecretFinding{ + RuleID: "github-fine-grained-pat", + Category: secret.CategoryGitHub, + Title: "GitHub Fine-grained personal access tokens", + Severity: "CRITICAL", + StartLine: 1, + EndLine: 1, + Match: "GITHUB_TOKEN=*********************************************************************************************", + Code: types.Code{ + Lines: []types.Line{ + { + Number: 1, + Content: "GITHUB_TOKEN=*********************************************************************************************", + Highlighted: "GITHUB_TOKEN=*********************************************************************************************", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + }, + }, + } wantFindingGHButDisableAWS := types.SecretFinding{ RuleID: "github-pat", Category: secret.CategoryGitHub, @@ -721,6 +742,15 @@ func TestSecretScanner(t *testing.T) { Findings: []types.SecretFinding{wantFinding5a, wantFinding6}, }, }, + { + name: "should find GitHub Personal Access Token (classic)", + configPath: filepath.Join("testdata", "skip-test.yaml"), + inputFilePath: "testdata/github-token.txt", + want: types.Secret{ + FilePath: "testdata/github-token.txt", + Findings: []types.SecretFinding{wantFindingGitHubPAT}, + }, + }, { name: "should enable github-pat builtin rule, but disable aws-access-key-id rule", configPath: filepath.Join("testdata", "config-enable-ghp.yaml"), diff --git a/pkg/fanal/secret/testdata/github-token.txt b/pkg/fanal/secret/testdata/github-token.txt new file mode 100644 index 000000000000..6c7026200bbb --- /dev/null +++ b/pkg/fanal/secret/testdata/github-token.txt @@ -0,0 +1 @@ +GITHUB_TOKEN=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 \ No newline at end of file From eb9741954ca809407148423c8826e3cb8af4ca19 Mon Sep 17 00:00:00 2001 From: Dirk Klimpel <5740567+dklimpel@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:13:43 +0100 Subject: [PATCH 038/108] fix(report): update Gitlab template (#5721) --- contrib/gitlab.tpl | 34 ++++++++--- integration/testdata/alpine-310.gitlab.golden | 57 +++++++++---------- pkg/report/template.go | 5 +- pkg/report/template_test.go | 2 +- pkg/report/writer.go | 2 +- 5 files changed, 59 insertions(+), 41 deletions(-) diff --git a/contrib/gitlab.tpl b/contrib/gitlab.tpl index bc5dc3dc9c28..187438776b72 100644 --- a/contrib/gitlab.tpl +++ b/contrib/gitlab.tpl @@ -1,6 +1,29 @@ {{- /* Template based on https://docs.gitlab.com/ee/user/application_security/container_scanning/#reports-json-format */ -}} { - "version": "14.0.6", + "version": "15.0.7", + "scan": { + "analyzer": { + "id": "trivy", + "name": "Trivy", + "vendor": { + "name": "Aqua Security" + }, + "version": "{{ appVersion }}" + }, + "end_time": "{{ now | date "2006-01-02T15:04:05" }}", + "scanner": { + "id": "trivy", + "name": "Trivy", + "url": "https://github.com/aquasecurity/trivy/", + "vendor": { + "name": "Aqua Security" + }, + "version": "{{ appVersion }}" + }, + "start_time": "{{ now | date "2006-01-02T15:04:05" }}", + "status": "success", + "type": "container_scanning" + }, "vulnerabilities": [ {{- $t_first := true }} {{- range . }} @@ -14,11 +37,8 @@ {{- end }} { "id": "{{ .VulnerabilityID }}", - "category": "container_scanning", - "message": {{ .Title | printf "%q" }}, + "name": {{ .Title | printf "%q" }}, "description": {{ .Description | printf "%q" }}, - {{- /* cve is a deprecated key, use id instead */}} - "cve": "{{ .VulnerabilityID }}", "severity": {{ if eq .Severity "UNKNOWN" -}} "Unknown" {{- else if eq .Severity "LOW" -}} @@ -37,10 +57,6 @@ {{- else -}} "No solution provided" {{- end }}, - "scanner": { - "id": "trivy", - "name": "trivy" - }, "location": { "dependency": { "package": { diff --git a/integration/testdata/alpine-310.gitlab.golden b/integration/testdata/alpine-310.gitlab.golden index e006c9a34db3..ad769b31959e 100644 --- a/integration/testdata/alpine-310.gitlab.golden +++ b/integration/testdata/alpine-310.gitlab.golden @@ -1,18 +1,35 @@ { - "version": "14.0.6", + "version": "15.0.7", + "scan": { + "analyzer": { + "id": "trivy", + "name": "Trivy", + "vendor": { + "name": "Aqua Security" + }, + "version": "dev" + }, + "end_time": "2021-08-25T12:20:30", + "scanner": { + "id": "trivy", + "name": "Trivy", + "url": "https://github.com/aquasecurity/trivy/", + "vendor": { + "name": "Aqua Security" + }, + "version": "dev" + }, + "start_time": "2021-08-25T12:20:30", + "status": "success", + "type": "container_scanning" + }, "vulnerabilities": [ { "id": "CVE-2019-1549", - "category": "container_scanning", - "message": "openssl: information disclosure in fork()", + "name": "openssl: information disclosure in fork()", "description": "OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).", - "cve": "CVE-2019-1549", "severity": "Medium", "solution": "Upgrade libcrypto1.1 to 1.1.1d-r0", - "scanner": { - "id": "trivy", - "name": "trivy" - }, "location": { "dependency": { "package": { @@ -76,16 +93,10 @@ }, { "id": "CVE-2019-1551", - "category": "container_scanning", - "message": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64", + "name": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64", "description": "There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t).", - "cve": "CVE-2019-1551", "severity": "Medium", "solution": "Upgrade libcrypto1.1 to 1.1.1d-r2", - "scanner": { - "id": "trivy", - "name": "trivy" - }, "location": { "dependency": { "package": { @@ -169,16 +180,10 @@ }, { "id": "CVE-2019-1549", - "category": "container_scanning", - "message": "openssl: information disclosure in fork()", + "name": "openssl: information disclosure in fork()", "description": "OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).", - "cve": "CVE-2019-1549", "severity": "Medium", "solution": "Upgrade libssl1.1 to 1.1.1d-r0", - "scanner": { - "id": "trivy", - "name": "trivy" - }, "location": { "dependency": { "package": { @@ -242,16 +247,10 @@ }, { "id": "CVE-2019-1551", - "category": "container_scanning", - "message": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64", + "name": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64", "description": "There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t).", - "cve": "CVE-2019-1551", "severity": "Medium", "solution": "Upgrade libssl1.1 to 1.1.1d-r2", - "scanner": { - "id": "trivy", - "name": "trivy" - }, "location": { "dependency": { "package": { diff --git a/pkg/report/template.go b/pkg/report/template.go index 4904b8472ecb..d320a420f722 100644 --- a/pkg/report/template.go +++ b/pkg/report/template.go @@ -27,7 +27,7 @@ type TemplateWriter struct { } // NewTemplateWriter is the factory method to return TemplateWriter object -func NewTemplateWriter(output io.Writer, outputTemplate string) (*TemplateWriter, error) { +func NewTemplateWriter(output io.Writer, outputTemplate, appVersion string) (*TemplateWriter, error) { if strings.HasPrefix(outputTemplate, "@") { buf, err := os.ReadFile(strings.TrimPrefix(outputTemplate, "@")) if err != nil { @@ -54,6 +54,9 @@ func NewTemplateWriter(output io.Writer, outputTemplate string) (*TemplateWriter templateFuncMap["sourceID"] = func(input string) dbTypes.SourceID { return dbTypes.SourceID(input) } + templateFuncMap["appVersion"] = func() string { + return appVersion + } // Overwrite functions for k, v := range CustomTemplateFuncMap { diff --git a/pkg/report/template_test.go b/pkg/report/template_test.go index ded1fa8844c9..30db3595680e 100644 --- a/pkg/report/template_test.go +++ b/pkg/report/template_test.go @@ -178,7 +178,7 @@ func TestReportWriter_Template(t *testing.T) { }, } - w, err := report.NewTemplateWriter(&got, tc.template) + w, err := report.NewTemplateWriter(&got, tc.template, "dev") require.NoError(t, err) err = w.Write(inputReport) assert.NoError(t, err) diff --git a/pkg/report/writer.go b/pkg/report/writer.go index e53cad0e0463..c467f921d4d2 100644 --- a/pkg/report/writer.go +++ b/pkg/report/writer.go @@ -78,7 +78,7 @@ func Write(ctx context.Context, report types.Report, option flag.Options) (err e break } var err error - if writer, err = NewTemplateWriter(output, option.Template); err != nil { + if writer, err = NewTemplateWriter(output, option.Template, option.AppVersion); err != nil { return xerrors.Errorf("failed to initialize template writer: %w", err) } case types.FormatSarif: From 01edbda3472ebbbe71f341d1741194ec35de7d69 Mon Sep 17 00:00:00 2001 From: Veronika Priesner <125653631+nika-pr@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:12:26 +0100 Subject: [PATCH 039/108] docs(k8s): replace --scanners config with --scanners misconfig in docs (#5746) --- docs/docs/target/kubernetes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/target/kubernetes.md b/docs/docs/target/kubernetes.md index 7927938482f3..88986b6d3eff 100644 --- a/docs/docs/target/kubernetes.md +++ b/docs/docs/target/kubernetes.md @@ -134,7 +134,7 @@ Filter by scanners (Vulnerabilities, Secrets or Misconfigurations): ``` trivy k8s --scanners=secret --report=summary cluster # or -trivy k8s --scanners=config --report=summary cluster +trivy k8s --scanners=misconfig --report=summary cluster ``` The supported output formats are `table`, which is the default, and `json`. From be5a550491f581311c938f7230b389cb10aacae7 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:30:26 +0600 Subject: [PATCH 040/108] fix(report): don't mark misconfig passed tests as failed in junit.tpl (#5767) --- contrib/junit.tpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/junit.tpl b/contrib/junit.tpl index 0a2d7ee32341..227cfa9246de 100644 --- a/contrib/junit.tpl +++ b/contrib/junit.tpl @@ -14,8 +14,7 @@ {{- end }} -{{- $failures := len .Misconfigurations }} - + {{- if not (eq .Type "") }} @@ -23,7 +22,9 @@ {{- end -}} {{ range .Misconfigurations }} + {{- if (eq .Status "FAIL") }} {{ escapeXML .Description }} + {{- end }} {{- end }} From 9b4bcedf0ec151c950ce52bf41bcc6ebb1bc9a7a Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:33:41 +0600 Subject: [PATCH 041/108] refactor(vuln): don't remove VendorSeverity in JSON report (#5761) --- integration/testdata/almalinux-8.json.golden | 12 +++++ .../testdata/alpine-310-registry.json.golden | 32 +++++++++++++ integration/testdata/alpine-310.json.golden | 32 +++++++++++++ .../alpine-39-high-critical.json.golden | 6 +++ .../alpine-39-ignore-cveids.json.golden | 16 +++++++ integration/testdata/alpine-39.json.golden | 38 ++++++++++++++++ .../testdata/alpine-distroless.json.golden | 3 ++ integration/testdata/amazon-1.json.golden | 9 ++++ integration/testdata/amazon-2.json.golden | 18 ++++++++ .../amazonlinux2-gp2-x86-vm.json.golden | 6 +++ .../busybox-with-lockfile.json.golden | 6 +++ integration/testdata/centos-6.json.golden | 16 +++++++ .../centos-7-ignore-unfixed.json.golden | 18 ++++++++ .../testdata/centos-7-medium.json.golden | 8 ++++ integration/testdata/centos-7.json.golden | 26 +++++++++++ integration/testdata/cocoapods.json.golden | 3 ++ .../testdata/composer.lock.json.golden | 3 ++ integration/testdata/conda-spdx.json.golden | 24 +++++----- .../debian-buster-ignore-unfixed.json.golden | 6 +++ .../testdata/debian-buster.json.golden | 15 +++++++ .../testdata/debian-stretch.json.golden | 45 +++++++++++++++++++ .../testdata/distroless-base.json.golden | 32 +++++++++++++ .../testdata/distroless-python27.json.golden | 32 +++++++++++++ integration/testdata/dotnet.json.golden | 3 ++ integration/testdata/fluentd-gems.json.golden | 11 +++++ .../fluentd-multiple-lockfiles.json.golden | 20 +++++++++ integration/testdata/gomod-skip.json.golden | 3 ++ integration/testdata/gomod.json.golden | 3 ++ integration/testdata/gradle.json.golden | 10 +++++ integration/testdata/mariner-1.0.json.golden | 8 ++++ .../testdata/minikube-kbom.json.golden | 3 ++ integration/testdata/mix.lock.json.golden | 3 ++ integration/testdata/npm-with-dev.json.golden | 12 +++++ integration/testdata/npm.json.golden | 12 +++++ integration/testdata/nuget.json.golden | 3 ++ .../testdata/opensuse-leap-151.json.golden | 6 +++ .../testdata/oraclelinux-8.json.golden | 18 ++++++++ .../testdata/packagesprops.json.golden | 3 ++ integration/testdata/photon-30.json.golden | 26 +++++++++++ integration/testdata/pip.json.golden | 12 +++++ integration/testdata/pipenv.json.golden | 12 +++++ integration/testdata/pnpm.json.golden | 17 +++++++ integration/testdata/poetry.json.golden | 6 +++ integration/testdata/pom.json.golden | 10 +++++ integration/testdata/pubspec.lock.json.golden | 3 ++ integration/testdata/rockylinux-8.json.golden | 12 +++++ .../testdata/spring4shell-jre11.json.golden | 5 +++ .../testdata/spring4shell-jre8.json.golden | 5 +++ integration/testdata/swift.json.golden | 3 ++ integration/testdata/test-repo.json.golden | 6 +++ integration/testdata/ubi-7.json.golden | 8 ++++ .../ubuntu-1804-ignore-unfixed.json.golden | 36 +++++++++++++++ integration/testdata/ubuntu-1804.json.golden | 44 ++++++++++++++++++ .../testdata/ubuntu-gp2-x86-vm.json.golden | 7 +++ integration/testdata/yarn.json.golden | 12 +++++ pkg/report/json_test.go | 3 ++ pkg/report/predicate/vuln_test.go | 3 ++ pkg/types/report.go | 17 ------- 58 files changed, 742 insertions(+), 29 deletions(-) diff --git a/integration/testdata/almalinux-8.json.golden b/integration/testdata/almalinux-8.json.golden index 824279932ef2..c2ae9382f4b4 100644 --- a/integration/testdata/almalinux-8.json.golden +++ b/integration/testdata/almalinux-8.json.golden @@ -76,6 +76,18 @@ "CweIDs": [ "CWE-125" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 3, + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 2, + "rocky": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:P", diff --git a/integration/testdata/alpine-310-registry.json.golden b/integration/testdata/alpine-310-registry.json.golden index c5336caaa4ed..df64131304b2 100644 --- a/integration/testdata/alpine-310-registry.json.golden +++ b/integration/testdata/alpine-310-registry.json.golden @@ -84,6 +84,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -145,6 +153,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -216,6 +232,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -277,6 +301,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/alpine-310.json.golden b/integration/testdata/alpine-310.json.golden index 6b0f8fb57389..8c591c26815c 100644 --- a/integration/testdata/alpine-310.json.golden +++ b/integration/testdata/alpine-310.json.golden @@ -78,6 +78,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -139,6 +147,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -210,6 +226,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -271,6 +295,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/alpine-39-high-critical.json.golden b/integration/testdata/alpine-39-high-critical.json.golden index 3d9a5acc2c12..fc61f908f444 100644 --- a/integration/testdata/alpine-39-high-critical.json.golden +++ b/integration/testdata/alpine-39-high-critical.json.golden @@ -77,6 +77,9 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "nvd": 4 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -116,6 +119,9 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "nvd": 4 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/alpine-39-ignore-cveids.json.golden b/integration/testdata/alpine-39-ignore-cveids.json.golden index 1d187b9ed057..e620ebe42066 100644 --- a/integration/testdata/alpine-39-ignore-cveids.json.golden +++ b/integration/testdata/alpine-39-ignore-cveids.json.golden @@ -78,6 +78,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -149,6 +157,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/alpine-39.json.golden b/integration/testdata/alpine-39.json.golden index f5dc05335673..7781ccc44c21 100644 --- a/integration/testdata/alpine-39.json.golden +++ b/integration/testdata/alpine-39.json.golden @@ -78,6 +78,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -139,6 +147,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -210,6 +226,14 @@ "CweIDs": [ "CWE-330" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -271,6 +295,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -341,6 +373,9 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "nvd": 4 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -380,6 +415,9 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "nvd": 4 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/alpine-distroless.json.golden b/integration/testdata/alpine-distroless.json.golden index 5dc55d99806b..6896e3c56053 100644 --- a/integration/testdata/alpine-distroless.json.golden +++ b/integration/testdata/alpine-distroless.json.golden @@ -67,6 +67,9 @@ "CweIDs": [ "CWE-427" ], + "VendorSeverity": { + "ubuntu": 2 + }, "References": [ "http://www.openwall.com/lists/oss-security/2022/04/12/7", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24765", diff --git a/integration/testdata/amazon-1.json.golden b/integration/testdata/amazon-1.json.golden index 9324ad548ed2..dde37a90724c 100644 --- a/integration/testdata/amazon-1.json.golden +++ b/integration/testdata/amazon-1.json.golden @@ -77,6 +77,15 @@ "CweIDs": [ "CWE-415" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 4, + "oracle-oval": 2, + "photon": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/amazon-2.json.golden b/integration/testdata/amazon-2.json.golden index 5b19f2d5e006..ba19b615dfd7 100644 --- a/integration/testdata/amazon-2.json.golden +++ b/integration/testdata/amazon-2.json.golden @@ -77,6 +77,15 @@ "CweIDs": [ "CWE-415" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 4, + "oracle-oval": 2, + "photon": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -136,6 +145,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 1, + "arch-linux": 3, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 1, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden index aa3b62adbcb8..fe220cabad2e 100644 --- a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden +++ b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden @@ -43,6 +43,12 @@ "Title": "bind: memory leak in ECDSA DNSSEC verification code", "Description": "By spoofing the target resolver with responses that have a malformed ECDSA signature, an attacker can trigger a small memory leak. It is possible to gradually erode available memory to the point where named crashes for lack of resources.", "Severity": "MEDIUM", + "VendorSeverity": { + "arch-linux": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N", diff --git a/integration/testdata/busybox-with-lockfile.json.golden b/integration/testdata/busybox-with-lockfile.json.golden index f17f8796aa8b..8c02e02b4d6f 100644 --- a/integration/testdata/busybox-with-lockfile.json.golden +++ b/integration/testdata/busybox-with-lockfile.json.golden @@ -76,6 +76,9 @@ "CweIDs": [ "CWE-674" ], + "VendorSeverity": { + "nvd": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", @@ -115,6 +118,9 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "nvd": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/centos-6.json.golden b/integration/testdata/centos-6.json.golden index 3fbca6d85ad6..d8cb95553e79 100644 --- a/integration/testdata/centos-6.json.golden +++ b/integration/testdata/centos-6.json.golden @@ -93,6 +93,14 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", @@ -139,6 +147,14 @@ "CweIDs": [ "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/centos-7-ignore-unfixed.json.golden b/integration/testdata/centos-7-ignore-unfixed.json.golden index f27d99919849..49777f004005 100644 --- a/integration/testdata/centos-7-ignore-unfixed.json.golden +++ b/integration/testdata/centos-7-ignore-unfixed.json.golden @@ -87,6 +87,14 @@ "CweIDs": [ "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", @@ -169,6 +177,16 @@ "CweIDs": [ "CWE-327" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 1, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/centos-7-medium.json.golden b/integration/testdata/centos-7-medium.json.golden index 955c833a34c1..eb54be5b1315 100644 --- a/integration/testdata/centos-7-medium.json.golden +++ b/integration/testdata/centos-7-medium.json.golden @@ -87,6 +87,14 @@ "CweIDs": [ "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/centos-7.json.golden b/integration/testdata/centos-7.json.golden index e549fdac14db..333ce10d4e5f 100644 --- a/integration/testdata/centos-7.json.golden +++ b/integration/testdata/centos-7.json.golden @@ -83,6 +83,14 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -133,6 +141,14 @@ "CweIDs": [ "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", @@ -215,6 +231,16 @@ "CweIDs": [ "CWE-327" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 1, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/cocoapods.json.golden b/integration/testdata/cocoapods.json.golden index 35ea7c41a051..71c4651e8158 100644 --- a/integration/testdata/cocoapods.json.golden +++ b/integration/testdata/cocoapods.json.golden @@ -41,6 +41,9 @@ "Title": "SwiftNIO vulnerable to Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')", "Description": "`NIOHTTP1` and projects using it for generating HTTP responses, including SwiftNIO, can be subject to a HTTP Response Injection attack...", "Severity": "MEDIUM", + "VendorSeverity": { + "ghsa": 2 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", diff --git a/integration/testdata/composer.lock.json.golden b/integration/testdata/composer.lock.json.golden index 6b8dbc6cf6bc..02718c7cab3d 100644 --- a/integration/testdata/composer.lock.json.golden +++ b/integration/testdata/composer.lock.json.golden @@ -78,6 +78,9 @@ "CweIDs": [ "CWE-20" ], + "VendorSeverity": { + "ghsa": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N", diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index 9fc685b4aa5b..73b3394e6697 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -75,23 +75,23 @@ ], "files": [ { - "fileName": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json", - "SPDXID": "SPDXRef-File-600e5e0110a84891", + "fileName": "miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json", + "SPDXID": "SPDXRef-File-7eb62e2a3edddc0a", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "237db0da53131e4548cb1181337fa0f420299e1f" + "checksumValue": "a6a2db7668f1ad541d704369fc66c96a4415aa24" } ], "copyrightText": "" }, { - "fileName": "miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json", - "SPDXID": "SPDXRef-File-7eb62e2a3edddc0a", + "fileName": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json", + "SPDXID": "SPDXRef-File-600e5e0110a84891", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "a6a2db7668f1ad541d704369fc66c96a4415aa24" + "checksumValue": "237db0da53131e4548cb1181337fa0f420299e1f" } ], "copyrightText": "" @@ -110,22 +110,22 @@ }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-c75d9dc75200186f", + "relatedSpdxElement": "SPDXRef-Package-195557cddf18e4a9", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-c75d9dc75200186f", - "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", + "spdxElementId": "SPDXRef-Package-195557cddf18e4a9", + "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-195557cddf18e4a9", + "relatedSpdxElement": "SPDXRef-Package-c75d9dc75200186f", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-195557cddf18e4a9", - "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", + "spdxElementId": "SPDXRef-Package-c75d9dc75200186f", + "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", "relationshipType": "CONTAINS" } ] diff --git a/integration/testdata/debian-buster-ignore-unfixed.json.golden b/integration/testdata/debian-buster-ignore-unfixed.json.golden index 57c94d41b662..0ef080d4a7a7 100644 --- a/integration/testdata/debian-buster-ignore-unfixed.json.golden +++ b/integration/testdata/debian-buster-ignore-unfixed.json.golden @@ -80,6 +80,12 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/debian-buster.json.golden b/integration/testdata/debian-buster.json.golden index 6124ab93de1b..67a40b7b5a58 100644 --- a/integration/testdata/debian-buster.json.golden +++ b/integration/testdata/debian-buster.json.golden @@ -76,6 +76,15 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "debian": 1, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -131,6 +140,12 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/debian-stretch.json.golden b/integration/testdata/debian-stretch.json.golden index 0b31b5eedaa5..7c8893cbdad7 100644 --- a/integration/testdata/debian-stretch.json.golden +++ b/integration/testdata/debian-stretch.json.golden @@ -77,6 +77,15 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "debian": 1, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -132,6 +141,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -193,6 +211,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -254,6 +281,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -315,6 +351,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/distroless-base.json.golden b/integration/testdata/distroless-base.json.golden index ff3156dacfd6..b9ce4e3b400d 100644 --- a/integration/testdata/distroless-base.json.golden +++ b/integration/testdata/distroless-base.json.golden @@ -75,6 +75,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -150,6 +158,14 @@ "CWE-327", "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 1, + "oracle-oval": 2, + "photon": 1, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", @@ -227,6 +243,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -302,6 +326,14 @@ "CWE-327", "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 1, + "oracle-oval": 2, + "photon": 1, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/distroless-python27.json.golden b/integration/testdata/distroless-python27.json.golden index 4e6a2464b941..d97edd78bfed 100644 --- a/integration/testdata/distroless-python27.json.golden +++ b/integration/testdata/distroless-python27.json.golden @@ -92,6 +92,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -167,6 +175,14 @@ "CWE-327", "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 1, + "oracle-oval": 2, + "photon": 1, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", @@ -244,6 +260,14 @@ "CweIDs": [ "CWE-200" ], + "VendorSeverity": { + "amazon": 1, + "nvd": 2, + "oracle-oval": 1, + "photon": 2, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -319,6 +343,14 @@ "CWE-327", "CWE-203" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 1, + "oracle-oval": 2, + "photon": 1, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/dotnet.json.golden b/integration/testdata/dotnet.json.golden index d04624965482..c2d51a2080aa 100644 --- a/integration/testdata/dotnet.json.golden +++ b/integration/testdata/dotnet.json.golden @@ -54,6 +54,9 @@ "CweIDs": [ "CWE-755" ], + "VendorSeverity": { + "ghsa": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", diff --git a/integration/testdata/fluentd-gems.json.golden b/integration/testdata/fluentd-gems.json.golden index f75e6ac6fb2a..eb24957e0a13 100644 --- a/integration/testdata/fluentd-gems.json.golden +++ b/integration/testdata/fluentd-gems.json.golden @@ -133,6 +133,12 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -195,6 +201,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/fluentd-multiple-lockfiles.json.golden b/integration/testdata/fluentd-multiple-lockfiles.json.golden index a3917f31d7b6..c067638c8dd1 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.json.golden @@ -45,6 +45,15 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "debian": 1, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -97,6 +106,12 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "nvd": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -157,6 +172,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/gomod-skip.json.golden b/integration/testdata/gomod-skip.json.golden index a0ad5e7182cc..8f1e4f643cdc 100644 --- a/integration/testdata/gomod-skip.json.golden +++ b/integration/testdata/gomod-skip.json.golden @@ -65,6 +65,9 @@ "CweIDs": [ "CWE-682" ], + "VendorSeverity": { + "nvd": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/gomod.json.golden b/integration/testdata/gomod.json.golden index fb495a8e07ed..4d553e7ca2c7 100644 --- a/integration/testdata/gomod.json.golden +++ b/integration/testdata/gomod.json.golden @@ -65,6 +65,9 @@ "CweIDs": [ "CWE-682" ], + "VendorSeverity": { + "nvd": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/gradle.json.golden b/integration/testdata/gradle.json.golden index 48c2580b8cba..9ff2b02aeb8d 100644 --- a/integration/testdata/gradle.json.golden +++ b/integration/testdata/gradle.json.golden @@ -41,6 +41,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 4, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P", @@ -97,6 +102,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:C", diff --git a/integration/testdata/mariner-1.0.json.golden b/integration/testdata/mariner-1.0.json.golden index 3c9ccbcd50e3..4b5ac7b7363d 100644 --- a/integration/testdata/mariner-1.0.json.golden +++ b/integration/testdata/mariner-1.0.json.golden @@ -60,6 +60,9 @@ "CweIDs": [ "CWE-122" ], + "VendorSeverity": { + "cbl-mariner": 3 + }, "References": [ "https://github.com/vim/vim/commit/9f8c304c8a390ade133bac29963dc8e56ab14cbc", "https://huntr.dev/bounties/fa795954-8775-4f23-98c6-d4d4d3fe8a82", @@ -91,6 +94,11 @@ "CweIDs": [ "CWE-122" ], + "VendorSeverity": { + "cbl-mariner": 1, + "nvd": 1, + "redhat": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/minikube-kbom.json.golden b/integration/testdata/minikube-kbom.json.golden index 92215cf7b6e3..e144904828e4 100644 --- a/integration/testdata/minikube-kbom.json.golden +++ b/integration/testdata/minikube-kbom.json.golden @@ -48,6 +48,9 @@ "Title": "Bypass of seccomp profile enforcement ", "Description": "A security issue was discovered in Kubelet that allows pods to bypass the seccomp profile enforcement...", "Severity": "LOW", + "VendorSeverity": { + "k8s": 1 + }, "CVSS": { "k8s": { "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N", diff --git a/integration/testdata/mix.lock.json.golden b/integration/testdata/mix.lock.json.golden index b7180404bc3c..76eb19ece6a0 100644 --- a/integration/testdata/mix.lock.json.golden +++ b/integration/testdata/mix.lock.json.golden @@ -161,6 +161,9 @@ "Title": "Phoenix before 1.6.14 mishandles check_origin wildcarding", "Description": "socket/transport.ex in Phoenix before 1.6.14 mishandles check_origin wildcarding. NOTE: LiveView applications are unaffected by default because of the presence of a LiveView CSRF token.", "Severity": "HIGH", + "VendorSeverity": { + "ghsa": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N", diff --git a/integration/testdata/npm-with-dev.json.golden b/integration/testdata/npm-with-dev.json.golden index 9ace83bf5b27..071bfd18d643 100644 --- a/integration/testdata/npm-with-dev.json.golden +++ b/integration/testdata/npm-with-dev.json.golden @@ -257,6 +257,18 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/npm.json.golden b/integration/testdata/npm.json.golden index 94dd11ae41db..ec19f9d5975a 100644 --- a/integration/testdata/npm.json.golden +++ b/integration/testdata/npm.json.golden @@ -240,6 +240,18 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/nuget.json.golden b/integration/testdata/nuget.json.golden index c0285aea9555..5027f75894b4 100644 --- a/integration/testdata/nuget.json.golden +++ b/integration/testdata/nuget.json.golden @@ -71,6 +71,9 @@ "CweIDs": [ "CWE-755" ], + "VendorSeverity": { + "ghsa": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", diff --git a/integration/testdata/opensuse-leap-151.json.golden b/integration/testdata/opensuse-leap-151.json.golden index 5b66db1b580f..ed0c29a6d890 100644 --- a/integration/testdata/opensuse-leap-151.json.golden +++ b/integration/testdata/opensuse-leap-151.json.golden @@ -82,6 +82,9 @@ "Title": "Security update for openssl-1_1", "Description": "This update for openssl-1_1 fixes the following issues:\n\nSecurity issue fixed:\n\n- CVE-2019-1551: Fixed an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli (bsc#1158809). \n\nVarious FIPS related improvements were done:\n\n- FIPS: Backport SSH KDF to openssl (jsc#SLE-8789, bsc#1157775).\n- Port FIPS patches from SLE-12 (bsc#1158101).\n- Use SHA-2 in the RSA pairwise consistency check (bsc#1155346).\n\nThis update was imported from the SUSE:SLE-15-SP1:Update update project.", "Severity": "MEDIUM", + "VendorSeverity": { + "suse-cvrf": 2 + }, "References": [ "https://lists.opensuse.org/opensuse-security-announce/2020-01/msg00030.html", "https://www.suse.com/support/security/rating/" @@ -108,6 +111,9 @@ "Title": "Security update for openssl-1_1", "Description": "This update for openssl-1_1 fixes the following issues:\n\nSecurity issue fixed:\n\n- CVE-2019-1551: Fixed an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli (bsc#1158809). \n\nVarious FIPS related improvements were done:\n\n- FIPS: Backport SSH KDF to openssl (jsc#SLE-8789, bsc#1157775).\n- Port FIPS patches from SLE-12 (bsc#1158101).\n- Use SHA-2 in the RSA pairwise consistency check (bsc#1155346).\n\nThis update was imported from the SUSE:SLE-15-SP1:Update update project.", "Severity": "MEDIUM", + "VendorSeverity": { + "suse-cvrf": 2 + }, "References": [ "https://lists.opensuse.org/opensuse-security-announce/2020-01/msg00030.html", "https://www.suse.com/support/security/rating/" diff --git a/integration/testdata/oraclelinux-8.json.golden b/integration/testdata/oraclelinux-8.json.golden index d44fb10ec399..b00634c1079f 100644 --- a/integration/testdata/oraclelinux-8.json.golden +++ b/integration/testdata/oraclelinux-8.json.golden @@ -86,6 +86,15 @@ "CweIDs": [ "CWE-125" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 3, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", @@ -144,6 +153,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 1, + "arch-linux": 3, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 1, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/packagesprops.json.golden b/integration/testdata/packagesprops.json.golden index 132152aaf744..77a6cb03c51e 100644 --- a/integration/testdata/packagesprops.json.golden +++ b/integration/testdata/packagesprops.json.golden @@ -50,6 +50,9 @@ "CweIDs": [ "CWE-755" ], + "VendorSeverity": { + "ghsa": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", diff --git a/integration/testdata/photon-30.json.golden b/integration/testdata/photon-30.json.golden index f27af155f454..5a97889fd3d6 100644 --- a/integration/testdata/photon-30.json.golden +++ b/integration/testdata/photon-30.json.golden @@ -87,6 +87,14 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -139,6 +147,15 @@ "CweIDs": [ "CWE-415" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 4, + "oracle-oval": 2, + "photon": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", @@ -198,6 +215,15 @@ "CweIDs": [ "CWE-415" ], + "VendorSeverity": { + "amazon": 2, + "arch-linux": 2, + "nvd": 4, + "oracle-oval": 2, + "photon": 4, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/pip.json.golden b/integration/testdata/pip.json.golden index ef4af98f6293..60590d12ea05 100644 --- a/integration/testdata/pip.json.golden +++ b/integration/testdata/pip.json.golden @@ -78,6 +78,12 @@ "CweIDs": [ "CWE-331" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -125,6 +131,12 @@ "CweIDs": [ "CWE-601" ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:N", diff --git a/integration/testdata/pipenv.json.golden b/integration/testdata/pipenv.json.golden index 507ecfe6a45e..f77722278843 100644 --- a/integration/testdata/pipenv.json.golden +++ b/integration/testdata/pipenv.json.golden @@ -54,6 +54,12 @@ "CweIDs": [ "CWE-331" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", @@ -101,6 +107,12 @@ "CweIDs": [ "CWE-601" ], + "VendorSeverity": { + "ghsa": 2, + "nvd": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:N", diff --git a/integration/testdata/pnpm.json.golden b/integration/testdata/pnpm.json.golden index d5001c1758cb..2f69244be160 100644 --- a/integration/testdata/pnpm.json.golden +++ b/integration/testdata/pnpm.json.golden @@ -42,6 +42,18 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", @@ -156,6 +168,11 @@ "Title": "nodejs-lodash: prototype pollution in defaultsDeep function leading to modifying properties", "Description": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", "Severity": "CRITICAL", + "VendorSeverity": { + "ghsa": 4, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:N/I:P/A:P", diff --git a/integration/testdata/poetry.json.golden b/integration/testdata/poetry.json.golden index ac174525bcc4..26f4085bf95b 100644 --- a/integration/testdata/poetry.json.golden +++ b/integration/testdata/poetry.json.golden @@ -66,6 +66,12 @@ "CweIDs": [ "CWE-331" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N", diff --git a/integration/testdata/pom.json.golden b/integration/testdata/pom.json.golden index 249f3c24505b..bf8d69f4125c 100644 --- a/integration/testdata/pom.json.golden +++ b/integration/testdata/pom.json.golden @@ -42,6 +42,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 4, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P", @@ -99,6 +104,11 @@ "CweIDs": [ "CWE-502" ], + "VendorSeverity": { + "ghsa": 3, + "nvd": 3, + "redhat": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:C", diff --git a/integration/testdata/pubspec.lock.json.golden b/integration/testdata/pubspec.lock.json.golden index bceade5a9b6a..a7e76e3153b8 100644 --- a/integration/testdata/pubspec.lock.json.golden +++ b/integration/testdata/pubspec.lock.json.golden @@ -57,6 +57,9 @@ "CweIDs": [ "CWE-74" ], + "VendorSeverity": { + "ghsa": 2 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", diff --git a/integration/testdata/rockylinux-8.json.golden b/integration/testdata/rockylinux-8.json.golden index 67ecc66b246d..c47d69455875 100644 --- a/integration/testdata/rockylinux-8.json.golden +++ b/integration/testdata/rockylinux-8.json.golden @@ -76,6 +76,18 @@ "CweIDs": [ "CWE-125" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 3, + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 2, + "rocky": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:P/I:N/A:P", diff --git a/integration/testdata/spring4shell-jre11.json.golden b/integration/testdata/spring4shell-jre11.json.golden index 1b9d2db6885c..b6ad22e931dd 100644 --- a/integration/testdata/spring4shell-jre11.json.golden +++ b/integration/testdata/spring4shell-jre11.json.golden @@ -218,6 +218,11 @@ "CweIDs": [ "CWE-94" ], + "VendorSeverity": { + "ghsa": 4, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", diff --git a/integration/testdata/spring4shell-jre8.json.golden b/integration/testdata/spring4shell-jre8.json.golden index 13fbc3943355..f894c07d659c 100644 --- a/integration/testdata/spring4shell-jre8.json.golden +++ b/integration/testdata/spring4shell-jre8.json.golden @@ -218,6 +218,11 @@ "CweIDs": [ "CWE-94" ], + "VendorSeverity": { + "ghsa": 4, + "nvd": 4, + "redhat": 3 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", diff --git a/integration/testdata/swift.json.golden b/integration/testdata/swift.json.golden index 10b004671c89..47d1d2850470 100644 --- a/integration/testdata/swift.json.golden +++ b/integration/testdata/swift.json.golden @@ -59,6 +59,9 @@ "Title": "SwiftNIO vulnerable to Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')", "Description": "`NIOHTTP1` and projects using it for generating HTTP responses, including SwiftNIO, can be subject to a HTTP Response Injection attack...", "Severity": "MEDIUM", + "VendorSeverity": { + "ghsa": 2 + }, "CVSS": { "ghsa": { "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", diff --git a/integration/testdata/test-repo.json.golden b/integration/testdata/test-repo.json.golden index 4235056228c0..b98f0e94f0d1 100644 --- a/integration/testdata/test-repo.json.golden +++ b/integration/testdata/test-repo.json.golden @@ -41,6 +41,9 @@ "CweIDs": [ "CWE-674" ], + "VendorSeverity": { + "nvd": 3 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", @@ -77,6 +80,9 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "nvd": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/integration/testdata/ubi-7.json.golden b/integration/testdata/ubi-7.json.golden index c2939762b954..2b382d42ed04 100644 --- a/integration/testdata/ubi-7.json.golden +++ b/integration/testdata/ubi-7.json.golden @@ -94,6 +94,14 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", diff --git a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden index a35729b41d71..8020b35f5982 100644 --- a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden +++ b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden @@ -96,6 +96,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -154,6 +163,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -212,6 +230,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -270,6 +297,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/ubuntu-1804.json.golden b/integration/testdata/ubuntu-1804.json.golden index 8c8d174674b2..bbca0359b3f5 100644 --- a/integration/testdata/ubuntu-1804.json.golden +++ b/integration/testdata/ubuntu-1804.json.golden @@ -95,6 +95,14 @@ "CweIDs": [ "CWE-273" ], + "VendorSeverity": { + "cbl-mariner": 3, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", @@ -147,6 +155,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -205,6 +222,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -263,6 +289,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", @@ -321,6 +356,15 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "amazon": 2, + "cbl-mariner": 2, + "nvd": 2, + "oracle-oval": 2, + "photon": 2, + "redhat": 2, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", diff --git a/integration/testdata/ubuntu-gp2-x86-vm.json.golden b/integration/testdata/ubuntu-gp2-x86-vm.json.golden index 1ec3c1c86015..485dc3712542 100644 --- a/integration/testdata/ubuntu-gp2-x86-vm.json.golden +++ b/integration/testdata/ubuntu-gp2-x86-vm.json.golden @@ -40,6 +40,13 @@ "CweIDs": [ "CWE-787" ], + "VendorSeverity": { + "cbl-mariner": 3, + "nvd": 3, + "photon": 3, + "redhat": 1, + "ubuntu": 2 + }, "CVSS": { "nvd": { "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", diff --git a/integration/testdata/yarn.json.golden b/integration/testdata/yarn.json.golden index 1e9054339883..3002b9f9b992 100644 --- a/integration/testdata/yarn.json.golden +++ b/integration/testdata/yarn.json.golden @@ -59,6 +59,18 @@ "CweIDs": [ "CWE-79" ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, "CVSS": { "nvd": { "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", diff --git a/pkg/report/json_test.go b/pkg/report/json_test.go index 850afd003545..ea486c145327 100644 --- a/pkg/report/json_test.go +++ b/pkg/report/json_test.go @@ -55,6 +55,9 @@ func TestReportWriter_JSON(t *testing.T) { Title: "foobar", Description: "baz", Severity: "HIGH", + VendorSeverity: map[dbTypes.SourceID]dbTypes.Severity{ + vulnerability.NVD: dbTypes.SeverityHigh, + }, }, }, }, diff --git a/pkg/report/predicate/vuln_test.go b/pkg/report/predicate/vuln_test.go index c574141bfa70..a09716b849c0 100644 --- a/pkg/report/predicate/vuln_test.go +++ b/pkg/report/predicate/vuln_test.go @@ -64,6 +64,9 @@ func TestWriter_Write(t *testing.T) { Title: "foobar", Description: "baz", Severity: "HIGH", + VendorSeverity: map[dbTypes.SourceID]dbTypes.Severity{ + vulnerability.NVD: dbTypes.SeverityHigh, + }, }, }, }, diff --git a/pkg/types/report.go b/pkg/types/report.go index c923097ee4a0..9d01a704a081 100644 --- a/pkg/types/report.go +++ b/pkg/types/report.go @@ -1,7 +1,6 @@ package types import ( - "encoding/json" "time" v1 "github.com/google/go-containerregistry/pkg/v1" // nolint: goimports @@ -114,22 +113,6 @@ type Result struct { CustomResources []ftypes.CustomResource `json:"CustomResources,omitempty"` } -func (r *Result) MarshalJSON() ([]byte, error) { - // VendorSeverity includes all vendor severities. - // It would be noisy to users, so it should be removed from the JSON output. - for i := range r.Vulnerabilities { - r.Vulnerabilities[i].VendorSeverity = nil - } - - // Notice the Alias struct prevents MarshalJSON being called infinitely - type ResultAlias Result - return json.Marshal(&struct { - *ResultAlias - }{ - ResultAlias: (*ResultAlias)(r), - }) -} - func (r *Result) IsEmpty() bool { return len(r.Packages) == 0 && len(r.Vulnerabilities) == 0 && len(r.Misconfigurations) == 0 && len(r.Secrets) == 0 && len(r.Licenses) == 0 && len(r.CustomResources) == 0 From c317fe828d6d2630bad014d4f185037f3b24df2b Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:34:37 +0600 Subject: [PATCH 042/108] fix(report): fix error if miconfigs are empty (#5782) --- contrib/junit.tpl | 7 +++++- integration/client_server_test.go | 9 +++++++ integration/testdata/alpine-310.junit.golden | 25 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 integration/testdata/alpine-310.junit.golden diff --git a/contrib/junit.tpl b/contrib/junit.tpl index 227cfa9246de..08e649b9eb00 100644 --- a/contrib/junit.tpl +++ b/contrib/junit.tpl @@ -14,7 +14,12 @@ {{- end }} - + +{{- if .MisconfSummary }} + +{{- else }} + +{{- end }} {{- if not (eq .Type "") }} diff --git a/integration/client_server_test.go b/integration/client_server_test.go index 6a85ca0b50a2..0fd0d0522ed9 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -344,6 +344,15 @@ func TestClientServerWithFormat(t *testing.T) { }, golden: "testdata/alpine-310.html.golden", }, + { + name: "alpine 3.10 with junit template", + args: csArgs{ + Format: "template", + TemplatePath: "@../contrib/junit.tpl", + Input: "testdata/fixtures/images/alpine-310.tar.gz", + }, + golden: "testdata/alpine-310.junit.golden", + }, { name: "alpine 3.10 with github dependency snapshots format", args: csArgs{ diff --git a/integration/testdata/alpine-310.junit.golden b/integration/testdata/alpine-310.junit.golden new file mode 100644 index 000000000000..b3f5aab40c3b --- /dev/null +++ b/integration/testdata/alpine-310.junit.golden @@ -0,0 +1,25 @@ + + + + + + + + OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). + + + There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t). + + + OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). + + + There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t). + + + + + + + + From 6cc00c2f0c18901522ed2e32d5b07912bb37b4a3 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:37:14 +0600 Subject: [PATCH 043/108] fix(report): use OS information for OS packages purl in `github` template (#5783) --- integration/testdata/alpine-310.gsbom.golden | 28 ++++++++--------- pkg/report/github/github.go | 6 ++-- pkg/report/github/github_test.go | 32 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/integration/testdata/alpine-310.gsbom.golden b/integration/testdata/alpine-310.gsbom.golden index 006efffebf05..699b07520428 100644 --- a/integration/testdata/alpine-310.gsbom.golden +++ b/integration/testdata/alpine-310.gsbom.golden @@ -17,7 +17,7 @@ "name": "alpine", "resolved": { "alpine-baselayout": { - "package_url": "pkg:apk/alpine-baselayout@3.1.2-r0", + "package_url": "pkg:apk/alpine/alpine-baselayout@3.1.2-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "busybox@1.30.1-r2", @@ -26,12 +26,12 @@ "scope": "runtime" }, "alpine-keys": { - "package_url": "pkg:apk/alpine-keys@2.1-r2", + "package_url": "pkg:apk/alpine/alpine-keys@2.1-r2?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "scope": "runtime" }, "apk-tools": { - "package_url": "pkg:apk/apk-tools@2.10.4-r2", + "package_url": "pkg:apk/alpine/apk-tools@2.10.4-r2?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "libcrypto1.1@1.1.1c-r0", @@ -42,7 +42,7 @@ "scope": "runtime" }, "busybox": { - "package_url": "pkg:apk/busybox@1.30.1-r2", + "package_url": "pkg:apk/alpine/busybox@1.30.1-r2?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl@1.1.22-r3" @@ -50,12 +50,12 @@ "scope": "runtime" }, "ca-certificates-cacert": { - "package_url": "pkg:apk/ca-certificates-cacert@20190108-r0", + "package_url": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "scope": "runtime" }, "libc-utils": { - "package_url": "pkg:apk/libc-utils@0.7.1-r0", + "package_url": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl-utils@1.1.22-r3" @@ -63,7 +63,7 @@ "scope": "runtime" }, "libcrypto1.1": { - "package_url": "pkg:apk/libcrypto1.1@1.1.1c-r0", + "package_url": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl@1.1.22-r3" @@ -71,7 +71,7 @@ "scope": "runtime" }, "libssl1.1": { - "package_url": "pkg:apk/libssl1.1@1.1.1c-r0", + "package_url": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "libcrypto1.1@1.1.1c-r0", @@ -80,7 +80,7 @@ "scope": "runtime" }, "libtls-standalone": { - "package_url": "pkg:apk/libtls-standalone@2.9.1-r0", + "package_url": "pkg:apk/alpine/libtls-standalone@2.9.1-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "ca-certificates-cacert@20190108-r0", @@ -91,12 +91,12 @@ "scope": "runtime" }, "musl": { - "package_url": "pkg:apk/musl@1.1.22-r3", + "package_url": "pkg:apk/alpine/musl@1.1.22-r3?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "scope": "runtime" }, "musl-utils": { - "package_url": "pkg:apk/musl-utils@1.1.22-r3", + "package_url": "pkg:apk/alpine/musl-utils@1.1.22-r3?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl@1.1.22-r3", @@ -105,7 +105,7 @@ "scope": "runtime" }, "scanelf": { - "package_url": "pkg:apk/scanelf@1.2.3-r0", + "package_url": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl@1.1.22-r3" @@ -113,7 +113,7 @@ "scope": "runtime" }, "ssl_client": { - "package_url": "pkg:apk/ssl_client@1.30.1-r2", + "package_url": "pkg:apk/alpine/ssl_client@1.30.1-r2?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "libtls-standalone@2.9.1-r0", @@ -122,7 +122,7 @@ "scope": "runtime" }, "zlib": { - "package_url": "pkg:apk/zlib@1.2.11-r1", + "package_url": "pkg:apk/alpine/zlib@1.2.11-r1?arch=x86_64\u0026distro=3.10.2", "relationship": "direct", "dependencies": [ "musl@1.1.22-r3" diff --git a/pkg/report/github/github.go b/pkg/report/github/github.go index 4a5007c79872..9476c5020709 100644 --- a/pkg/report/github/github.go +++ b/pkg/report/github/github.go @@ -117,7 +117,7 @@ func (w Writer) Write(report types.Report) error { githubPkg.Scope = RuntimeScope githubPkg.Relationship = getPkgRelationshipType(pkg) githubPkg.Dependencies = pkg.DependsOn // TODO: replace with PURL - githubPkg.PackageUrl, err = buildPurl(result.Type, pkg) + githubPkg.PackageUrl, err = buildPurl(result.Type, report.Metadata, pkg) if err != nil { return xerrors.Errorf("unable to build purl for %s: %w", pkg.Name, err) } @@ -160,8 +160,8 @@ func getPkgRelationshipType(pkg ftypes.Package) string { return DirectRelationship } -func buildPurl(t ftypes.TargetType, pkg ftypes.Package) (string, error) { - packageUrl, err := purl.NewPackageURL(t, types.Metadata{}, pkg) +func buildPurl(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (string, error) { + packageUrl, err := purl.NewPackageURL(t, metadata, pkg) if err != nil { return "", xerrors.Errorf("purl error: %w", err) } diff --git a/pkg/report/github/github_test.go b/pkg/report/github/github_test.go index 961ae3c1649e..b7187c9723c8 100644 --- a/pkg/report/github/github_test.go +++ b/pkg/report/github/github_test.go @@ -24,6 +24,13 @@ func TestWriter_Write(t *testing.T) { report: types.Report{ SchemaVersion: 2, ArtifactName: "alpine:3.14", + Metadata: types.Metadata{ + OS: &ftypes.OS{ + Family: "alpine", + Name: "3.14", + Eosl: true, + }, + }, Results: types.Results{ { Target: "yarn.lock", @@ -59,9 +66,34 @@ func TestWriter_Write(t *testing.T) { }, }, }, + { + Target: "alpine:3.14 (alpine 3.14.10)", + Class: "os-pkgs", + Type: "alpine", + Packages: []ftypes.Package{ + { + ID: "apk-tools@2.12.7-r0", + Name: "apk-tools", + Version: "2.12.7-r0", + Arch: "x86_64", + SrcName: "apk-tools", + SrcVersion: "2.12.7-r0", + }, + }, + }, }, }, want: map[string]github.Manifest{ + "alpine:3.14 (alpine 3.14.10)": { + Name: "alpine", + Resolved: map[string]github.Package{ + "apk-tools": { + PackageUrl: "pkg:apk/alpine/apk-tools@2.12.7-r0?arch=x86_64&distro=3.14", + Relationship: "direct", + Scope: "runtime", + }, + }, + }, "yarn.lock": { Name: "yarn", File: &github.File{ From b5e3b77f0f683353580a971e13ef747911424d80 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:39:00 +0600 Subject: [PATCH 044/108] docs(python): add note to using `pip freeze` for `compatible releases` (#5760) --- docs/docs/coverage/language/python.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/docs/coverage/language/python.md b/docs/docs/coverage/language/python.md index b598bd964a7c..eaed8f1d4b7d 100644 --- a/docs/docs/coverage/language/python.md +++ b/docs/docs/coverage/language/python.md @@ -40,6 +40,31 @@ See [here](./index.md) for the detail. Trivy parses your files generated by package managers in filesystem/repository scanning. ### pip +Trivy only parses [version specifiers](https://packaging.python.org/en/latest/specifications/version-specifiers/#id4) with `==` comparison operator and without `.*`. +To convert unsupported version specifiers - use the `pip freeze` command. + +```bash +$ cat requirements.txt +boto3~=1.24.60 +click>=8.0 +json-fix==0.5.* +$ pip install -r requirements.txt +... +$ pip freeze > requirements.txt +$ cat requirements.txt +boto3==1.24.96 +botocore==1.27.96 +click==8.1.7 +jmespath==1.0.1 +json-fix==0.5.2 +python-dateutil==2.8.2 +s3transfer==0.6.2 +setuptools==69.0.2 +six==1.16.0 +urllib3==1.26.18 +wheel==0.42.0 +``` + `requirements.txt` files usually contain only the direct dependencies and not contain the transitive dependencies. Therefore, Trivy scans only for the direct dependencies with `requirements.txt`. From f25e2df1c03a69981819f1c1c8f50ad32d453a56 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 13 Dec 2023 18:07:31 +0600 Subject: [PATCH 045/108] refactor(purl): use `pub` from `package-url` (#5784) --- pkg/purl/purl.go | 7 +++---- pkg/purl/purl_test.go | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 5c4441bad3bc..582647166ab2 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -16,8 +16,7 @@ import ( ) const ( - TypeOCI = "oci" - TypeDart = "dart" + TypeOCI = "oci" // TypeK8s is a custom type for Kubernetes components in PURL. // - namespace: The service provider such as EKS or GKE. It is not case sensitive and must be lowercased. @@ -141,7 +140,7 @@ func (p *PackageURL) LangType() ftypes.LangType { return ftypes.Hex case packageurl.TypeConan: return ftypes.Conan - case TypeDart: // TODO: replace with packageurl.TypeDart once they add it. + case packageurl.TypePub: return ftypes.Pub case packageurl.TypeBitnami: return ftypes.Bitnami @@ -432,7 +431,7 @@ func purlType(t ftypes.TargetType) string { case ftypes.Conan: return packageurl.TypeConan case ftypes.Pub: - return TypeDart // TODO: replace with packageurl.TypeDart once they add it. + return packageurl.TypePub case ftypes.RustBinary, ftypes.Cargo: return packageurl.TypeCargo case ftypes.Alpine: diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index d1fc9ab0d5a4..9847ff57d5ce 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -219,7 +219,7 @@ func TestNewPackageURL(t *testing.T) { }, want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: purl.TypeDart, + Type: packageurl.TypePub, Name: "http", Version: "0.13.2", }, @@ -512,10 +512,10 @@ func TestFromString(t *testing.T) { }, { name: "happy path for dart", - purl: "pkg:dart/http@0.13.2", + purl: "pkg:pub/http@0.13.2", want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: purl.TypeDart, + Type: packageurl.TypePub, Name: "http", Version: "0.13.2", Qualifiers: packageurl.Qualifiers{}, From df49ea4a14f471c6e1aba6336cafe27884cb64fb Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Sun, 17 Dec 2023 15:25:08 +0600 Subject: [PATCH 046/108] refactor(sbom): disable html escaping for CycloneDX (#5764) --- ...fluentd-multiple-lockfiles.cdx.json.golden | 1216 ++++++++--------- pkg/k8s/report/cyclonedx.go | 1 + pkg/report/cyclonedx/cyclonedx.go | 1 + 3 files changed, 610 insertions(+), 608 deletions(-) diff --git a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden index d8583f1ad6ea..c3e5903d5b79 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden @@ -51,7 +51,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/adduser@3.118?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/adduser@3.118?arch=all&distro=debian-10.2", "type": "library", "name": "adduser", "version": "3.118", @@ -62,7 +62,7 @@ } } ], - "purl": "pkg:deb/debian/adduser@3.118?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/adduser@3.118?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -91,7 +91,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/apt@1.8.2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/apt@1.8.2?arch=amd64&distro=debian-10.2", "type": "library", "name": "apt", "version": "1.8.2", @@ -102,7 +102,7 @@ } } ], - "purl": "pkg:deb/debian/apt@1.8.2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/apt@1.8.2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -131,7 +131,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "base-files", "version": "10.3+deb10u2", @@ -142,7 +142,7 @@ } } ], - "purl": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -171,7 +171,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64&distro=debian-10.2", "type": "library", "name": "base-passwd", "version": "3.5.46", @@ -187,7 +187,7 @@ } } ], - "purl": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -216,7 +216,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/bash@5.0-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "bash", "version": "5.0-4", @@ -227,7 +227,7 @@ } } ], - "purl": "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/bash@5.0-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -260,7 +260,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "bsdutils", "version": "2.33.1-0.1", @@ -316,7 +316,7 @@ } } ], - "purl": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -349,7 +349,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ca-certificates@20190110?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ca-certificates@20190110?arch=all&distro=debian-10.2", "type": "library", "name": "ca-certificates", "version": "20190110", @@ -365,7 +365,7 @@ } } ], - "purl": "pkg:deb/debian/ca-certificates@20190110?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ca-certificates@20190110?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -394,7 +394,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/coreutils@8.30-3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/coreutils@8.30-3?arch=amd64&distro=debian-10.2", "type": "library", "name": "coreutils", "version": "8.30-3", @@ -405,7 +405,7 @@ } } ], - "purl": "pkg:deb/debian/coreutils@8.30-3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/coreutils@8.30-3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -438,7 +438,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "dash", "version": "0.5.10.2-5", @@ -449,7 +449,7 @@ } } ], - "purl": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -482,7 +482,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", "type": "library", "name": "debconf", "version": "1.5.71", @@ -493,7 +493,7 @@ } } ], - "purl": "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -522,7 +522,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all&distro=debian-10.2", "type": "library", "name": "debian-archive-keyring", "version": "2019.1", @@ -533,7 +533,7 @@ } } ], - "purl": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -562,7 +562,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "debianutils", "version": "4.8.6.1", @@ -573,7 +573,7 @@ } } ], - "purl": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -602,7 +602,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/diffutils@3.7-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/diffutils@3.7-3?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "diffutils", "version": "3.7-3", @@ -618,7 +618,7 @@ } } ], - "purl": "pkg:deb/debian/diffutils@3.7-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/diffutils@3.7-3?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -655,7 +655,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2", "type": "library", "name": "dpkg", "version": "1.19.7", @@ -681,7 +681,7 @@ } } ], - "purl": "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -710,7 +710,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "e2fsprogs", "version": "1.44.5-1+deb10u2", @@ -726,7 +726,7 @@ } } ], - "purl": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -759,7 +759,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "fdisk", "version": "2.33.1-0.1", @@ -815,7 +815,7 @@ } } ], - "purl": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -848,7 +848,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64&distro=debian-10.2", "type": "library", "name": "findutils", "version": "4.6.0+git+20190209-2", @@ -864,7 +864,7 @@ } } ], - "purl": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -897,7 +897,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", "type": "library", "name": "gcc-8-base", "version": "8.3.0-6", @@ -928,7 +928,7 @@ } } ], - "purl": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -961,7 +961,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64&distro=debian-10.2", "type": "library", "name": "gpgv", "version": "2.2.12-1+deb10u1", @@ -1012,7 +1012,7 @@ } } ], - "purl": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1045,7 +1045,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/grep@3.3-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/grep@3.3-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "grep", "version": "3.3-1", @@ -1056,7 +1056,7 @@ } } ], - "purl": "pkg:deb/debian/grep@3.3-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/grep@3.3-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1089,7 +1089,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/gzip@1.9-3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/gzip@1.9-3?arch=amd64&distro=debian-10.2", "type": "library", "name": "gzip", "version": "1.9-3", @@ -1100,7 +1100,7 @@ } } ], - "purl": "pkg:deb/debian/gzip@1.9-3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/gzip@1.9-3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1133,7 +1133,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/hostname@3.21?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/hostname@3.21?arch=amd64&distro=debian-10.2", "type": "library", "name": "hostname", "version": "3.21", @@ -1144,7 +1144,7 @@ } } ], - "purl": "pkg:deb/debian/hostname@3.21?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/hostname@3.21?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1173,7 +1173,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all&distro=debian-10.2", "type": "library", "name": "init-system-helpers", "version": "1.56+nmu1", @@ -1189,7 +1189,7 @@ } } ], - "purl": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1218,7 +1218,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "libacl1", "version": "2.2.53-4", @@ -1239,7 +1239,7 @@ } } ], - "purl": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1272,7 +1272,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libapt-pkg5.0", "version": "1.8.2", @@ -1283,7 +1283,7 @@ } } ], - "purl": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1312,7 +1312,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "libattr1", "version": "2.4.48-4", @@ -1333,7 +1333,7 @@ } } ], - "purl": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1370,7 +1370,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all&distro=debian-10.2&epoch=1", "type": "library", "name": "libaudit-common", "version": "2.8.4-3", @@ -1391,7 +1391,7 @@ } } ], - "purl": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1428,7 +1428,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "libaudit1", "version": "2.8.4-3", @@ -1449,7 +1449,7 @@ } } ], - "purl": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1486,7 +1486,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libblkid1", "version": "2.33.1-0.1", @@ -1542,7 +1542,7 @@ } } ], - "purl": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1575,7 +1575,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libbz2-1.0", "version": "1.0.6-9.2~deb10u1", @@ -1591,7 +1591,7 @@ } } ], - "purl": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1624,7 +1624,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64&distro=debian-10.2", "type": "library", "name": "libc-bin", "version": "2.28-10", @@ -1640,7 +1640,7 @@ } } ], - "purl": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1673,7 +1673,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", "type": "library", "name": "libc6", "version": "2.28-10", @@ -1689,7 +1689,7 @@ } } ], - "purl": "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1722,7 +1722,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libcap-ng0", "version": "0.7.9-2", @@ -1743,7 +1743,7 @@ } } ], - "purl": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1776,11 +1776,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libcom-err2", "version": "1.44.5-1+deb10u2", - "purl": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1813,11 +1813,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libdb5.3", "version": "5.3.28+dfsg1-0.5", - "purl": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1850,11 +1850,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64&distro=debian-10.2", "type": "library", "name": "libdebconfclient0", "version": "0.249", - "purl": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1883,7 +1883,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libext2fs2", "version": "1.44.5-1+deb10u2", @@ -1899,7 +1899,7 @@ } } ], - "purl": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -1932,7 +1932,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libfdisk1", "version": "2.33.1-0.1", @@ -1988,7 +1988,7 @@ } } ], - "purl": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2021,7 +2021,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2", "type": "library", "name": "libffi6", "version": "3.2.1-9", @@ -2032,7 +2032,7 @@ } } ], - "purl": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2065,11 +2065,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "libgcc1", "version": "8.3.0-6", - "purl": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2102,7 +2102,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libgcrypt20", "version": "1.8.4-5", @@ -2118,7 +2118,7 @@ } } ], - "purl": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2151,7 +2151,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "libgdbm-compat4", "version": "1.18.1-4", @@ -2172,7 +2172,7 @@ } } ], - "purl": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2205,7 +2205,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "libgdbm6", "version": "1.18.1-4", @@ -2226,7 +2226,7 @@ } } ], - "purl": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2259,7 +2259,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "bom-ref": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", "type": "library", "name": "libgmp10", "version": "6.1.2+dfsg-4", @@ -2280,7 +2280,7 @@ } } ], - "purl": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "purl": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2317,7 +2317,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "libgnutls30", "version": "3.6.7-4", @@ -2363,7 +2363,7 @@ } } ], - "purl": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2396,7 +2396,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libgpg-error0", "version": "1.35-1", @@ -2422,7 +2422,7 @@ } } ], - "purl": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2455,11 +2455,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libhogweed4", "version": "3.4.1-1", - "purl": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2492,7 +2492,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libidn2-0", "version": "2.0.5-1", @@ -2518,7 +2518,7 @@ } } ], - "purl": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2551,7 +2551,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64&distro=debian-10.2", "type": "library", "name": "libjemalloc2", "version": "5.1.0-3", @@ -2587,7 +2587,7 @@ } } ], - "purl": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2620,7 +2620,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "liblz4-1", "version": "1.8.3-1", @@ -2636,7 +2636,7 @@ } } ], - "purl": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2669,7 +2669,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "liblzma5", "version": "5.2.4-1", @@ -2740,7 +2740,7 @@ } } ], - "purl": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2773,7 +2773,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libmount1", "version": "2.33.1-0.1", @@ -2829,7 +2829,7 @@ } } ], - "purl": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2862,11 +2862,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libncurses6", "version": "6.1+20181013-2+deb10u2", - "purl": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2899,11 +2899,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libncursesw6", "version": "6.1+20181013-2+deb10u2", - "purl": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -2936,7 +2936,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libnettle6", "version": "3.4.1-1", @@ -2987,7 +2987,7 @@ } } ], - "purl": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3020,7 +3020,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libp11-kit0", "version": "0.23.15-2", @@ -3051,7 +3051,7 @@ } } ], - "purl": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3084,7 +3084,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libpam-modules-bin", "version": "1.3.1-5", @@ -3095,7 +3095,7 @@ } } ], - "purl": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3128,7 +3128,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libpam-modules", "version": "1.3.1-5", @@ -3139,7 +3139,7 @@ } } ], - "purl": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3172,7 +3172,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all&distro=debian-10.2", "type": "library", "name": "libpam-runtime", "version": "1.3.1-5", @@ -3183,7 +3183,7 @@ } } ], - "purl": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3216,7 +3216,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libpam0g", "version": "1.3.1-5", @@ -3227,7 +3227,7 @@ } } ], - "purl": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3260,11 +3260,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "bom-ref": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64&distro=debian-10.2&epoch=2", "type": "library", "name": "libpcre3", "version": "8.39-12", - "purl": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "purl": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64&distro=debian-10.2&epoch=2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3301,7 +3301,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64&distro=debian-10.2", "type": "library", "name": "libreadline7", "version": "7.0-5", @@ -3317,7 +3317,7 @@ } } ], - "purl": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3350,7 +3350,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libruby2.5", "version": "2.5.5-3+deb10u1", @@ -3451,7 +3451,7 @@ } } ], - "purl": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3484,7 +3484,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64&distro=debian-10.2", "type": "library", "name": "libseccomp2", "version": "2.3.3-4", @@ -3495,7 +3495,7 @@ } } ], - "purl": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3528,7 +3528,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libselinux1", "version": "2.8-1+b1", @@ -3544,7 +3544,7 @@ } } ], - "purl": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3577,7 +3577,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all&distro=debian-10.2", "type": "library", "name": "libsemanage-common", "version": "2.8-2", @@ -3593,7 +3593,7 @@ } } ], - "purl": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3626,7 +3626,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libsemanage1", "version": "2.8-2", @@ -3642,7 +3642,7 @@ } } ], - "purl": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3675,7 +3675,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libsepol1", "version": "2.8-1", @@ -3691,7 +3691,7 @@ } } ], - "purl": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3724,7 +3724,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libsmartcols1", "version": "2.33.1-0.1", @@ -3780,7 +3780,7 @@ } } ], - "purl": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3813,11 +3813,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libss2", "version": "1.44.5-1+deb10u2", - "purl": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3850,11 +3850,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libssl1.1", "version": "1.1.1d-0+deb10u2", - "purl": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3887,11 +3887,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2", "type": "library", "name": "libstdc++6", "version": "8.3.0-6", - "purl": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3924,7 +3924,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libsystemd0", "version": "241-7~deb10u2", @@ -3955,7 +3955,7 @@ } } ], - "purl": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -3988,7 +3988,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64&distro=debian-10.2", "type": "library", "name": "libtasn1-6", "version": "4.13-3", @@ -4014,7 +4014,7 @@ } } ], - "purl": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4047,11 +4047,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libtinfo6", "version": "6.1+20181013-2+deb10u2", - "purl": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4084,7 +4084,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "libudev1", "version": "241-7~deb10u2", @@ -4115,7 +4115,7 @@ } } ], - "purl": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4148,7 +4148,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libunistring2", "version": "0.9.10-1", @@ -4194,7 +4194,7 @@ } } ], - "purl": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4227,7 +4227,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libuuid1", "version": "2.33.1-0.1", @@ -4283,7 +4283,7 @@ } } ], - "purl": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4316,7 +4316,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "libyaml-0-2", "version": "0.2.1-1", @@ -4332,7 +4332,7 @@ } } ], - "purl": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4365,7 +4365,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64&distro=debian-10.2", "type": "library", "name": "libzstd1", "version": "1.3.8+dfsg-3", @@ -4391,7 +4391,7 @@ } } ], - "purl": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4424,7 +4424,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/login@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/login@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "login", "version": "4.5-1.1", @@ -4435,7 +4435,7 @@ } } ], - "purl": "pkg:deb/debian/login@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/login@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4472,7 +4472,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64&distro=debian-10.2", "type": "library", "name": "mawk", "version": "1.3.3-17+b3", @@ -4483,7 +4483,7 @@ } } ], - "purl": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4516,7 +4516,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "mount", "version": "2.33.1-0.1", @@ -4572,7 +4572,7 @@ } } ], - "purl": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4605,11 +4605,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all&distro=debian-10.2", "type": "library", "name": "ncurses-base", "version": "6.1+20181013-2+deb10u2", - "purl": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4642,11 +4642,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "ncurses-bin", "version": "6.1+20181013-2+deb10u2", - "purl": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4679,11 +4679,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "type": "library", "name": "openssl", "version": "1.1.1d-0+deb10u2", - "purl": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4716,7 +4716,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "passwd", "version": "4.5-1.1", @@ -4727,7 +4727,7 @@ } } ], - "purl": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4764,11 +4764,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64&distro=debian-10.2", "type": "library", "name": "perl-base", "version": "5.28.1-6", - "purl": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4801,7 +4801,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/rake@12.3.1-3?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/rake@12.3.1-3?arch=all&distro=debian-10.2", "type": "library", "name": "rake", "version": "12.3.1-3", @@ -4812,7 +4812,7 @@ } } ], - "purl": "pkg:deb/debian/rake@12.3.1-3?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/rake@12.3.1-3?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4845,7 +4845,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/readline-common@7.0-5?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/readline-common@7.0-5?arch=all&distro=debian-10.2", "type": "library", "name": "readline-common", "version": "7.0-5", @@ -4861,7 +4861,7 @@ } } ], - "purl": "pkg:deb/debian/readline-common@7.0-5?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/readline-common@7.0-5?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4894,7 +4894,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-did-you-mean", "version": "1.2.1-1", @@ -4905,7 +4905,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4938,7 +4938,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-minitest", "version": "5.11.3-1", @@ -4949,7 +4949,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -4982,7 +4982,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-net-telnet", "version": "0.1.1-2", @@ -4993,7 +4993,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5026,7 +5026,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-power-assert", "version": "1.1.1-1", @@ -5042,7 +5042,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5075,7 +5075,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-test-unit", "version": "3.2.8-1", @@ -5101,7 +5101,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5134,7 +5134,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all&distro=debian-10.2", "type": "library", "name": "ruby-xmlrpc", "version": "0.3.0-2", @@ -5145,7 +5145,7 @@ } } ], - "purl": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5178,7 +5178,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "type": "library", "name": "ruby2.5", "version": "2.5.5-3+deb10u1", @@ -5279,7 +5279,7 @@ } } ], - "purl": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5312,7 +5312,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/ruby@2.5.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/ruby@2.5.1?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "ruby", "version": "2.5.1", @@ -5328,7 +5328,7 @@ } } ], - "purl": "pkg:deb/debian/ruby@2.5.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/ruby@2.5.1?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5361,7 +5361,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/rubygems-integration@1.11?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/rubygems-integration@1.11?arch=all&distro=debian-10.2", "type": "library", "name": "rubygems-integration", "version": "1.11", @@ -5372,7 +5372,7 @@ } } ], - "purl": "pkg:deb/debian/rubygems-integration@1.11?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/rubygems-integration@1.11?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5401,7 +5401,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/sed@4.7-1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/sed@4.7-1?arch=amd64&distro=debian-10.2", "type": "library", "name": "sed", "version": "4.7-1", @@ -5412,7 +5412,7 @@ } } ], - "purl": "pkg:deb/debian/sed@4.7-1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/sed@4.7-1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5445,7 +5445,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64&distro=debian-10.2", "type": "library", "name": "sysvinit-utils", "version": "2.93-8", @@ -5456,7 +5456,7 @@ } } ], - "purl": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5489,7 +5489,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64&distro=debian-10.2", "type": "library", "name": "tar", "version": "1.30+dfsg-6", @@ -5505,7 +5505,7 @@ } } ], - "purl": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5538,11 +5538,11 @@ ] }, { - "bom-ref": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all&distro=debian-10.2", "type": "library", "name": "tzdata", "version": "2019c-0+deb10u1", - "purl": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5575,7 +5575,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "bom-ref": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2", "type": "library", "name": "util-linux", "version": "2.33.1-0.1", @@ -5631,7 +5631,7 @@ } } ], - "purl": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "purl": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -5664,7 +5664,7 @@ ] }, { - "bom-ref": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "bom-ref": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1", "type": "library", "name": "zlib1g", "version": "1.2.11.dfsg-1", @@ -5675,7 +5675,7 @@ } } ], - "purl": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "purl": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1", "properties": [ { "name": "aquasecurity:trivy:LayerDiffID", @@ -7533,791 +7533,791 @@ { "ref": "3ff14136-e09f-4df9-80ea-000000000003", "dependsOn": [ - "pkg:deb/debian/adduser@3.118?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/apt@1.8.2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/base-passwd@3.5.46?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/ca-certificates@20190110?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/coreutils@8.30-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/diffutils@3.7-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/grep@3.3-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/gzip@1.9-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/hostname@3.21?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc-bin@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpcre3@8.39-12?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libreadline7@7.0-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsemanage-common@2.8-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsepol1@2.8-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/login@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/passwd@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/rake@12.3.1-3?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/readline-common@7.0-5?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/ruby@2.5.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/rubygems-integration@1.11?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/sed@4.7-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" - ] - }, - { - "ref": "pkg:deb/debian/adduser@3.118?arch=all\u0026distro=debian-10.2", + "pkg:deb/debian/adduser@3.118?arch=all&distro=debian-10.2", + "pkg:deb/debian/apt@1.8.2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/base-passwd@3.5.46?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/bash@5.0-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/ca-certificates@20190110?arch=all&distro=debian-10.2", + "pkg:deb/debian/coreutils@8.30-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all&distro=debian-10.2", + "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/diffutils@3.7-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/grep@3.3-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/gzip@1.9-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/hostname@3.21?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all&distro=debian-10.2", + "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc-bin@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all&distro=debian-10.2", + "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpcre3@8.39-12?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libreadline7@7.0-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsemanage-common@2.8-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsepol1@2.8-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/login@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all&distro=debian-10.2", + "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/passwd@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/rake@12.3.1-3?arch=all&distro=debian-10.2", + "pkg:deb/debian/readline-common@7.0-5?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/ruby@2.5.1?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/rubygems-integration@1.11?arch=all&distro=debian-10.2", + "pkg:deb/debian/sed@4.7-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all&distro=debian-10.2", + "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1" + ] + }, + { + "ref": "pkg:deb/debian/adduser@3.118?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/passwd@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/passwd@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/apt@1.8.2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/apt@1.8.2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/adduser@3.118?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/adduser@3.118?arch=all&distro=debian-10.2", + "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all&distro=debian-10.2", + "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/base-passwd@3.5.46?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/bash@5.0-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/base-files@10.3%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/bsdutils@2.33.1-0.1?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ca-certificates@20190110?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ca-certificates@20190110?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/coreutils@8.30-3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/coreutils@8.30-3?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/dash@0.5.10.2-5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/debian-archive-keyring@2019.1?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/debianutils@4.8.6.1?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/diffutils@3.7-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/diffutils@3.7-3?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [] }, { - "ref": "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/e2fsprogs@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/findutils@4.6.0%2Bgit%2B20190209-2?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/gpgv@2.2.12-1%2Bdeb10u1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/grep@3.3-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/grep@3.3-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/gzip@1.9-3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/gzip@1.9-3?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/hostname@3.21?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/hostname@3.21?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libacl1@2.2.53-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libapt-pkg5.0@1.8.2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/libattr1@2.4.48-4?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all&distro=debian-10.2&epoch=1", "dependsOn": [] }, { - "ref": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libaudit-common@2.8.4-3?arch=all&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libc-bin@2.28-10?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libcap-ng0@0.7.9-2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libdebconfclient0@0.249?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libext2fs2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libfdisk1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libgcrypt20@1.8.4-5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "ref": "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libgnutls30@3.6.7-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libgpg-error0@1.35-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libhogweed4@3.4.1-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libjemalloc2@5.1.0-3?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/liblz4-1@1.8.3-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/liblzma5@5.2.4-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libmount1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libblkid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libncursesw6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libnettle6@3.4.1-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libp11-kit0@0.23.15-2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libpam-modules-bin@1.3.1-5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libpam-runtime@1.3.1-5?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", + "ref": "pkg:deb/debian/libpcre3@8.39-12?arch=amd64&distro=debian-10.2&epoch=2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libreadline7@7.0-5?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/readline-common@7.0-5?arch=all\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/readline-common@7.0-5?arch=all&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libreadline7@7.0-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/rake@12.3.1-3?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" - ] - }, - { - "ref": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64\u0026distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libffi6@3.2.1-9?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgdbm-compat4@1.18.1-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgdbm6@1.18.1-4?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libncurses6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libreadline7@7.0-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/rake@12.3.1-3?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all&distro=debian-10.2", + "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1" + ] + }, + { + "ref": "pkg:deb/debian/libseccomp2@2.3.3-4?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpcre3@8.39-12?arch=amd64\u0026distro=debian-10.2\u0026epoch=2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpcre3@8.39-12?arch=amd64&distro=debian-10.2&epoch=2" ] }, { - "ref": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libsemanage-common@2.8-2?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsemanage-common@2.8-2?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libsepol1@2.8-1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libbz2-1.0@1.0.6-9.2~deb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsemanage-common@2.8-2?arch=all&distro=debian-10.2", + "pkg:deb/debian/libsepol1@2.8-1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libsepol1@2.8-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libsmartcols1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libss2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libcom-err2@1.44.5-1%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libstdc%2B%2B6@8.3.0-6?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/gcc-8-base@8.3.0-6?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgcc1@8.3.0-6?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libsystemd0@241-7~deb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libtasn1-6@4.13-3?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libtinfo6@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libudev1@241-7~deb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libunistring2@0.9.10-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libuuid1@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libyaml-0-2@0.2.1-1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/libzstd1@1.3.8%2Bdfsg-3?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/login@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/login@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [] }, { - "ref": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/mawk@1.3.3-17%2Bb3?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/mount@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ncurses-base@6.1%2B20181013-2%2Bdeb10u2?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ncurses-bin@6.1%2B20181013-2%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/openssl@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libssl1.1@1.1.1d-0%2Bdeb10u2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/passwd@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libaudit1@2.8.4-3?arch=amd64&distro=debian-10.2&epoch=1", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam-modules@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libpam0g@1.3.1-5?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libselinux1@2.8-1%2Bb1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libsemanage1@2.8-2?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/perl-base@5.28.1-6?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/rake@12.3.1-3?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/rake@12.3.1-3?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/ruby@2.5.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/ruby@2.5.1?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/readline-common@7.0-5?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/readline-common@7.0-5?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/dpkg@1.19.7?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/dpkg@1.19.7?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-did-you-mean@1.2.1-1?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-minitest@5.11.3-1?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-net-telnet@0.1.1-2?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-test-unit@3.2.8-1?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all\u0026distro=debian-10.2" + "pkg:deb/debian/ruby-power-assert@1.1.1-1?arch=all&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby-xmlrpc@0.3.0-2?arch=all&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64\u0026distro=debian-10.2\u0026epoch=2", - "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/rubygems-integration@1.11?arch=all\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/libgmp10@6.1.2%2Bdfsg-4?arch=amd64&distro=debian-10.2&epoch=2", + "pkg:deb/debian/libruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/rubygems-integration@1.11?arch=all&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/ruby@2.5.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/ruby@2.5.1?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/ruby2.5@2.5.5-3%2Bdeb10u1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/rubygems-integration@1.11?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/rubygems-integration@1.11?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/ca-certificates@20190110?arch=all\u0026distro=debian-10.2" + "pkg:deb/debian/ca-certificates@20190110?arch=all&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/sed@4.7-1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/sed@4.7-1?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/sysvinit-utils@2.93-8?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all\u0026distro=debian-10.2", - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/init-system-helpers@1.56%2Bnmu1?arch=all&distro=debian-10.2", + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/tar@1.30%2Bdfsg-6?arch=amd64&distro=debian-10.2", "dependsOn": [] }, { - "ref": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/tzdata@2019c-0%2Bdeb10u1?arch=all&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/debconf@1.5.71?arch=all\u0026distro=debian-10.2" + "pkg:deb/debian/debconf@1.5.71?arch=all&distro=debian-10.2" ] }, { - "ref": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", + "ref": "pkg:deb/debian/util-linux@2.33.1-0.1?arch=amd64&distro=debian-10.2", "dependsOn": [ - "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64\u0026distro=debian-10.2", - "pkg:deb/debian/login@4.5-1.1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1" + "pkg:deb/debian/fdisk@2.33.1-0.1?arch=amd64&distro=debian-10.2", + "pkg:deb/debian/login@4.5-1.1?arch=amd64&distro=debian-10.2&epoch=1" ] }, { - "ref": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64\u0026distro=debian-10.2\u0026epoch=1", + "ref": "pkg:deb/debian/zlib1g@1.2.11.dfsg-1?arch=amd64&distro=debian-10.2&epoch=1", "dependsOn": [ - "pkg:deb/debian/libc6@2.28-10?arch=amd64\u0026distro=debian-10.2" + "pkg:deb/debian/libc6@2.28-10?arch=amd64&distro=debian-10.2" ] }, { diff --git a/pkg/k8s/report/cyclonedx.go b/pkg/k8s/report/cyclonedx.go index a7bbf69d026f..0640aed036a6 100644 --- a/pkg/k8s/report/cyclonedx.go +++ b/pkg/k8s/report/cyclonedx.go @@ -18,6 +18,7 @@ type CycloneDXWriter struct { func NewCycloneDXWriter(output io.Writer, format cdx.BOMFileFormat, appVersion string) CycloneDXWriter { encoder := cdx.NewBOMEncoder(output, format) encoder.SetPretty(true) + encoder.SetEscapeHTML(false) return CycloneDXWriter{ encoder: encoder, marshaler: core.NewCycloneDX(appVersion), diff --git a/pkg/report/cyclonedx/cyclonedx.go b/pkg/report/cyclonedx/cyclonedx.go index e5cd85b3db67..a99d2f6511db 100644 --- a/pkg/report/cyclonedx/cyclonedx.go +++ b/pkg/report/cyclonedx/cyclonedx.go @@ -34,6 +34,7 @@ func (w Writer) Write(report types.Report) error { encoder := cdx.NewBOMEncoder(w.output, w.format) encoder.SetPretty(true) + encoder.SetEscapeHTML(false) if err = encoder.Encode(bom); err != nil { return xerrors.Errorf("failed to encode bom: %w", err) } From abf227e06ec205c712f2434a60ca739a8ea4fd50 Mon Sep 17 00:00:00 2001 From: Juan Ariza Toledano Date: Sun, 17 Dec 2023 11:27:19 +0100 Subject: [PATCH 047/108] fix(bitnami): use a different comparer for detecting vulnerabilities (#5633) Signed-off-by: juan131 --- go.mod | 2 + go.sum | 2 + .../library/compare/bitnami/compare.go | 32 ++++ .../library/compare/bitnami/compare_test.go | 141 ++++++++++++++++++ pkg/detector/library/driver.go | 3 +- 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 pkg/detector/library/compare/bitnami/compare.go create mode 100644 pkg/detector/library/compare/bitnami/compare_test.go diff --git a/go.mod b/go.mod index ea65d56a2f41..ca061ec875dc 100644 --- a/go.mod +++ b/go.mod @@ -116,6 +116,8 @@ require ( modernc.org/sqlite v1.23.1 ) +require github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c + require ( cloud.google.com/go v0.110.7 // indirect cloud.google.com/go/compute v1.23.0 // indirect diff --git a/go.sum b/go.sum index ebf176383970..0a2ceabc86fe 100644 --- a/go.sum +++ b/go.sum @@ -516,6 +516,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c h1:C4UZIaS+HAw+X6jGUsoP2ZbM99PuqhCttjomg1yhNAI= +github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c/go.mod h1:9iglf1GG4oNRJ39bZ5AZrjgAFD2RwQbXw6Qf7Cs47wo= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= diff --git a/pkg/detector/library/compare/bitnami/compare.go b/pkg/detector/library/compare/bitnami/compare.go new file mode 100644 index 000000000000..f3f62a7194d1 --- /dev/null +++ b/pkg/detector/library/compare/bitnami/compare.go @@ -0,0 +1,32 @@ +package bitnami + +import ( + version "github.com/bitnami/go-version/pkg/version" + "golang.org/x/xerrors" + + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy/pkg/detector/library/compare" +) + +// Comparer represents a comparer for Bitnami +type Comparer struct{} + +// IsVulnerable checks if the package version is vulnerable to the advisory. +func (n Comparer) IsVulnerable(ver string, advisory dbTypes.Advisory) bool { + return compare.IsVulnerable(ver, advisory, n.matchVersion) +} + +// matchVersion checks if the package version satisfies the given constraint. +func (n Comparer) matchVersion(currentVersion, constraint string) (bool, error) { + v, err := version.Parse(currentVersion) + if err != nil { + return false, xerrors.Errorf("bitnami version error (%s): %s", currentVersion, err) + } + + c, err := version.NewConstraints(constraint) + if err != nil { + return false, xerrors.Errorf("bitnami constraint error (%s): %s", constraint, err) + } + + return c.Check(v), nil +} diff --git a/pkg/detector/library/compare/bitnami/compare_test.go b/pkg/detector/library/compare/bitnami/compare_test.go new file mode 100644 index 000000000000..fda9c5e5f0e0 --- /dev/null +++ b/pkg/detector/library/compare/bitnami/compare_test.go @@ -0,0 +1,141 @@ +package bitnami_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy/pkg/detector/library/compare/bitnami" +) + +func TestBitnamiComparer_IsVulnerable(t *testing.T) { + type args struct { + currentVersion string + advisory types.Advisory + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "not vulnerable", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + VulnerableVersions: []string{"<1.2.3"}, + }, + }, + want: false, + }, + { + name: "vulnerable", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + VulnerableVersions: []string{"<=1.2.3"}, + }, + }, + want: true, + }, + { + name: "patched", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3"}, + }, + }, + want: false, + }, + { + name: "unaffected", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + UnaffectedVersions: []string{"=1.2.3"}, + }, + }, + want: false, + }, + { + name: "vulnerable based on patched & unaffected versions", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + UnaffectedVersions: []string{"=1.2.0"}, + PatchedVersions: []string{">=1.2.4"}, + }, + }, + want: true, + }, + { + name: "patched with revision on current version", + args: args{ + currentVersion: "1.2.3-1", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3"}, + }, + }, + want: false, + }, + { + name: "vulnerable with revision on current version", + args: args{ + currentVersion: "1.2.3-1", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.4"}, + }, + }, + want: true, + }, + { + name: "patched with revision on patch", + args: args{ + currentVersion: "1.2.4", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3-1"}, + }, + }, + want: false, + }, + { + name: "vulnerable with revision on patch", + args: args{ + currentVersion: "1.2.3", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3-1"}, + }, + }, + want: true, + }, + { + name: "patched with revisions on both current and patch", + args: args{ + currentVersion: "1.2.4-2", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3-1"}, + }, + }, + want: false, + }, + { + name: "vulnerable with revision on both current and patch", + args: args{ + currentVersion: "1.2.3-0", + advisory: types.Advisory{ + PatchedVersions: []string{">=1.2.3-1"}, + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := bitnami.Comparer{} + got := b.IsVulnerable(tt.args.currentVersion, tt.args.advisory) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/detector/library/driver.go b/pkg/detector/library/driver.go index e18f926a3964..b2f5b6babc38 100644 --- a/pkg/detector/library/driver.go +++ b/pkg/detector/library/driver.go @@ -11,6 +11,7 @@ import ( dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/detector/library/compare" + "github.com/aquasecurity/trivy/pkg/detector/library/compare/bitnami" "github.com/aquasecurity/trivy/pkg/detector/library/compare/maven" "github.com/aquasecurity/trivy/pkg/detector/library/compare/npm" "github.com/aquasecurity/trivy/pkg/detector/library/compare/pep440" @@ -76,7 +77,7 @@ func NewDriver(libType ftypes.LangType) (Driver, bool) { return Driver{}, false case ftypes.Bitnami: ecosystem = vulnerability.Bitnami - comparer = compare.GenericComparer{} + comparer = bitnami.Comparer{} case ftypes.K8sUpstream: ecosystem = vulnerability.Kubernetes comparer = compare.GenericComparer{} From ba825b2ae1b0481d4b0d2845eafbb3cc83914c2f Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Mon, 18 Dec 2023 15:31:07 +0300 Subject: [PATCH 048/108] chore(deps): bump trivy-iac to v0.7.1 (#5797) --- go.mod | 30 ++++++++++---------- go.sum | 87 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 57 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index ca061ec875dc..05daa1d411fa 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NYTimes/gziphandler v1.1.1 github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 - github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 + github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 @@ -25,7 +25,7 @@ require ( github.com/aquasecurity/tml v0.6.1 github.com/aquasecurity/trivy-aws v0.5.0 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d - github.com/aquasecurity/trivy-iac v0.7.0 + github.com/aquasecurity/trivy-iac v0.7.1 github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 @@ -52,7 +52,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/go-containerregistry v0.17.0 github.com/google/licenseclassifier/v2 v2.0.0 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/google/wire v0.5.0 github.com/hashicorp/go-getter v1.7.2 github.com/hashicorp/go-multierror v1.1.1 @@ -76,7 +76,7 @@ require ( github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 github.com/moby/buildkit v0.11.6 - github.com/open-policy-agent/opa v0.57.0 + github.com/open-policy-agent/opa v0.58.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc5 github.com/openvex/go-vex v0.2.5 @@ -105,7 +105,7 @@ require ( go.uber.org/zap v1.26.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/mod v0.14.0 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.4.0 golang.org/x/term v0.14.0 golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 @@ -235,7 +235,7 @@ require ( github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect @@ -275,7 +275,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -361,10 +361,10 @@ require ( github.com/zclconf/go-cty-yaml v1.0.3 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/sdk v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/sdk v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.15.0 // indirect @@ -375,10 +375,10 @@ require ( golang.org/x/tools v0.13.0 // indirect google.golang.org/api v0.138.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect - google.golang.org/grpc v1.58.3 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 0a2ceabc86fe..63d77fef4926 100644 --- a/go.sum +++ b/go.sum @@ -321,8 +321,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= -github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 h1:w/Sm2fVtb0Rv1bcLLwsW9j37mNUya8MwzKMcjG9OW/Q= -github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8/go.mod h1:J30VViSgmoW2Ic/6aqVJO2qvuADsmZ3MYuNxPcU6Vt0= +github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 h1:mjQvKTiKYXWGxHU5pw37q1n6deky0KcJq5JJwtuVrF4= +github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08/go.mod h1:NBF6hvbQSc4s/WCHdKV5sNNxLl258M2OiIFoUfgEn/k= github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf h1:kweQrNMfarPfjZGI1537GtuujhpzhsuT/MvmW2FwaBE= github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= @@ -348,8 +348,8 @@ github.com/aquasecurity/trivy-aws v0.5.0 h1:6RJrw+QHeVn2MH7bI7bsVIiqRyhDCPvdEqkN github.com/aquasecurity/trivy-aws v0.5.0/go.mod h1:dPx0xRElmFrVXBxeYqEAl5NejJ2kHb51ybFPzBMxWow= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= -github.com/aquasecurity/trivy-iac v0.7.0 h1:L2/mqQJD1iwY4xOr1un5Prg51epYBQgM34JVZtkp4Gg= -github.com/aquasecurity/trivy-iac v0.7.0/go.mod h1:GG9Y2YylH3e16PoJ0RUZ+C0Xw93Gic/5fwdkKjKwwqU= +github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkvmyd5Lsg= +github.com/aquasecurity/trivy-iac v0.7.1/go.mod h1:SK5XaVwGh5M17QV81139BSPXNlm3bIGp+YmAYs7slRw= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 h1:OTJMSbvKQYxbQ2NQ8Nht2NSL1bL36YfBCrlsGGxHPlI= @@ -811,8 +811,8 @@ github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0X github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -968,8 +968,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1081,8 +1081,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= @@ -1127,8 +1127,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -1168,8 +1168,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.6 h1:3xi/Cafd1NaoEnS/yDssIiuVeDVywU0QdFG github.com/hashicorp/golang-lru/v2 v2.0.6/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= -github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= +github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= @@ -1444,8 +1444,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/open-policy-agent/opa v0.57.0 h1:DftxYfOEHOheXvO2Q6HCIM2ZVdKrvnF4cZlU9C64MIQ= -github.com/open-policy-agent/opa v0.57.0/go.mod h1:3FY6GNSbUqOhjCdvTXCBJ2rNuh66p/XrIc2owr/hSwo= +github.com/open-policy-agent/opa v0.58.0 h1:S5qvevW8JoFizU7Hp66R/Y1SOXol0aCdFYVkzIqIpUo= +github.com/open-policy-agent/opa v0.58.0/go.mod h1:EGWBwvmyt50YURNvL8X4W5hXdlKeNhAHn3QXsetmYcc= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1781,25 +1781,23 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1999,8 +1997,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2122,7 +2120,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2407,12 +2404,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= -google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44= -google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2452,8 +2449,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 81748f5ad003251e552675bb13a58047364c9b80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:59:21 +0400 Subject: [PATCH 049/108] chore(deps): bump golang.org/x/crypto from 0.15.0 to 0.17.0 (#5805) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 05daa1d411fa..9198c1b5a65f 100644 --- a/go.mod +++ b/go.mod @@ -106,7 +106,7 @@ require ( golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/mod v0.14.0 golang.org/x/sync v0.4.0 - golang.org/x/term v0.14.0 + golang.org/x/term v0.15.0 golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 google.golang.org/protobuf v1.31.0 @@ -367,10 +367,10 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.15.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.18.0 // indirect golang.org/x/oauth2 v0.11.0 // indirect - golang.org/x/sys v0.14.0 // indirect + golang.org/x/sys v0.15.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/api v0.138.0 // indirect diff --git a/go.sum b/go.sum index 63d77fef4926..4c88c9912fde 100644 --- a/go.sum +++ b/go.sum @@ -1840,8 +1840,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -2125,8 +2125,8 @@ 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.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2134,8 +2134,8 @@ golang.org/x/term v0.1.0/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.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 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= From be969d413619c27671b6238783bb7c63528ef043 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 10:13:16 +0400 Subject: [PATCH 050/108] chore(deps): bump github.com/containerd/containerd from 1.7.7 to 1.7.11 (#5809) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 ++++-- go.sum | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9198c1b5a65f..9ed1531fd7ed 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cheggaaa/pb/v3 v3.1.4 - github.com/containerd/containerd v1.7.7 + github.com/containerd/containerd v1.7.11 github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/color v1.15.0 @@ -142,7 +142,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/VividCortex/ewma v1.2.0 // indirect @@ -235,6 +235,7 @@ require ( github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect @@ -361,6 +362,7 @@ require ( github.com/zclconf/go-cty-yaml v1.0.3 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/sdk v1.19.0 // indirect diff --git a/go.sum b/go.sum index 4c88c9912fde..b38076674a08 100644 --- a/go.sum +++ b/go.sum @@ -275,8 +275,8 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= -github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -616,8 +616,8 @@ github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= -github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= From 4cdff0e57316f16efec6cc86f305ee4047225d5b Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Tue, 26 Dec 2023 15:09:43 +0300 Subject: [PATCH 051/108] chore(deps): bump github.com/aws/aws-sdk-go-v2/service/ec2 from v1.116.0 to v1.134.0 (#5822) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9ed1531fd7ed..cac96e6e7337 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/aws/aws-sdk-go-v2/config v1.25.11 github.com/aws/aws-sdk-go-v2/credentials v1.16.9 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 diff --git a/go.sum b/go.sum index b38076674a08..726b561bd8b8 100644 --- a/go.sum +++ b/go.sum @@ -433,8 +433,8 @@ github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.5 h1:EeNQ3bDA6hlx3vifHf7LT/l github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.5/go.mod h1:X3ThW5RPV19hi7bnQ0RMAiBjZbzxj4rZlj+qdctbMWY= github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 h1:iUgGXA8fg41B4Of0F+BS766SRQ7c8rr5jtka8RgaocQ= github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1/go.mod h1:9n0SC5yHomD8IjsR37+/txpdfNdpGSgV1RzmsTHrbWg= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0 h1:knbx9D59itE07Ihbx+1Po8jPDfo2M/8vDQn/4oUtTxk= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.116.0/go.mod h1:0FhI2Rzcv5BNM3dNnbcCx2qa2naFZoAidJi11cQgzL0= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 h1:ZozGfw2s79TxoqisrkALGCpXokhMkfZRQxPkd8+MK+Y= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0/go.mod h1:xYJZQIo/YZxEbeBxUYRQJTCJ924EuKtDfrhVx76yzOE= github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 h1:zqXEIhuR7RcHob2gxB/Xf1X4XuMS0vapn7xr+wCPrpg= github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1/go.mod h1:+rWYJfms9p+D/wUN599tx3FtWvxoXCP25b8Porlrxcc= github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1 h1:bOS7hAfvd8+glVAG88WnvRITe5N1vopGFHh10ORe/BI= From 1f0d6290c33c95d5f213cc409a0ff6a53a2c888e Mon Sep 17 00:00:00 2001 From: Juan Ariza Toledano Date: Wed, 27 Dec 2023 08:54:56 +0100 Subject: [PATCH 052/108] feat(vuln): include pkg identifier on detected vulnerabilities (#5439) Signed-off-by: juan131 Signed-off-by: knqyf263 Co-authored-by: DmitriyLewen Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Co-authored-by: Nikita Pivkin Co-authored-by: knqyf263 --- integration/client_server_test.go | 2 +- integration/sbom_test.go | 54 +- integration/testdata/almalinux-8.json.golden | 3 + .../testdata/alpine-310-registry.json.golden | 12 + integration/testdata/alpine-310.json.golden | 12 + .../alpine-39-high-critical.json.golden | 6 + .../alpine-39-ignore-cveids.json.golden | 6 + integration/testdata/alpine-39.json.golden | 18 + .../testdata/alpine-distroless.json.golden | 3 + integration/testdata/amazon-1.json.golden | 3 + integration/testdata/amazon-2.json.golden | 6 + .../amazonlinux2-gp2-x86-vm.json.golden | 3 + .../busybox-with-lockfile.json.golden | 6 + integration/testdata/centos-6.json.golden | 6 + .../centos-7-ignore-unfixed.json.golden | 6 + .../testdata/centos-7-medium.json.golden | 3 + integration/testdata/centos-7.json.golden | 9 + integration/testdata/cocoapods.json.golden | 6 + .../testdata/composer.lock.json.golden | 9 + integration/testdata/conan.json.golden | 24 + integration/testdata/conda-spdx.json.golden | 28 +- .../debian-buster-ignore-unfixed.json.golden | 3 + .../testdata/debian-buster.json.golden | 6 + .../testdata/debian-stretch.json.golden | 15 + .../testdata/distroless-base.json.golden | 12 + .../testdata/distroless-python27.json.golden | 12 + integration/testdata/dotnet.json.golden | 6 + integration/testdata/fluentd-gems.json.golden | 6 + .../fluentd-multiple-lockfiles.json.golden | 9 + integration/testdata/gomod-skip.json.golden | 12 + integration/testdata/gomod.json.golden | 15 + integration/testdata/gradle.json.golden | 6 + integration/testdata/mariner-1.0.json.golden | 6 + .../testdata/minikube-kbom.json.golden | 3 + integration/testdata/mix.lock.json.golden | 33 + integration/testdata/npm-with-dev.json.golden | 42 + integration/testdata/npm.json.golden | 39 + integration/testdata/nuget.json.golden | 9 + .../testdata/opensuse-leap-151.json.golden | 6 + .../testdata/oraclelinux-8.json.golden | 6 + .../testdata/packagesprops.json.golden | 6 + integration/testdata/photon-30.json.golden | 9 + integration/testdata/pip.json.golden | 27 + integration/testdata/pipenv.json.golden | 9 + integration/testdata/pnpm.json.golden | 6 + integration/testdata/poetry.json.golden | 12 + .../testdata/pom-cyclonedx.json.golden | 156 +-- integration/testdata/pom.json.golden | 6 + integration/testdata/pubspec.lock.json.golden | 9 + integration/testdata/rockylinux-8.json.golden | 3 + .../testdata/spring4shell-jre11.json.golden | 3 + .../testdata/spring4shell-jre8.json.golden | 3 + integration/testdata/swift.json.golden | 9 + integration/testdata/test-repo.json.golden | 6 + integration/testdata/ubi-7.json.golden | 3 + .../ubuntu-1804-ignore-unfixed.json.golden | 12 + integration/testdata/ubuntu-1804.json.golden | 15 + .../testdata/ubuntu-gp2-x86-vm.json.golden | 3 + integration/testdata/yarn.json.golden | 6 + pkg/detector/library/detect.go | 1 + pkg/detector/ospkg/alma/alma.go | 2 +- pkg/detector/ospkg/alpine/alpine.go | 1 + pkg/detector/ospkg/amazon/amazon.go | 1 + pkg/detector/ospkg/chainguard/chainguard.go | 1 + pkg/detector/ospkg/debian/debian.go | 1 + pkg/detector/ospkg/mariner/mariner.go | 1 + pkg/detector/ospkg/oracle/oracle.go | 1 + pkg/detector/ospkg/photon/photon.go | 1 + pkg/detector/ospkg/redhat/redhat.go | 1 + pkg/detector/ospkg/rocky/rocky.go | 1 + pkg/detector/ospkg/suse/suse.go | 1 + pkg/detector/ospkg/ubuntu/ubuntu.go | 1 + pkg/detector/ospkg/wolfi/wolfi.go | 1 + pkg/fanal/analyzer/imgconf/apk/apk.go | 12 +- pkg/fanal/analyzer/imgconf/apk/apk_test.go | 4 +- pkg/fanal/analyzer/language/analyze.go | 6 +- pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go | 5 +- pkg/fanal/analyzer/pkg/rpm/rpm_test.go | 7 +- pkg/fanal/analyzer/pkg/rpm/rpmqa.go | 5 +- pkg/fanal/analyzer/sbom/sbom.go | 6 +- pkg/fanal/analyzer/sbom/sbom_test.go | 114 ++ pkg/fanal/applier/applier_test.go | 174 +++ pkg/fanal/applier/docker.go | 83 +- pkg/fanal/applier/docker_test.go | 169 +++ pkg/fanal/artifact/image/remote_sbom_test.go | 58 +- pkg/fanal/artifact/local/fs_test.go | 20 +- pkg/fanal/artifact/sbom/sbom_test.go | 161 ++- pkg/fanal/artifact/vm/vm_test.go | 8 +- pkg/fanal/cache/fs_test.go | 4 + pkg/fanal/cache/mock_artifact_cache.go | 5 +- pkg/fanal/handler/sysfile/filter_test.go | 2 +- .../handler/unpackaged/unpackaged_test.go | 11 + pkg/fanal/test/integration/library_test.go | 8 + .../goldens/packages/alpine-310.json.golden | 42 + .../goldens/packages/vulnimage.json.golden | 174 +++ .../vuln-image1.2.3.expectedlibs.golden | 630 +++++++++ ...uln-image1.2.3.expectedpkgsfromcmds.golden | 1158 +++++------------ pkg/fanal/types/artifact.go | 47 +- pkg/fanal/types/handler.go | 3 +- pkg/fanal/types/purl.go | 78 ++ pkg/k8s/scanner/scanner.go | 8 +- pkg/k8s/scanner/scanner_test.go | 11 +- pkg/module/serialize/types_easyjson.go | 197 ++- pkg/purl/purl.go | 152 +-- pkg/purl/purl_test.go | 169 ++- pkg/report/github/github.go | 2 +- pkg/result/filter_test.go | 57 +- pkg/rpc/convert.go | 32 + pkg/sbom/cyclonedx/core/cyclonedx.go | 6 +- pkg/sbom/cyclonedx/core/cyclonedx_test.go | 8 +- pkg/sbom/cyclonedx/marshal.go | 11 +- pkg/sbom/cyclonedx/marshal_test.go | 315 ++++- pkg/sbom/cyclonedx/unmarshal.go | 51 +- pkg/sbom/cyclonedx/unmarshal_test.go | 339 ++++- pkg/sbom/spdx/marshal.go | 11 +- pkg/sbom/spdx/marshal_test.go | 142 +- pkg/sbom/spdx/unmarshal.go | 13 +- pkg/sbom/spdx/unmarshal_test.go | 167 ++- pkg/types/vulnerability.go | 26 +- pkg/vex/testdata/cyclonedx.json | 2 +- pkg/vex/testdata/openvex-multiple.json | 8 +- pkg/vex/testdata/openvex.json | 4 +- pkg/vex/vex.go | 21 +- pkg/vex/vex_test.go | 100 +- rpc/common/service.pb.go | 1035 ++++++++------- rpc/common/service.proto | 21 +- 126 files changed, 4728 insertions(+), 1963 deletions(-) create mode 100644 pkg/fanal/types/purl.go diff --git a/integration/client_server_test.go b/integration/client_server_test.go index 0fd0d0522ed9..c4274eb77a80 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -539,7 +539,7 @@ func TestClientServerWithRedis(t *testing.T) { // Run Trivy client err := execute(osArgs) require.Error(t, err) - assert.Contains(t, err.Error(), "connect: connection refused") + assert.Contains(t, err.Error(), "unable to store cache") }) } diff --git a/integration/sbom_test.go b/integration/sbom_test.go index c195e23d43df..5b657335d316 100644 --- a/integration/sbom_test.go +++ b/integration/sbom_test.go @@ -41,9 +41,15 @@ func TestSBOM(t *testing.T) { { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ - {PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, + { + PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -82,9 +88,15 @@ func TestSBOM(t *testing.T) { { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ - {PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, + { + PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -105,9 +117,15 @@ func TestSBOM(t *testing.T) { { Target: "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ - {PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, + { + PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -128,9 +146,15 @@ func TestSBOM(t *testing.T) { { Target: "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ - {PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, - {PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"}, + { + PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, + { + PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -200,6 +224,12 @@ func compareSBOMReports(t *testing.T, wantFile, gotFile string, overrideWant typ want.Results[i].Target = result.Target for j, vuln := range result.Vulnerabilities { want.Results[i].Vulnerabilities[j].PkgRef = vuln.PkgRef + if vuln.PkgIdentifier.Empty() { + continue + } + want.Results[i].Vulnerabilities[j].PkgIdentifier = ftypes.PkgIdentifier{ + PURL: vuln.PkgIdentifier.PURL, + } } } diff --git a/integration/testdata/almalinux-8.json.golden b/integration/testdata/almalinux-8.json.golden index c2ae9382f4b4..409e02d6e9bd 100644 --- a/integration/testdata/almalinux-8.json.golden +++ b/integration/testdata/almalinux-8.json.golden @@ -56,6 +56,9 @@ "VulnerabilityID": "CVE-2021-3712", "PkgID": "openssl-libs@1.1.1k-4.el8.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/alma/openssl-libs@1.1.1k-4.el8?arch=x86_64\u0026distro=alma-8.5\u0026epoch=1" + }, "InstalledVersion": "1:1.1.1k-4.el8", "FixedVersion": "1:1.1.1k-5.el8_5", "Status": "fixed", diff --git a/integration/testdata/alpine-310-registry.json.golden b/integration/testdata/alpine-310-registry.json.golden index df64131304b2..cf451bbd7bfb 100644 --- a/integration/testdata/alpine-310-registry.json.golden +++ b/integration/testdata/alpine-310-registry.json.golden @@ -64,6 +64,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libcrypto1.1@1.1.1c-r0", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -133,6 +136,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libcrypto1.1@1.1.1c-r0", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r2", "Status": "fixed", @@ -212,6 +218,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libssl1.1@1.1.1c-r0", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -281,6 +290,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.1c-r0", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r2", "Status": "fixed", diff --git a/integration/testdata/alpine-310.json.golden b/integration/testdata/alpine-310.json.golden index 8c591c26815c..d6b4a7884027 100644 --- a/integration/testdata/alpine-310.json.golden +++ b/integration/testdata/alpine-310.json.golden @@ -58,6 +58,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libcrypto1.1@1.1.1c-r0", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -127,6 +130,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libcrypto1.1@1.1.1c-r0", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r2", "Status": "fixed", @@ -206,6 +212,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libssl1.1@1.1.1c-r0", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -275,6 +284,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.1c-r0", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "InstalledVersion": "1.1.1c-r0", "FixedVersion": "1.1.1d-r2", "Status": "fixed", diff --git a/integration/testdata/alpine-39-high-critical.json.golden b/integration/testdata/alpine-39-high-critical.json.golden index fc61f908f444..73288f579caa 100644 --- a/integration/testdata/alpine-39-high-critical.json.golden +++ b/integration/testdata/alpine-39-high-critical.json.golden @@ -58,6 +58,9 @@ "VulnerabilityID": "CVE-2019-14697", "PkgID": "musl@1.1.20-r4", "PkgName": "musl", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/musl@1.1.20-r4?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.20-r4", "FixedVersion": "1.1.20-r5", "Status": "fixed", @@ -100,6 +103,9 @@ "VulnerabilityID": "CVE-2019-14697", "PkgID": "musl-utils@1.1.20-r4", "PkgName": "musl-utils", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/musl-utils@1.1.20-r4?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.20-r4", "FixedVersion": "1.1.20-r5", "Status": "fixed", diff --git a/integration/testdata/alpine-39-ignore-cveids.json.golden b/integration/testdata/alpine-39-ignore-cveids.json.golden index e620ebe42066..f11198c2364e 100644 --- a/integration/testdata/alpine-39-ignore-cveids.json.golden +++ b/integration/testdata/alpine-39-ignore-cveids.json.golden @@ -58,6 +58,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libcrypto1.1@1.1.1b-r1", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r2", "Status": "fixed", @@ -137,6 +140,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.1b-r1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r2", "Status": "fixed", diff --git a/integration/testdata/alpine-39.json.golden b/integration/testdata/alpine-39.json.golden index 7781ccc44c21..303f7a3c7277 100644 --- a/integration/testdata/alpine-39.json.golden +++ b/integration/testdata/alpine-39.json.golden @@ -58,6 +58,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libcrypto1.1@1.1.1b-r1", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -127,6 +130,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libcrypto1.1@1.1.1b-r1", "PkgName": "libcrypto1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r2", "Status": "fixed", @@ -206,6 +212,9 @@ "VulnerabilityID": "CVE-2019-1549", "PkgID": "libssl1.1@1.1.1b-r1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r0", "Status": "fixed", @@ -275,6 +284,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.1b-r1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.1b-r1", "FixedVersion": "1.1.1d-r2", "Status": "fixed", @@ -354,6 +366,9 @@ "VulnerabilityID": "CVE-2019-14697", "PkgID": "musl@1.1.20-r4", "PkgName": "musl", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/musl@1.1.20-r4?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.20-r4", "FixedVersion": "1.1.20-r5", "Status": "fixed", @@ -396,6 +411,9 @@ "VulnerabilityID": "CVE-2019-14697", "PkgID": "musl-utils@1.1.20-r4", "PkgName": "musl-utils", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/musl-utils@1.1.20-r4?arch=x86_64\u0026distro=3.9.4" + }, "InstalledVersion": "1.1.20-r4", "FixedVersion": "1.1.20-r5", "Status": "fixed", diff --git a/integration/testdata/alpine-distroless.json.golden b/integration/testdata/alpine-distroless.json.golden index 6896e3c56053..8f79cba7610c 100644 --- a/integration/testdata/alpine-distroless.json.golden +++ b/integration/testdata/alpine-distroless.json.golden @@ -53,6 +53,9 @@ "VulnerabilityID": "CVE-2022-24765", "PkgID": "git@2.35.1-r2", "PkgName": "git", + "PkgIdentifier": { + "PURL": "pkg:apk/alpine/git@2.35.1-r2?arch=x86_64\u0026distro=3.16" + }, "InstalledVersion": "2.35.1-r2", "FixedVersion": "2.35.2-r0", "Status": "fixed", diff --git a/integration/testdata/amazon-1.json.golden b/integration/testdata/amazon-1.json.golden index dde37a90724c..6be4b41ffe3b 100644 --- a/integration/testdata/amazon-1.json.golden +++ b/integration/testdata/amazon-1.json.golden @@ -57,6 +57,9 @@ "VulnerabilityID": "CVE-2019-5481", "PkgID": "curl@7.61.1-11.91.amzn1.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/amazon/curl@7.61.1-11.91.amzn1?arch=x86_64\u0026distro=amazon-AMI+release+2018.03" + }, "InstalledVersion": "7.61.1-11.91.amzn1", "FixedVersion": "7.61.1-12.93.amzn1", "Status": "fixed", diff --git a/integration/testdata/amazon-2.json.golden b/integration/testdata/amazon-2.json.golden index ba19b615dfd7..1f20d8d37b68 100644 --- a/integration/testdata/amazon-2.json.golden +++ b/integration/testdata/amazon-2.json.golden @@ -57,6 +57,9 @@ "VulnerabilityID": "CVE-2019-5481", "PkgID": "curl@7.61.1-9.amzn2.0.1.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/amazon/curl@7.61.1-9.amzn2.0.1?arch=x86_64\u0026distro=amazon-2+%28Karoo%29" + }, "InstalledVersion": "7.61.1-9.amzn2.0.1", "FixedVersion": "7.61.1-12.amzn2.0.1", "Status": "fixed", @@ -125,6 +128,9 @@ "VulnerabilityID": "CVE-2019-5436", "PkgID": "curl@7.61.1-9.amzn2.0.1.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/amazon/curl@7.61.1-9.amzn2.0.1?arch=x86_64\u0026distro=amazon-2+%28Karoo%29" + }, "InstalledVersion": "7.61.1-9.amzn2.0.1", "FixedVersion": "7.61.1-11.amzn2.0.2", "Status": "fixed", diff --git a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden index fe220cabad2e..27cda6c2b6e7 100644 --- a/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden +++ b/integration/testdata/amazonlinux2-gp2-x86-vm.json.golden @@ -29,6 +29,9 @@ "VulnerabilityID": "CVE-2022-38177", "PkgID": "bind-export-libs@9.11.4-26.P2.amzn2.5.2.x86_64", "PkgName": "bind-export-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/amazon/bind-export-libs@9.11.4-26.P2.amzn2.5.2?arch=x86_64\u0026distro=amazon-2+%28Karoo%29\u0026epoch=32" + }, "InstalledVersion": "32:9.11.4-26.P2.amzn2.5.2", "FixedVersion": "99:9.11.4-26.P2.amzn2.13", "Status": "fixed", diff --git a/integration/testdata/busybox-with-lockfile.json.golden b/integration/testdata/busybox-with-lockfile.json.golden index 8c02e02b4d6f..520afe2de928 100644 --- a/integration/testdata/busybox-with-lockfile.json.golden +++ b/integration/testdata/busybox-with-lockfile.json.golden @@ -57,6 +57,9 @@ "VulnerabilityID": "CVE-2019-15542", "PkgID": "ammonia@1.9.0", "PkgName": "ammonia", + "PkgIdentifier": { + "PURL": "pkg:cargo/ammonia@1.9.0" + }, "InstalledVersion": "1.9.0", "FixedVersion": "\u003e= 2.1.0", "Status": "fixed", @@ -99,6 +102,9 @@ "VulnerabilityID": "CVE-2021-38193", "PkgID": "ammonia@1.9.0", "PkgName": "ammonia", + "PkgIdentifier": { + "PURL": "pkg:cargo/ammonia@1.9.0" + }, "InstalledVersion": "1.9.0", "FixedVersion": "\u003e= 3.1.0, \u003e= 2.1.3, \u003c 3.0.0", "Status": "fixed", diff --git a/integration/testdata/centos-6.json.golden b/integration/testdata/centos-6.json.golden index d8cb95553e79..c1791c58a486 100644 --- a/integration/testdata/centos-6.json.golden +++ b/integration/testdata/centos-6.json.golden @@ -79,6 +79,9 @@ "VulnerabilityID": "CVE-2020-29573", "PkgID": "glibc@2.12-1.212.el6.x86_64", "PkgName": "glibc", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/glibc@2.12-1.212.el6?arch=x86_64\u0026distro=centos-6.10" + }, "InstalledVersion": "2.12-1.212.el6", "Status": "end_of_life", "Layer": { @@ -132,6 +135,9 @@ ], "PkgID": "openssl@1.0.1e-57.el6.x86_64", "PkgName": "openssl", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl@1.0.1e-57.el6?arch=x86_64\u0026distro=centos-6.10" + }, "InstalledVersion": "1.0.1e-57.el6", "FixedVersion": "1.0.1e-58.el6_10", "Status": "fixed", diff --git a/integration/testdata/centos-7-ignore-unfixed.json.golden b/integration/testdata/centos-7-ignore-unfixed.json.golden index 49777f004005..ad8379a5d80e 100644 --- a/integration/testdata/centos-7-ignore-unfixed.json.golden +++ b/integration/testdata/centos-7-ignore-unfixed.json.golden @@ -72,6 +72,9 @@ ], "PkgID": "openssl-libs@1.0.2k-16.el7.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810\u0026epoch=1" + }, "InstalledVersion": "1:1.0.2k-16.el7", "FixedVersion": "1:1.0.2k-19.el7", "Status": "fixed", @@ -162,6 +165,9 @@ ], "PkgID": "openssl-libs@1.0.2k-16.el7.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810\u0026epoch=1" + }, "InstalledVersion": "1:1.0.2k-16.el7", "FixedVersion": "1:1.0.2k-19.el7", "Status": "fixed", diff --git a/integration/testdata/centos-7-medium.json.golden b/integration/testdata/centos-7-medium.json.golden index eb54be5b1315..ef4a44d2bbe5 100644 --- a/integration/testdata/centos-7-medium.json.golden +++ b/integration/testdata/centos-7-medium.json.golden @@ -72,6 +72,9 @@ ], "PkgID": "openssl-libs@1.0.2k-16.el7.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810\u0026epoch=1" + }, "InstalledVersion": "1:1.0.2k-16.el7", "FixedVersion": "1:1.0.2k-19.el7", "Status": "fixed", diff --git a/integration/testdata/centos-7.json.golden b/integration/testdata/centos-7.json.golden index 333ce10d4e5f..55ea768c99a8 100644 --- a/integration/testdata/centos-7.json.golden +++ b/integration/testdata/centos-7.json.golden @@ -69,6 +69,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@4.2.46-31.el7.x86_64", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64\u0026distro=centos-7.6.1810" + }, "InstalledVersion": "4.2.46-31.el7", "Status": "will_not_fix", "Layer": { @@ -126,6 +129,9 @@ ], "PkgID": "openssl-libs@1.0.2k-16.el7.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810\u0026epoch=1" + }, "InstalledVersion": "1:1.0.2k-16.el7", "FixedVersion": "1:1.0.2k-19.el7", "Status": "fixed", @@ -216,6 +222,9 @@ ], "PkgID": "openssl-libs@1.0.2k-16.el7.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810\u0026epoch=1" + }, "InstalledVersion": "1:1.0.2k-16.el7", "FixedVersion": "1:1.0.2k-19.el7", "Status": "fixed", diff --git a/integration/testdata/cocoapods.json.golden b/integration/testdata/cocoapods.json.golden index 71c4651e8158..9553f0624286 100644 --- a/integration/testdata/cocoapods.json.golden +++ b/integration/testdata/cocoapods.json.golden @@ -24,6 +24,9 @@ { "ID": "_NIODataStructures@2.41.0", "Name": "_NIODataStructures", + "Identifier": { + "PURL": "pkg:cocoapods/_NIODataStructures@2.41.0" + }, "Version": "2.41.0", "Layer": {} } @@ -33,6 +36,9 @@ "VulnerabilityID": "CVE-2022-3215", "PkgID": "_NIODataStructures@2.41.0", "PkgName": "_NIODataStructures", + "PkgIdentifier": { + "PURL": "pkg:cocoapods/_NIODataStructures@2.41.0" + }, "InstalledVersion": "2.41.0", "FixedVersion": "2.29.1, 2.39.1, 2.42.0", "Status": "fixed", diff --git a/integration/testdata/composer.lock.json.golden b/integration/testdata/composer.lock.json.golden index 02718c7cab3d..a3bdf13f9ece 100644 --- a/integration/testdata/composer.lock.json.golden +++ b/integration/testdata/composer.lock.json.golden @@ -24,6 +24,9 @@ { "ID": "guzzlehttp/guzzle@7.4.4", "Name": "guzzlehttp/guzzle", + "Identifier": { + "PURL": "pkg:composer/guzzlehttp/guzzle@7.4.4" + }, "Version": "7.4.4", "Licenses": [ "MIT" @@ -42,6 +45,9 @@ { "ID": "guzzlehttp/psr7@1.8.3", "Name": "guzzlehttp/psr7", + "Identifier": { + "PURL": "pkg:composer/guzzlehttp/psr7@1.8.3" + }, "Version": "1.8.3", "Licenses": [ "MIT" @@ -61,6 +67,9 @@ "VulnerabilityID": "CVE-2022-24775", "PkgID": "guzzlehttp/psr7@1.8.3", "PkgName": "guzzlehttp/psr7", + "PkgIdentifier": { + "PURL": "pkg:composer/guzzlehttp/psr7@1.8.3" + }, "InstalledVersion": "1.8.3", "FixedVersion": "1.8.4", "Status": "fixed", diff --git a/integration/testdata/conan.json.golden b/integration/testdata/conan.json.golden index 3b0d8d4f4e0d..ee60780c1d5f 100644 --- a/integration/testdata/conan.json.golden +++ b/integration/testdata/conan.json.golden @@ -24,6 +24,9 @@ { "ID": "bzip2/1.0.8", "Name": "bzip2", + "Identifier": { + "PURL": "pkg:conan/bzip2@1.0.8" + }, "Version": "1.0.8", "Indirect": true, "Layer": {}, @@ -37,6 +40,9 @@ { "ID": "expat/2.4.8", "Name": "expat", + "Identifier": { + "PURL": "pkg:conan/expat@2.4.8" + }, "Version": "2.4.8", "Indirect": true, "Layer": {}, @@ -50,6 +56,9 @@ { "ID": "openssl/1.1.1q", "Name": "openssl", + "Identifier": { + "PURL": "pkg:conan/openssl@1.1.1q" + }, "Version": "1.1.1q", "Indirect": true, "Layer": {}, @@ -63,6 +72,9 @@ { "ID": "pcre/8.43", "Name": "pcre", + "Identifier": { + "PURL": "pkg:conan/pcre@8.43" + }, "Version": "8.43", "Indirect": true, "DependsOn": [ @@ -80,6 +92,9 @@ { "ID": "poco/1.9.4", "Name": "poco", + "Identifier": { + "PURL": "pkg:conan/poco@1.9.4" + }, "Version": "1.9.4", "DependsOn": [ "pcre/8.43", @@ -99,6 +114,9 @@ { "ID": "sqlite3/3.39.2", "Name": "sqlite3", + "Identifier": { + "PURL": "pkg:conan/sqlite3@3.39.2" + }, "Version": "3.39.2", "Indirect": true, "Layer": {}, @@ -112,6 +130,9 @@ { "ID": "zlib/1.2.12", "Name": "zlib", + "Identifier": { + "PURL": "pkg:conan/zlib@1.2.12" + }, "Version": "1.2.12", "Indirect": true, "Layer": {}, @@ -128,6 +149,9 @@ "VulnerabilityID": "CVE-2020-14155", "PkgID": "pcre/8.43", "PkgName": "pcre", + "PkgIdentifier": { + "PURL": "pkg:conan/pcre@8.43" + }, "InstalledVersion": "8.43", "FixedVersion": "8.45", "Status": "fixed", diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index 73b3394e6697..4803da139d8c 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -22,7 +22,7 @@ }, { "name": "openssl", - "SPDXID": "SPDXRef-Package-c75d9dc75200186f", + "SPDXID": "SPDXRef-Package-a4bad823866cc210", "versionInfo": "1.1.1q", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -43,7 +43,7 @@ }, { "name": "pip", - "SPDXID": "SPDXRef-Package-195557cddf18e4a9", + "SPDXID": "SPDXRef-Package-e8a0eb2c9979a021", "versionInfo": "22.2.2", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -75,23 +75,23 @@ ], "files": [ { - "fileName": "miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json", - "SPDXID": "SPDXRef-File-7eb62e2a3edddc0a", + "fileName": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json", + "SPDXID": "SPDXRef-File-600e5e0110a84891", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "a6a2db7668f1ad541d704369fc66c96a4415aa24" + "checksumValue": "237db0da53131e4548cb1181337fa0f420299e1f" } ], "copyrightText": "" }, { - "fileName": "miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json", - "SPDXID": "SPDXRef-File-600e5e0110a84891", + "fileName": "miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json", + "SPDXID": "SPDXRef-File-7eb62e2a3edddc0a", "checksums": [ { "algorithm": "SHA1", - "checksumValue": "237db0da53131e4548cb1181337fa0f420299e1f" + "checksumValue": "a6a2db7668f1ad541d704369fc66c96a4415aa24" } ], "copyrightText": "" @@ -110,22 +110,22 @@ }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-195557cddf18e4a9", + "relatedSpdxElement": "SPDXRef-Package-a4bad823866cc210", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-195557cddf18e4a9", - "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", + "spdxElementId": "SPDXRef-Package-a4bad823866cc210", + "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-c75d9dc75200186f", + "relatedSpdxElement": "SPDXRef-Package-e8a0eb2c9979a021", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-c75d9dc75200186f", - "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", + "spdxElementId": "SPDXRef-Package-e8a0eb2c9979a021", + "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", "relationshipType": "CONTAINS" } ] diff --git a/integration/testdata/debian-buster-ignore-unfixed.json.golden b/integration/testdata/debian-buster-ignore-unfixed.json.golden index 0ef080d4a7a7..0d387db18fbf 100644 --- a/integration/testdata/debian-buster-ignore-unfixed.json.golden +++ b/integration/testdata/debian-buster-ignore-unfixed.json.golden @@ -60,6 +60,9 @@ ], "PkgID": "libidn2-0@2.0.5-1", "PkgName": "libidn2-0", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.1" + }, "InstalledVersion": "2.0.5-1", "FixedVersion": "2.0.5-1+deb10u1", "Status": "fixed", diff --git a/integration/testdata/debian-buster.json.golden b/integration/testdata/debian-buster.json.golden index 67a40b7b5a58..739158b5fe6e 100644 --- a/integration/testdata/debian-buster.json.golden +++ b/integration/testdata/debian-buster.json.golden @@ -57,6 +57,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@5.0-4", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.1" + }, "InstalledVersion": "5.0-4", "Status": "affected", "Layer": { @@ -120,6 +123,9 @@ ], "PkgID": "libidn2-0@2.0.5-1", "PkgName": "libidn2-0", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.1" + }, "InstalledVersion": "2.0.5-1", "FixedVersion": "2.0.5-1+deb10u1", "Status": "fixed", diff --git a/integration/testdata/debian-stretch.json.golden b/integration/testdata/debian-stretch.json.golden index 7c8893cbdad7..6fd20bda1ee8 100644 --- a/integration/testdata/debian-stretch.json.golden +++ b/integration/testdata/debian-stretch.json.golden @@ -58,6 +58,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@4.4-5", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/bash@4.4-5?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "4.4-5", "Status": "end_of_life", "Layer": { @@ -121,6 +124,9 @@ ], "PkgID": "e2fslibs@1.43.4-2", "PkgName": "e2fslibs", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/e2fslibs@1.43.4-2?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.43.4-2", "FixedVersion": "1.43.4-2+deb9u1", "Status": "fixed", @@ -191,6 +197,9 @@ ], "PkgID": "e2fsprogs@1.43.4-2", "PkgName": "e2fsprogs", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/e2fsprogs@1.43.4-2?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.43.4-2", "FixedVersion": "1.43.4-2+deb9u1", "Status": "fixed", @@ -261,6 +270,9 @@ ], "PkgID": "libcomerr2@1.43.4-2", "PkgName": "libcomerr2", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libcomerr2@1.43.4-2?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.43.4-2", "FixedVersion": "1.43.4-2+deb9u1", "Status": "fixed", @@ -331,6 +343,9 @@ ], "PkgID": "libss2@1.43.4-2", "PkgName": "libss2", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libss2@1.43.4-2?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.43.4-2", "FixedVersion": "1.43.4-2+deb9u1", "Status": "fixed", diff --git a/integration/testdata/distroless-base.json.golden b/integration/testdata/distroless-base.json.golden index b9ce4e3b400d..82de2d5368b9 100644 --- a/integration/testdata/distroless-base.json.golden +++ b/integration/testdata/distroless-base.json.golden @@ -56,6 +56,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.0k-1~deb9u1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libssl1.1@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "Status": "affected", "Layer": { @@ -137,6 +140,9 @@ ], "PkgID": "libssl1.1@1.1.0k-1~deb9u1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libssl1.1@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "FixedVersion": "1.1.0l-1~deb9u1", "Status": "fixed", @@ -224,6 +230,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "openssl@1.1.0k-1~deb9u1", "PkgName": "openssl", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/openssl@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "Status": "affected", "Layer": { @@ -305,6 +314,9 @@ ], "PkgID": "openssl@1.1.0k-1~deb9u1", "PkgName": "openssl", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/openssl@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "FixedVersion": "1.1.0l-1~deb9u1", "Status": "fixed", diff --git a/integration/testdata/distroless-python27.json.golden b/integration/testdata/distroless-python27.json.golden index d97edd78bfed..f8d54b339867 100644 --- a/integration/testdata/distroless-python27.json.golden +++ b/integration/testdata/distroless-python27.json.golden @@ -73,6 +73,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "libssl1.1@1.1.0k-1~deb9u1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libssl1.1@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "Status": "affected", "Layer": { @@ -154,6 +157,9 @@ ], "PkgID": "libssl1.1@1.1.0k-1~deb9u1", "PkgName": "libssl1.1", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libssl1.1@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "FixedVersion": "1.1.0l-1~deb9u1", "Status": "fixed", @@ -241,6 +247,9 @@ "VulnerabilityID": "CVE-2019-1551", "PkgID": "openssl@1.1.0k-1~deb9u1", "PkgName": "openssl", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/openssl@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "Status": "affected", "Layer": { @@ -322,6 +331,9 @@ ], "PkgID": "openssl@1.1.0k-1~deb9u1", "PkgName": "openssl", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/openssl@1.1.0k-1~deb9u1?arch=amd64\u0026distro=debian-9.9" + }, "InstalledVersion": "1.1.0k-1~deb9u1", "FixedVersion": "1.1.0l-1~deb9u1", "Status": "fixed", diff --git a/integration/testdata/dotnet.json.golden b/integration/testdata/dotnet.json.golden index c2d51a2080aa..264b28d7534d 100644 --- a/integration/testdata/dotnet.json.golden +++ b/integration/testdata/dotnet.json.golden @@ -23,6 +23,9 @@ "Packages": [ { "Name": "Newtonsoft.Json", + "Identifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@9.0.1" + }, "Version": "9.0.1", "Layer": {}, "Locations": [ @@ -37,6 +40,9 @@ { "VulnerabilityID": "GHSA-5crp-9r3c-p9vr", "PkgName": "Newtonsoft.Json", + "PkgIdentifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@9.0.1" + }, "InstalledVersion": "9.0.1", "FixedVersion": "13.0.1", "Status": "fixed", diff --git a/integration/testdata/fluentd-gems.json.golden b/integration/testdata/fluentd-gems.json.golden index eb24957e0a13..2072e0c4bf8d 100644 --- a/integration/testdata/fluentd-gems.json.golden +++ b/integration/testdata/fluentd-gems.json.golden @@ -113,6 +113,9 @@ ], "PkgID": "libidn2-0@2.0.5-1", "PkgName": "libidn2-0", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.2" + }, "InstalledVersion": "2.0.5-1", "FixedVersion": "2.0.5-1+deb10u1", "Status": "fixed", @@ -181,6 +184,9 @@ "VulnerabilityID": "CVE-2020-8165", "PkgName": "activesupport", "PkgPath": "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", + "PkgIdentifier": { + "PURL": "pkg:gem/activesupport@6.0.2.1" + }, "InstalledVersion": "6.0.2.1", "FixedVersion": "6.0.3.1, 5.2.4.3", "Status": "fixed", diff --git a/integration/testdata/fluentd-multiple-lockfiles.json.golden b/integration/testdata/fluentd-multiple-lockfiles.json.golden index c067638c8dd1..784f9f1a0339 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.json.golden @@ -28,6 +28,9 @@ { "VulnerabilityID": "CVE-2019-18276", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2" + }, "InstalledVersion": "5.0-4", "Status": "affected", "Layer": {}, @@ -88,6 +91,9 @@ "DSA-4613-1" ], "PkgName": "libidn2-0", + "PkgIdentifier": { + "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2" + }, "InstalledVersion": "2.0.5-1", "FixedVersion": "2.0.5-1+deb10u1", "Status": "fixed", @@ -154,6 +160,9 @@ "VulnerabilityID": "CVE-2020-8165", "PkgName": "activesupport", "PkgPath": "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", + "PkgIdentifier": { + "PURL": "pkg:gem/activesupport@6.0.2.1" + }, "InstalledVersion": "6.0.2.1", "FixedVersion": "6.0.3.1, 5.2.4.3", "Status": "fixed", diff --git a/integration/testdata/gomod-skip.json.golden b/integration/testdata/gomod-skip.json.golden index 8f1e4f643cdc..ce748cc19823 100644 --- a/integration/testdata/gomod-skip.json.golden +++ b/integration/testdata/gomod-skip.json.golden @@ -25,6 +25,9 @@ "VulnerabilityID": "GMS-2022-20", "PkgID": "github.com/docker/distribution@v2.7.1+incompatible", "PkgName": "github.com/docker/distribution", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible" + }, "InstalledVersion": "2.7.1+incompatible", "FixedVersion": "v2.8.0", "Status": "fixed", @@ -48,6 +51,9 @@ "VulnerabilityID": "CVE-2022-23628", "PkgID": "github.com/open-policy-agent/opa@v0.35.0", "PkgName": "github.com/open-policy-agent/opa", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/open-policy-agent/opa@0.35.0" + }, "InstalledVersion": "0.35.0", "FixedVersion": "0.37.0", "Status": "fixed", @@ -91,6 +97,9 @@ "VulnerabilityID": "CVE-2021-38561", "PkgID": "golang.org/x/text@v0.3.6", "PkgName": "golang.org/x/text", + "PkgIdentifier": { + "PURL": "pkg:golang/golang.org/x/text@0.3.6" + }, "InstalledVersion": "0.3.6", "FixedVersion": "0.3.7", "Status": "fixed", @@ -120,6 +129,9 @@ "VulnerabilityID": "GMS-2022-20", "PkgID": "github.com/docker/distribution@v2.7.1+incompatible", "PkgName": "github.com/docker/distribution", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible" + }, "InstalledVersion": "2.7.1+incompatible", "FixedVersion": "v2.8.0", "Status": "fixed", diff --git a/integration/testdata/gomod.json.golden b/integration/testdata/gomod.json.golden index 4d553e7ca2c7..5009b9d3bf81 100644 --- a/integration/testdata/gomod.json.golden +++ b/integration/testdata/gomod.json.golden @@ -25,6 +25,9 @@ "VulnerabilityID": "GMS-2022-20", "PkgID": "github.com/docker/distribution@v2.7.1+incompatible", "PkgName": "github.com/docker/distribution", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible" + }, "InstalledVersion": "2.7.1+incompatible", "FixedVersion": "v2.8.0", "Status": "fixed", @@ -48,6 +51,9 @@ "VulnerabilityID": "CVE-2022-23628", "PkgID": "github.com/open-policy-agent/opa@v0.35.0", "PkgName": "github.com/open-policy-agent/opa", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/open-policy-agent/opa@0.35.0" + }, "InstalledVersion": "0.35.0", "FixedVersion": "0.37.0", "Status": "fixed", @@ -91,6 +97,9 @@ "VulnerabilityID": "CVE-2021-38561", "PkgID": "golang.org/x/text@v0.3.6", "PkgName": "golang.org/x/text", + "PkgIdentifier": { + "PURL": "pkg:golang/golang.org/x/text@0.3.6" + }, "InstalledVersion": "0.3.6", "FixedVersion": "0.3.7", "Status": "fixed", @@ -120,6 +129,9 @@ "VulnerabilityID": "GMS-2022-20", "PkgID": "github.com/docker/distribution@v2.7.1+incompatible", "PkgName": "github.com/docker/distribution", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible" + }, "InstalledVersion": "2.7.1+incompatible", "FixedVersion": "v2.8.0", "Status": "fixed", @@ -150,6 +162,9 @@ "VulnerabilityID": "GMS-2022-20", "PkgID": "github.com/docker/distribution@v2.7.1+incompatible", "PkgName": "github.com/docker/distribution", + "PkgIdentifier": { + "PURL": "pkg:golang/github.com/docker/distribution@2.7.1%2Bincompatible" + }, "InstalledVersion": "2.7.1+incompatible", "FixedVersion": "v2.8.0", "Status": "fixed", diff --git a/integration/testdata/gradle.json.golden b/integration/testdata/gradle.json.golden index 9ff2b02aeb8d..4979b31fbedf 100644 --- a/integration/testdata/gradle.json.golden +++ b/integration/testdata/gradle.json.golden @@ -24,6 +24,9 @@ { "VulnerabilityID": "CVE-2020-9548", "PkgName": "com.fasterxml.jackson.core:jackson-databind", + "PkgIdentifier": { + "PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1" + }, "InstalledVersion": "2.9.1", "FixedVersion": "2.9.10.4", "Status": "fixed", @@ -85,6 +88,9 @@ { "VulnerabilityID": "CVE-2021-20190", "PkgName": "com.fasterxml.jackson.core:jackson-databind", + "PkgIdentifier": { + "PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1" + }, "InstalledVersion": "2.9.1", "FixedVersion": "2.9.10.7", "Status": "fixed", diff --git a/integration/testdata/mariner-1.0.json.golden b/integration/testdata/mariner-1.0.json.golden index 4b5ac7b7363d..435dd5bdf7a6 100644 --- a/integration/testdata/mariner-1.0.json.golden +++ b/integration/testdata/mariner-1.0.json.golden @@ -41,6 +41,9 @@ { "VulnerabilityID": "CVE-2022-0261", "PkgName": "vim", + "PkgIdentifier": { + "PURL": "pkg:cbl-mariner/vim@8.2.4081-1.cm1?arch=x86_64" + }, "InstalledVersion": "8.2.4081-1.cm1", "Status": "affected", "Layer": { @@ -74,6 +77,9 @@ { "VulnerabilityID": "CVE-2022-0158", "PkgName": "vim", + "PkgIdentifier": { + "PURL": "pkg:cbl-mariner/vim@8.2.4081-1.cm1?arch=x86_64" + }, "InstalledVersion": "8.2.4081-1.cm1", "FixedVersion": "8.2.4082-1.cm1", "Status": "fixed", diff --git a/integration/testdata/minikube-kbom.json.golden b/integration/testdata/minikube-kbom.json.golden index e144904828e4..5a4ee8ed2949 100644 --- a/integration/testdata/minikube-kbom.json.golden +++ b/integration/testdata/minikube-kbom.json.golden @@ -33,6 +33,9 @@ { "VulnerabilityID": "CVE-2023-2431", "PkgName": "k8s.io/kubelet", + "PkgIdentifier": { + "PURL": "pkg:k8s/k8s.io%2Fkubelet@1.27.0" + }, "InstalledVersion": "1.27.0", "FixedVersion": "1.24.14, 1.25.9, 1.26.4, 1.27.1", "Status": "fixed", diff --git a/integration/testdata/mix.lock.json.golden b/integration/testdata/mix.lock.json.golden index 76eb19ece6a0..54445fbf9cfa 100644 --- a/integration/testdata/mix.lock.json.golden +++ b/integration/testdata/mix.lock.json.golden @@ -24,6 +24,9 @@ { "ID": "castore@0.1.18", "Name": "castore", + "Identifier": { + "PURL": "pkg:hex/castore@0.1.18" + }, "Version": "0.1.18", "Layer": {}, "Locations": [ @@ -36,6 +39,9 @@ { "ID": "jason@1.4.0", "Name": "jason", + "Identifier": { + "PURL": "pkg:hex/jason@1.4.0" + }, "Version": "1.4.0", "Layer": {}, "Locations": [ @@ -48,6 +54,9 @@ { "ID": "phoenix@1.6.13", "Name": "phoenix", + "Identifier": { + "PURL": "pkg:hex/phoenix@1.6.13" + }, "Version": "1.6.13", "Layer": {}, "Locations": [ @@ -60,6 +69,9 @@ { "ID": "phoenix_html@3.2.0", "Name": "phoenix_html", + "Identifier": { + "PURL": "pkg:hex/phoenix_html@3.2.0" + }, "Version": "3.2.0", "Layer": {}, "Locations": [ @@ -72,6 +84,9 @@ { "ID": "phoenix_pubsub@2.1.1", "Name": "phoenix_pubsub", + "Identifier": { + "PURL": "pkg:hex/phoenix_pubsub@2.1.1" + }, "Version": "2.1.1", "Layer": {}, "Locations": [ @@ -84,6 +99,9 @@ { "ID": "phoenix_template@1.0.0", "Name": "phoenix_template", + "Identifier": { + "PURL": "pkg:hex/phoenix_template@1.0.0" + }, "Version": "1.0.0", "Layer": {}, "Locations": [ @@ -96,6 +114,9 @@ { "ID": "phoenix_view@2.0.1", "Name": "phoenix_view", + "Identifier": { + "PURL": "pkg:hex/phoenix_view@2.0.1" + }, "Version": "2.0.1", "Layer": {}, "Locations": [ @@ -108,6 +129,9 @@ { "ID": "plug@1.14.0", "Name": "plug", + "Identifier": { + "PURL": "pkg:hex/plug@1.14.0" + }, "Version": "1.14.0", "Layer": {}, "Locations": [ @@ -120,6 +144,9 @@ { "ID": "plug_crypto@1.2.3", "Name": "plug_crypto", + "Identifier": { + "PURL": "pkg:hex/plug_crypto@1.2.3" + }, "Version": "1.2.3", "Layer": {}, "Locations": [ @@ -132,6 +159,9 @@ { "ID": "telemetry@1.1.0", "Name": "telemetry", + "Identifier": { + "PURL": "pkg:hex/telemetry@1.1.0" + }, "Version": "1.1.0", "Layer": {}, "Locations": [ @@ -147,6 +177,9 @@ "VulnerabilityID": "CVE-2022-42975", "PkgID": "phoenix@1.6.13", "PkgName": "phoenix", + "PkgIdentifier": { + "PURL": "pkg:hex/phoenix@1.6.13" + }, "InstalledVersion": "1.6.13", "FixedVersion": "1.6.14", "Status": "fixed", diff --git a/integration/testdata/npm-with-dev.json.golden b/integration/testdata/npm-with-dev.json.golden index 071bfd18d643..a512e5247910 100644 --- a/integration/testdata/npm-with-dev.json.golden +++ b/integration/testdata/npm-with-dev.json.golden @@ -24,6 +24,9 @@ { "ID": "asap@2.0.6", "Name": "asap", + "Identifier": { + "PURL": "pkg:npm/asap@2.0.6" + }, "Version": "2.0.6", "Indirect": true, "Layer": {}, @@ -37,6 +40,9 @@ { "ID": "jquery@3.3.9", "Name": "jquery", + "Identifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "Version": "3.3.9", "Licenses": [ "MIT" @@ -53,6 +59,9 @@ { "ID": "js-tokens@4.0.0", "Name": "js-tokens", + "Identifier": { + "PURL": "pkg:npm/js-tokens@4.0.0" + }, "Version": "4.0.0", "Indirect": true, "Layer": {}, @@ -66,6 +75,9 @@ { "ID": "loose-envify@1.4.0", "Name": "loose-envify", + "Identifier": { + "PURL": "pkg:npm/loose-envify@1.4.0" + }, "Version": "1.4.0", "Indirect": true, "DependsOn": [ @@ -82,6 +94,9 @@ { "ID": "object-assign@4.1.1", "Name": "object-assign", + "Identifier": { + "PURL": "pkg:npm/object-assign@4.1.1" + }, "Version": "4.1.1", "Indirect": true, "Layer": {}, @@ -95,6 +110,9 @@ { "ID": "promise@8.0.3", "Name": "promise", + "Identifier": { + "PURL": "pkg:npm/promise@8.0.3" + }, "Version": "8.0.3", "Licenses": [ "MIT" @@ -114,6 +132,9 @@ { "ID": "prop-types@15.7.2", "Name": "prop-types", + "Identifier": { + "PURL": "pkg:npm/prop-types@15.7.2" + }, "Version": "15.7.2", "Indirect": true, "DependsOn": [ @@ -132,6 +153,9 @@ { "ID": "react@16.8.6", "Name": "react", + "Identifier": { + "PURL": "pkg:npm/react@16.8.6" + }, "Version": "16.8.6", "Licenses": [ "MIT" @@ -154,6 +178,9 @@ { "ID": "react-is@16.8.6", "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@16.8.6" + }, "Version": "16.8.6", "Licenses": [ "MIT" @@ -170,6 +197,9 @@ { "ID": "redux@4.0.1", "Name": "redux", + "Identifier": { + "PURL": "pkg:npm/redux@4.0.1" + }, "Version": "4.0.1", "Licenses": [ "MIT" @@ -190,6 +220,9 @@ { "ID": "scheduler@0.13.6", "Name": "scheduler", + "Identifier": { + "PURL": "pkg:npm/scheduler@0.13.6" + }, "Version": "0.13.6", "Indirect": true, "DependsOn": [ @@ -207,6 +240,9 @@ { "ID": "symbol-observable@1.2.0", "Name": "symbol-observable", + "Identifier": { + "PURL": "pkg:npm/symbol-observable@1.2.0" + }, "Version": "1.2.0", "Indirect": true, "Layer": {}, @@ -220,6 +256,9 @@ { "ID": "z-lock@1.0.0", "Name": "z-lock", + "Identifier": { + "PURL": "pkg:npm/z-lock@1.0.0" + }, "Version": "1.0.0", "Dev": true, "Licenses": [ @@ -240,6 +279,9 @@ "VulnerabilityID": "CVE-2019-11358", "PkgID": "jquery@3.3.9", "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "InstalledVersion": "3.3.9", "FixedVersion": "3.4.0", "Status": "fixed", diff --git a/integration/testdata/npm.json.golden b/integration/testdata/npm.json.golden index ec19f9d5975a..9bdb9ae37649 100644 --- a/integration/testdata/npm.json.golden +++ b/integration/testdata/npm.json.golden @@ -24,6 +24,9 @@ { "ID": "asap@2.0.6", "Name": "asap", + "Identifier": { + "PURL": "pkg:npm/asap@2.0.6" + }, "Version": "2.0.6", "Indirect": true, "Layer": {}, @@ -37,6 +40,9 @@ { "ID": "jquery@3.3.9", "Name": "jquery", + "Identifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "Version": "3.3.9", "Licenses": [ "MIT" @@ -53,6 +59,9 @@ { "ID": "js-tokens@4.0.0", "Name": "js-tokens", + "Identifier": { + "PURL": "pkg:npm/js-tokens@4.0.0" + }, "Version": "4.0.0", "Indirect": true, "Layer": {}, @@ -66,6 +75,9 @@ { "ID": "loose-envify@1.4.0", "Name": "loose-envify", + "Identifier": { + "PURL": "pkg:npm/loose-envify@1.4.0" + }, "Version": "1.4.0", "Indirect": true, "DependsOn": [ @@ -82,6 +94,9 @@ { "ID": "object-assign@4.1.1", "Name": "object-assign", + "Identifier": { + "PURL": "pkg:npm/object-assign@4.1.1" + }, "Version": "4.1.1", "Indirect": true, "Layer": {}, @@ -95,6 +110,9 @@ { "ID": "promise@8.0.3", "Name": "promise", + "Identifier": { + "PURL": "pkg:npm/promise@8.0.3" + }, "Version": "8.0.3", "Licenses": [ "MIT" @@ -114,6 +132,9 @@ { "ID": "prop-types@15.7.2", "Name": "prop-types", + "Identifier": { + "PURL": "pkg:npm/prop-types@15.7.2" + }, "Version": "15.7.2", "Indirect": true, "DependsOn": [ @@ -132,6 +153,9 @@ { "ID": "react@16.8.6", "Name": "react", + "Identifier": { + "PURL": "pkg:npm/react@16.8.6" + }, "Version": "16.8.6", "Licenses": [ "MIT" @@ -154,6 +178,9 @@ { "ID": "react-is@16.8.6", "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@16.8.6" + }, "Version": "16.8.6", "Licenses": [ "MIT" @@ -170,6 +197,9 @@ { "ID": "redux@4.0.1", "Name": "redux", + "Identifier": { + "PURL": "pkg:npm/redux@4.0.1" + }, "Version": "4.0.1", "Licenses": [ "MIT" @@ -190,6 +220,9 @@ { "ID": "scheduler@0.13.6", "Name": "scheduler", + "Identifier": { + "PURL": "pkg:npm/scheduler@0.13.6" + }, "Version": "0.13.6", "Indirect": true, "DependsOn": [ @@ -207,6 +240,9 @@ { "ID": "symbol-observable@1.2.0", "Name": "symbol-observable", + "Identifier": { + "PURL": "pkg:npm/symbol-observable@1.2.0" + }, "Version": "1.2.0", "Indirect": true, "Layer": {}, @@ -223,6 +259,9 @@ "VulnerabilityID": "CVE-2019-11358", "PkgID": "jquery@3.3.9", "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "InstalledVersion": "3.3.9", "FixedVersion": "3.4.0", "Status": "fixed", diff --git a/integration/testdata/nuget.json.golden b/integration/testdata/nuget.json.golden index 5027f75894b4..064fb1e32d2f 100644 --- a/integration/testdata/nuget.json.golden +++ b/integration/testdata/nuget.json.golden @@ -24,6 +24,9 @@ { "ID": "Newtonsoft.Json@12.0.3", "Name": "Newtonsoft.Json", + "Identifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@12.0.3" + }, "Version": "12.0.3", "Layer": {}, "Locations": [ @@ -36,6 +39,9 @@ { "ID": "NuGet.Frameworks@5.7.0", "Name": "NuGet.Frameworks", + "Identifier": { + "PURL": "pkg:nuget/NuGet.Frameworks@5.7.0" + }, "Version": "5.7.0", "DependsOn": [ "Newtonsoft.Json@12.0.3" @@ -54,6 +60,9 @@ "VulnerabilityID": "GHSA-5crp-9r3c-p9vr", "PkgID": "Newtonsoft.Json@12.0.3", "PkgName": "Newtonsoft.Json", + "PkgIdentifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@12.0.3" + }, "InstalledVersion": "12.0.3", "FixedVersion": "13.0.1", "Status": "fixed", diff --git a/integration/testdata/opensuse-leap-151.json.golden b/integration/testdata/opensuse-leap-151.json.golden index ed0c29a6d890..9ca650d3dbb3 100644 --- a/integration/testdata/opensuse-leap-151.json.golden +++ b/integration/testdata/opensuse-leap-151.json.golden @@ -65,6 +65,9 @@ "VulnerabilityID": "openSUSE-SU-2020:0062-1", "PkgID": "libopenssl1_1@1.1.0i-lp151.8.3.1.x86_64", "PkgName": "libopenssl1_1", + "PkgIdentifier": { + "PURL": "pkg:rpm/opensuse.leap/libopenssl1_1@1.1.0i-lp151.8.3.1?arch=x86_64\u0026distro=opensuse.leap-15.1" + }, "InstalledVersion": "1.1.0i-lp151.8.3.1", "FixedVersion": "1.1.0i-lp151.8.6.1", "Status": "fixed", @@ -94,6 +97,9 @@ "VulnerabilityID": "openSUSE-SU-2020:0062-1", "PkgID": "openssl-1_1@1.1.0i-lp151.8.3.1.x86_64", "PkgName": "openssl-1_1", + "PkgIdentifier": { + "PURL": "pkg:rpm/opensuse.leap/openssl-1_1@1.1.0i-lp151.8.3.1?arch=x86_64\u0026distro=opensuse.leap-15.1" + }, "InstalledVersion": "1.1.0i-lp151.8.3.1", "FixedVersion": "1.1.0i-lp151.8.6.1", "Status": "fixed", diff --git a/integration/testdata/oraclelinux-8.json.golden b/integration/testdata/oraclelinux-8.json.golden index b00634c1079f..6629e7fe0e55 100644 --- a/integration/testdata/oraclelinux-8.json.golden +++ b/integration/testdata/oraclelinux-8.json.golden @@ -66,6 +66,9 @@ "VulnerabilityID": "CVE-2019-3823", "PkgID": "curl@7.61.1-8.el8.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/oracle/curl@7.61.1-8.el8?arch=x86_64\u0026distro=oracle-8.0" + }, "InstalledVersion": "7.61.1-8.el8", "FixedVersion": "7.61.1-11.el8", "Status": "fixed", @@ -133,6 +136,9 @@ "VulnerabilityID": "CVE-2019-5436", "PkgID": "curl@7.61.1-8.el8.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/oracle/curl@7.61.1-8.el8?arch=x86_64\u0026distro=oracle-8.0" + }, "InstalledVersion": "7.61.1-8.el8", "FixedVersion": "7.61.1-12.el8", "Status": "fixed", diff --git a/integration/testdata/packagesprops.json.golden b/integration/testdata/packagesprops.json.golden index 77a6cb03c51e..5cce23a7c754 100644 --- a/integration/testdata/packagesprops.json.golden +++ b/integration/testdata/packagesprops.json.golden @@ -24,6 +24,9 @@ { "ID": "Newtonsoft.Json@9.0.1", "Name": "Newtonsoft.Json", + "Identifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@9.0.1" + }, "Version": "9.0.1", "Layer": {} } @@ -33,6 +36,9 @@ "VulnerabilityID": "GHSA-5crp-9r3c-p9vr", "PkgID": "Newtonsoft.Json@9.0.1", "PkgName": "Newtonsoft.Json", + "PkgIdentifier": { + "PURL": "pkg:nuget/Newtonsoft.Json@9.0.1" + }, "InstalledVersion": "9.0.1", "FixedVersion": "13.0.1", "Status": "fixed", diff --git a/integration/testdata/photon-30.json.golden b/integration/testdata/photon-30.json.golden index 5a97889fd3d6..4e4c8d793faa 100644 --- a/integration/testdata/photon-30.json.golden +++ b/integration/testdata/photon-30.json.golden @@ -67,6 +67,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@4.4.18-1.ph3.x86_64", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:rpm/photon/bash@4.4.18-1.ph3?arch=x86_64\u0026distro=photon-3.0" + }, "InstalledVersion": "4.4.18-1.ph3", "FixedVersion": "4.4.18-2.ph3", "Status": "fixed", @@ -127,6 +130,9 @@ "VulnerabilityID": "CVE-2019-5481", "PkgID": "curl@7.61.1-4.ph3.x86_64", "PkgName": "curl", + "PkgIdentifier": { + "PURL": "pkg:rpm/photon/curl@7.61.1-4.ph3?arch=x86_64\u0026distro=photon-3.0" + }, "InstalledVersion": "7.61.1-4.ph3", "FixedVersion": "7.61.1-5.ph3", "Status": "fixed", @@ -195,6 +201,9 @@ "VulnerabilityID": "CVE-2019-5481", "PkgID": "curl-libs@7.61.1-4.ph3.x86_64", "PkgName": "curl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/photon/curl-libs@7.61.1-4.ph3?arch=x86_64\u0026distro=photon-3.0" + }, "InstalledVersion": "7.61.1-4.ph3", "FixedVersion": "7.61.1-5.ph3", "Status": "fixed", diff --git a/integration/testdata/pip.json.golden b/integration/testdata/pip.json.golden index 60590d12ea05..29873d943d55 100644 --- a/integration/testdata/pip.json.golden +++ b/integration/testdata/pip.json.golden @@ -23,36 +23,57 @@ "Packages": [ { "Name": "Flask", + "Identifier": { + "PURL": "pkg:pypi/flask@2.0.0" + }, "Version": "2.0.0", "Layer": {} }, { "Name": "Jinja2", + "Identifier": { + "PURL": "pkg:pypi/jinja2@3.0.0" + }, "Version": "3.0.0", "Layer": {} }, { "Name": "Werkzeug", + "Identifier": { + "PURL": "pkg:pypi/werkzeug@0.11" + }, "Version": "0.11", "Layer": {} }, { "Name": "click", + "Identifier": { + "PURL": "pkg:pypi/click@8.0.0" + }, "Version": "8.0.0", "Layer": {} }, { "Name": "itsdangerous", + "Identifier": { + "PURL": "pkg:pypi/itsdangerous@2.0.0" + }, "Version": "2.0.0", "Layer": {} }, { "Name": "oauth2-client", + "Identifier": { + "PURL": "pkg:pypi/oauth2-client@4.0.0" + }, "Version": "4.0.0", "Layer": {} }, { "Name": "python-gitlab", + "Identifier": { + "PURL": "pkg:pypi/python-gitlab@2.0.0" + }, "Version": "2.0.0", "Layer": {} } @@ -61,6 +82,9 @@ { "VulnerabilityID": "CVE-2019-14806", "PkgName": "Werkzeug", + "PkgIdentifier": { + "PURL": "pkg:pypi/werkzeug@0.11" + }, "InstalledVersion": "0.11", "FixedVersion": "0.15.3", "Status": "fixed", @@ -114,6 +138,9 @@ { "VulnerabilityID": "CVE-2020-28724", "PkgName": "Werkzeug", + "PkgIdentifier": { + "PURL": "pkg:pypi/werkzeug@0.11" + }, "InstalledVersion": "0.11", "FixedVersion": "0.11.6", "Status": "fixed", diff --git a/integration/testdata/pipenv.json.golden b/integration/testdata/pipenv.json.golden index f77722278843..e5076aa4571b 100644 --- a/integration/testdata/pipenv.json.golden +++ b/integration/testdata/pipenv.json.golden @@ -23,6 +23,9 @@ "Packages": [ { "Name": "werkzeug", + "Identifier": { + "PURL": "pkg:pypi/werkzeug@0.11.1" + }, "Version": "0.11.1", "Layer": {}, "Locations": [ @@ -37,6 +40,9 @@ { "VulnerabilityID": "CVE-2019-14806", "PkgName": "werkzeug", + "PkgIdentifier": { + "PURL": "pkg:pypi/werkzeug@0.11.1" + }, "InstalledVersion": "0.11.1", "FixedVersion": "0.15.3", "Status": "fixed", @@ -90,6 +96,9 @@ { "VulnerabilityID": "CVE-2020-28724", "PkgName": "werkzeug", + "PkgIdentifier": { + "PURL": "pkg:pypi/werkzeug@0.11.1" + }, "InstalledVersion": "0.11.1", "FixedVersion": "0.11.6", "Status": "fixed", diff --git a/integration/testdata/pnpm.json.golden b/integration/testdata/pnpm.json.golden index 2f69244be160..305552bf1f2a 100644 --- a/integration/testdata/pnpm.json.golden +++ b/integration/testdata/pnpm.json.golden @@ -25,6 +25,9 @@ "VulnerabilityID": "CVE-2019-11358", "PkgID": "jquery@3.3.9", "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "InstalledVersion": "3.3.9", "FixedVersion": "3.4.0", "Status": "fixed", @@ -154,6 +157,9 @@ "VulnerabilityID": "CVE-2019-10744", "PkgID": "lodash@4.17.4", "PkgName": "lodash", + "PkgIdentifier": { + "PURL": "pkg:npm/lodash@4.17.4" + }, "InstalledVersion": "4.17.4", "FixedVersion": "4.17.12", "Status": "fixed", diff --git a/integration/testdata/poetry.json.golden b/integration/testdata/poetry.json.golden index 26f4085bf95b..394977d3ea02 100644 --- a/integration/testdata/poetry.json.golden +++ b/integration/testdata/poetry.json.golden @@ -24,6 +24,9 @@ { "ID": "click@8.1.3", "Name": "click", + "Identifier": { + "PURL": "pkg:pypi/click@8.1.3" + }, "Version": "8.1.3", "DependsOn": [ "colorama@0.4.6" @@ -33,6 +36,9 @@ { "ID": "colorama@0.4.6", "Name": "colorama", + "Identifier": { + "PURL": "pkg:pypi/colorama@0.4.6" + }, "Version": "0.4.6", "Indirect": true, "Layer": {} @@ -40,6 +46,9 @@ { "ID": "werkzeug@0.14", "Name": "werkzeug", + "Identifier": { + "PURL": "pkg:pypi/werkzeug@0.14" + }, "Version": "0.14", "Layer": {} } @@ -49,6 +58,9 @@ "VulnerabilityID": "CVE-2019-14806", "PkgID": "werkzeug@0.14", "PkgName": "werkzeug", + "PkgIdentifier": { + "PURL": "pkg:pypi/werkzeug@0.14" + }, "InstalledVersion": "0.14", "FixedVersion": "0.15.3", "Status": "fixed", diff --git a/integration/testdata/pom-cyclonedx.json.golden b/integration/testdata/pom-cyclonedx.json.golden index b5e7f17e14f3..ac245de144ce 100644 --- a/integration/testdata/pom-cyclonedx.json.golden +++ b/integration/testdata/pom-cyclonedx.json.golden @@ -103,35 +103,35 @@ ], "vulnerabilities": [ { - "id": "CVE-2021-20190", + "id": "CVE-2020-9548", "source": { - "name": "glad", - "url": "https://gitlab.com/gitlab-org/advisories-community" + "name": "ghsa", + "url": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Amaven" }, "ratings": [ { "source": { "name": "ghsa" }, - "severity": "high" + "severity": "critical" }, { "source": { "name": "nvd" }, - "score": 8.3, - "severity": "high", + "score": 6.8, + "severity": "medium", "method": "CVSSv2", - "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:C" + "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P" }, { "source": { "name": "nvd" }, - "score": 8.1, - "severity": "high", + "score": 9.8, + "severity": "critical", "method": "CVSSv31", - "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H" + "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, { "source": { @@ -146,42 +146,72 @@ "cwes": [ 502 ], - "description": "A flaw was found in jackson-databind before 2.9.10.7. FasterXML mishandles the interaction between serialization gadgets and typing. The highest threat from this vulnerability is to data confidentiality and integrity as well as system availability.", - "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.9.10.7", + "description": "FasterXML jackson-databind 2.x before 2.9.10.4 mishandles the interaction between serialization gadgets and typing, related to br.com.anteros.dbcp.AnterosDBCPConfig (aka anteros-core).", + "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.9.10.4", "advisories": [ { - "url": "https://avd.aquasec.com/nvd/cve-2021-20190" + "url": "https://avd.aquasec.com/nvd/cve-2020-9548" }, { - "url": "https://access.redhat.com/security/cve/CVE-2021-20190" + "url": "https://access.redhat.com/security/cve/CVE-2020-9548" }, { - "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1916633" + "url": "https://github.com/FasterXML/jackson-databind/issues/2634" }, { - "url": "https://github.com/FasterXML/jackson-databind/commit/7dbf51bf78d157098074a20bd9da39bd48c18e4a" + "url": "https://github.com/advisories/GHSA-p43x-xfjf-5jhr" }, { - "url": "https://github.com/FasterXML/jackson-databind/issues/2854" + "url": "https://lists.apache.org/thread.html/r35d30db00440ef63b791c4b7f7acb036e14d4a23afa2a249cb66c0fd@%3Cissues.zookeeper.apache.org%3E" }, { - "url": "https://github.com/advisories/GHSA-5949-rw7g-wx7w" + "url": "https://lists.apache.org/thread.html/r9464a40d25c3ba1a55622db72f113eb494a889656962d098c70c5bb1@%3Cdev.zookeeper.apache.org%3E" }, { - "url": "https://lists.apache.org/thread.html/r380e9257bacb8551ee6fcf2c59890ae9477b2c78e553fa9ea08e9d9a@%3Ccommits.nifi.apache.org%3E" + "url": "https://lists.apache.org/thread.html/r98c9b6e4c9e17792e2cd1ec3e4aa20b61a791939046d3f10888176bb@%3Cissues.zookeeper.apache.org%3E" }, { - "url": "https://lists.debian.org/debian-lts-announce/2021/04/msg00025.html" + "url": "https://lists.apache.org/thread.html/rb6fecb5e96a6d61e175ff49f33f2713798dd05cf03067c169d195596@%3Cissues.zookeeper.apache.org%3E" }, { - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-20190" + "url": "https://lists.apache.org/thread.html/rd5a4457be4623038c3989294429bc063eec433a2e55995d81591e2ca@%3Cissues.zookeeper.apache.org%3E" }, { - "url": "https://security.netapp.com/advisory/ntap-20210219-0008/" + "url": "https://lists.apache.org/thread.html/rdd49ab9565bec436a896bc00c4b9fc9dce1598e106c318524fbdfec6@%3Cissues.zookeeper.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/rdd4df698d5d8e635144d2994922bf0842e933809eae259521f3b5097@%3Cissues.zookeeper.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/rf1bbc0ea4a9f014cf94df9a12a6477d24a27f52741dbc87f2fd52ff2@%3Cissues.geode.apache.org%3E" + }, + { + "url": "https://lists.debian.org/debian-lts-announce/2020/03/msg00008.html" + }, + { + "url": "https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062" + }, + { + "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-9548" + }, + { + "url": "https://security.netapp.com/advisory/ntap-20200904-0006/" + }, + { + "url": "https://www.oracle.com/security-alerts/cpujan2021.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpujul2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuoct2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuoct2021.html" } ], - "published": "2021-01-19T17:15:00+00:00", - "updated": "2021-07-20T23:15:00+00:00", + "published": "2020-03-02T04:15:00+00:00", + "updated": "2021-12-02T21:23:00+00:00", "affects": [ { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1", @@ -195,35 +225,35 @@ ] }, { - "id": "CVE-2020-9548", + "id": "CVE-2021-20190", "source": { - "name": "ghsa", - "url": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Amaven" + "name": "glad", + "url": "https://gitlab.com/gitlab-org/advisories-community" }, "ratings": [ { "source": { "name": "ghsa" }, - "severity": "critical" + "severity": "high" }, { "source": { "name": "nvd" }, - "score": 6.8, - "severity": "medium", + "score": 8.3, + "severity": "high", "method": "CVSSv2", - "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P" + "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:C" }, { "source": { "name": "nvd" }, - "score": 9.8, - "severity": "critical", + "score": 8.1, + "severity": "high", "method": "CVSSv31", - "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H" }, { "source": { @@ -238,72 +268,42 @@ "cwes": [ 502 ], - "description": "FasterXML jackson-databind 2.x before 2.9.10.4 mishandles the interaction between serialization gadgets and typing, related to br.com.anteros.dbcp.AnterosDBCPConfig (aka anteros-core).", - "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.9.10.4", + "description": "A flaw was found in jackson-databind before 2.9.10.7. FasterXML mishandles the interaction between serialization gadgets and typing. The highest threat from this vulnerability is to data confidentiality and integrity as well as system availability.", + "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.9.10.7", "advisories": [ { - "url": "https://avd.aquasec.com/nvd/cve-2020-9548" - }, - { - "url": "https://access.redhat.com/security/cve/CVE-2020-9548" - }, - { - "url": "https://github.com/FasterXML/jackson-databind/issues/2634" - }, - { - "url": "https://github.com/advisories/GHSA-p43x-xfjf-5jhr" - }, - { - "url": "https://lists.apache.org/thread.html/r35d30db00440ef63b791c4b7f7acb036e14d4a23afa2a249cb66c0fd@%3Cissues.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/r9464a40d25c3ba1a55622db72f113eb494a889656962d098c70c5bb1@%3Cdev.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/r98c9b6e4c9e17792e2cd1ec3e4aa20b61a791939046d3f10888176bb@%3Cissues.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/rb6fecb5e96a6d61e175ff49f33f2713798dd05cf03067c169d195596@%3Cissues.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/rd5a4457be4623038c3989294429bc063eec433a2e55995d81591e2ca@%3Cissues.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/rdd49ab9565bec436a896bc00c4b9fc9dce1598e106c318524fbdfec6@%3Cissues.zookeeper.apache.org%3E" - }, - { - "url": "https://lists.apache.org/thread.html/rdd4df698d5d8e635144d2994922bf0842e933809eae259521f3b5097@%3Cissues.zookeeper.apache.org%3E" + "url": "https://avd.aquasec.com/nvd/cve-2021-20190" }, { - "url": "https://lists.apache.org/thread.html/rf1bbc0ea4a9f014cf94df9a12a6477d24a27f52741dbc87f2fd52ff2@%3Cissues.geode.apache.org%3E" + "url": "https://access.redhat.com/security/cve/CVE-2021-20190" }, { - "url": "https://lists.debian.org/debian-lts-announce/2020/03/msg00008.html" + "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1916633" }, { - "url": "https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062" + "url": "https://github.com/FasterXML/jackson-databind/commit/7dbf51bf78d157098074a20bd9da39bd48c18e4a" }, { - "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-9548" + "url": "https://github.com/FasterXML/jackson-databind/issues/2854" }, { - "url": "https://security.netapp.com/advisory/ntap-20200904-0006/" + "url": "https://github.com/advisories/GHSA-5949-rw7g-wx7w" }, { - "url": "https://www.oracle.com/security-alerts/cpujan2021.html" + "url": "https://lists.apache.org/thread.html/r380e9257bacb8551ee6fcf2c59890ae9477b2c78e553fa9ea08e9d9a@%3Ccommits.nifi.apache.org%3E" }, { - "url": "https://www.oracle.com/security-alerts/cpujul2020.html" + "url": "https://lists.debian.org/debian-lts-announce/2021/04/msg00025.html" }, { - "url": "https://www.oracle.com/security-alerts/cpuoct2020.html" + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-20190" }, { - "url": "https://www.oracle.com/security-alerts/cpuoct2021.html" + "url": "https://security.netapp.com/advisory/ntap-20210219-0008/" } ], - "published": "2020-03-02T04:15:00+00:00", - "updated": "2021-12-02T21:23:00+00:00", + "published": "2021-01-19T17:15:00+00:00", + "updated": "2021-07-20T23:15:00+00:00", "affects": [ { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1", diff --git a/integration/testdata/pom.json.golden b/integration/testdata/pom.json.golden index bf8d69f4125c..244817f1e4c7 100644 --- a/integration/testdata/pom.json.golden +++ b/integration/testdata/pom.json.golden @@ -25,6 +25,9 @@ "VulnerabilityID": "CVE-2020-9548", "PkgID": "com.fasterxml.jackson.core:jackson-databind:2.9.1", "PkgName": "com.fasterxml.jackson.core:jackson-databind", + "PkgIdentifier": { + "PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1" + }, "InstalledVersion": "2.9.1", "FixedVersion": "2.9.10.4", "Status": "fixed", @@ -87,6 +90,9 @@ "VulnerabilityID": "CVE-2021-20190", "PkgID": "com.fasterxml.jackson.core:jackson-databind:2.9.1", "PkgName": "com.fasterxml.jackson.core:jackson-databind", + "PkgIdentifier": { + "PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1" + }, "InstalledVersion": "2.9.1", "FixedVersion": "2.9.10.7", "Status": "fixed", diff --git a/integration/testdata/pubspec.lock.json.golden b/integration/testdata/pubspec.lock.json.golden index a7e76e3153b8..7a101cd02eca 100644 --- a/integration/testdata/pubspec.lock.json.golden +++ b/integration/testdata/pubspec.lock.json.golden @@ -24,12 +24,18 @@ { "ID": "http@0.13.2", "Name": "http", + "Identifier": { + "PURL": "pkg:pub/http@0.13.2" + }, "Version": "0.13.2", "Layer": {} }, { "ID": "shelf@1.3.1", "Name": "shelf", + "Identifier": { + "PURL": "pkg:pub/shelf@1.3.1" + }, "Version": "1.3.1", "Indirect": true, "Layer": {} @@ -40,6 +46,9 @@ "VulnerabilityID": "CVE-2020-35669", "PkgID": "http@0.13.2", "PkgName": "http", + "PkgIdentifier": { + "PURL": "pkg:pub/http@0.13.2" + }, "InstalledVersion": "0.13.2", "FixedVersion": "0.13.3", "Status": "fixed", diff --git a/integration/testdata/rockylinux-8.json.golden b/integration/testdata/rockylinux-8.json.golden index c47d69455875..6d8b3b7a29a8 100644 --- a/integration/testdata/rockylinux-8.json.golden +++ b/integration/testdata/rockylinux-8.json.golden @@ -56,6 +56,9 @@ "VulnerabilityID": "CVE-2021-3712", "PkgID": "openssl-libs@1.1.1k-4.el8.x86_64", "PkgName": "openssl-libs", + "PkgIdentifier": { + "PURL": "pkg:rpm/rocky/openssl-libs@1.1.1k-4.el8?arch=x86_64\u0026distro=rocky-8.5\u0026epoch=1" + }, "InstalledVersion": "1:1.1.1k-4.el8", "FixedVersion": "1:1.1.1k-5.el8_5", "Status": "fixed", diff --git a/integration/testdata/spring4shell-jre11.json.golden b/integration/testdata/spring4shell-jre11.json.golden index b6ad22e931dd..7db6bae72bfa 100644 --- a/integration/testdata/spring4shell-jre11.json.golden +++ b/integration/testdata/spring4shell-jre11.json.golden @@ -198,6 +198,9 @@ "VulnerabilityID": "CVE-2022-22965", "PkgName": "org.springframework:spring-beans", "PkgPath": "usr/local/tomcat/webapps/helloworld.war/WEB-INF/lib/spring-beans-5.3.15.jar", + "PkgIdentifier": { + "PURL": "pkg:maven/org.springframework/spring-beans@5.3.15" + }, "InstalledVersion": "5.3.15", "FixedVersion": "5.3.18", "Status": "fixed", diff --git a/integration/testdata/spring4shell-jre8.json.golden b/integration/testdata/spring4shell-jre8.json.golden index f894c07d659c..e1a0e9ee0457 100644 --- a/integration/testdata/spring4shell-jre8.json.golden +++ b/integration/testdata/spring4shell-jre8.json.golden @@ -198,6 +198,9 @@ "VulnerabilityID": "CVE-2022-22965", "PkgName": "org.springframework:spring-beans", "PkgPath": "usr/local/tomcat/webapps/helloworld.war/WEB-INF/lib/spring-beans-5.3.15.jar", + "PkgIdentifier": { + "PURL": "pkg:maven/org.springframework/spring-beans@5.3.15" + }, "InstalledVersion": "5.3.15", "FixedVersion": "5.3.18", "Status": "fixed", diff --git a/integration/testdata/swift.json.golden b/integration/testdata/swift.json.golden index 47d1d2850470..0a9d1ebffb21 100644 --- a/integration/testdata/swift.json.golden +++ b/integration/testdata/swift.json.golden @@ -24,6 +24,9 @@ { "ID": "github.com/apple/swift-atomics@1.1.0", "Name": "github.com/apple/swift-atomics", + "Identifier": { + "PURL": "pkg:swift/github.com/apple/swift-atomics@1.1.0" + }, "Version": "1.1.0", "Layer": {}, "Locations": [ @@ -36,6 +39,9 @@ { "ID": "github.com/apple/swift-nio@2.41.0", "Name": "github.com/apple/swift-nio", + "Identifier": { + "PURL": "pkg:swift/github.com/apple/swift-nio@2.41.0" + }, "Version": "2.41.0", "Layer": {}, "Locations": [ @@ -51,6 +57,9 @@ "VulnerabilityID": "CVE-2022-3215", "PkgID": "github.com/apple/swift-nio@2.41.0", "PkgName": "github.com/apple/swift-nio", + "PkgIdentifier": { + "PURL": "pkg:swift/github.com/apple/swift-nio@2.41.0" + }, "InstalledVersion": "2.41.0", "FixedVersion": "2.29.1, 2.39.1, 2.42.0", "Status": "fixed", diff --git a/integration/testdata/test-repo.json.golden b/integration/testdata/test-repo.json.golden index b98f0e94f0d1..e1ebd91418f7 100644 --- a/integration/testdata/test-repo.json.golden +++ b/integration/testdata/test-repo.json.golden @@ -25,6 +25,9 @@ "VulnerabilityID": "CVE-2019-15542", "PkgID": "ammonia@1.9.0", "PkgName": "ammonia", + "PkgIdentifier": { + "PURL": "pkg:cargo/ammonia@1.9.0" + }, "InstalledVersion": "1.9.0", "FixedVersion": "\u003e= 2.1.0", "Status": "fixed", @@ -64,6 +67,9 @@ "VulnerabilityID": "CVE-2021-38193", "PkgID": "ammonia@1.9.0", "PkgName": "ammonia", + "PkgIdentifier": { + "PURL": "pkg:cargo/ammonia@1.9.0" + }, "InstalledVersion": "1.9.0", "FixedVersion": "\u003e= 3.1.0, \u003e= 2.1.3, \u003c 3.0.0", "Status": "fixed", diff --git a/integration/testdata/ubi-7.json.golden b/integration/testdata/ubi-7.json.golden index 2b382d42ed04..36062495c5a9 100644 --- a/integration/testdata/ubi-7.json.golden +++ b/integration/testdata/ubi-7.json.golden @@ -80,6 +80,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@4.2.46-33.el7.x86_64", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:rpm/redhat/bash@4.2.46-33.el7?arch=x86_64\u0026distro=redhat-7.7" + }, "InstalledVersion": "4.2.46-33.el7", "Status": "will_not_fix", "Layer": { diff --git a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden index 8020b35f5982..fbc7dafbdbb7 100644 --- a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden +++ b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden @@ -76,6 +76,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "e2fsprogs@1.44.1-1ubuntu1.1", "PkgName": "e2fsprogs", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/e2fsprogs@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -143,6 +146,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libcom-err2@1.44.1-1ubuntu1.1", "PkgName": "libcom-err2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libcom-err2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -210,6 +216,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libext2fs2@1.44.1-1ubuntu1.1", "PkgName": "libext2fs2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libext2fs2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -277,6 +286,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libss2@1.44.1-1ubuntu1.1", "PkgName": "libss2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libss2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", diff --git a/integration/testdata/ubuntu-1804.json.golden b/integration/testdata/ubuntu-1804.json.golden index bbca0359b3f5..93abad738729 100644 --- a/integration/testdata/ubuntu-1804.json.golden +++ b/integration/testdata/ubuntu-1804.json.golden @@ -76,6 +76,9 @@ "VulnerabilityID": "CVE-2019-18276", "PkgID": "bash@4.4.18-2ubuntu1.2", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/bash@4.4.18-2ubuntu1.2?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "4.4.18-2ubuntu1.2", "Status": "affected", "Layer": { @@ -135,6 +138,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "e2fsprogs@1.44.1-1ubuntu1.1", "PkgName": "e2fsprogs", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/e2fsprogs@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -202,6 +208,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libcom-err2@1.44.1-1ubuntu1.1", "PkgName": "libcom-err2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libcom-err2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -269,6 +278,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libext2fs2@1.44.1-1ubuntu1.1", "PkgName": "libext2fs2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libext2fs2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", @@ -336,6 +348,9 @@ "VulnerabilityID": "CVE-2019-5094", "PkgID": "libss2@1.44.1-1ubuntu1.1", "PkgName": "libss2", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/libss2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04" + }, "InstalledVersion": "1.44.1-1ubuntu1.1", "FixedVersion": "1.44.1-1ubuntu1.2", "Status": "fixed", diff --git a/integration/testdata/ubuntu-gp2-x86-vm.json.golden b/integration/testdata/ubuntu-gp2-x86-vm.json.golden index 485dc3712542..0c62f5aab4e2 100644 --- a/integration/testdata/ubuntu-gp2-x86-vm.json.golden +++ b/integration/testdata/ubuntu-gp2-x86-vm.json.golden @@ -29,6 +29,9 @@ "VulnerabilityID": "CVE-2022-3715", "PkgID": "bash@5.1-6ubuntu1", "PkgName": "bash", + "PkgIdentifier": { + "PURL": "pkg:deb/ubuntu/bash@5.1-6ubuntu1?arch=amd64\u0026distro=ubuntu-22.04" + }, "InstalledVersion": "5.1-6ubuntu1", "Status": "affected", "Layer": {}, diff --git a/integration/testdata/yarn.json.golden b/integration/testdata/yarn.json.golden index 3002b9f9b992..1e5cd3da24b3 100644 --- a/integration/testdata/yarn.json.golden +++ b/integration/testdata/yarn.json.golden @@ -24,6 +24,9 @@ { "ID": "jquery@3.2.1", "Name": "jquery", + "Identifier": { + "PURL": "pkg:npm/jquery@3.2.1" + }, "Version": "3.2.1", "Licenses": [ "MIT" @@ -42,6 +45,9 @@ "VulnerabilityID": "CVE-2019-11358", "PkgID": "jquery@3.2.1", "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.2.1" + }, "InstalledVersion": "3.2.1", "FixedVersion": "3.4.0", "Status": "fixed", diff --git a/pkg/detector/library/detect.go b/pkg/detector/library/detect.go index 121f33284e1a..14674be8d1a8 100644 --- a/pkg/detector/library/detect.go +++ b/pkg/detector/library/detect.go @@ -34,6 +34,7 @@ func detect(driver Driver, libs []ftypes.Package) ([]types.DetectedVulnerability vulns[i].Layer = lib.Layer vulns[i].PkgPath = lib.FilePath vulns[i].PkgRef = lib.Ref + vulns[i].PkgIdentifier = lib.Identifier } vulnerabilities = append(vulnerabilities, vulns...) } diff --git a/pkg/detector/ospkg/alma/alma.go b/pkg/detector/ospkg/alma/alma.go index 2c52fea3deb7..a3c3a546f8f4 100644 --- a/pkg/detector/ospkg/alma/alma.go +++ b/pkg/detector/ospkg/alma/alma.go @@ -81,7 +81,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa installed := utils.FormatVersion(pkg) installedVersion := version.NewVersion(installed) - for _, adv := range advisories { fixedVersion := version.NewVersion(adv.FixedVersion) if installedVersion.LessThan(fixedVersion) { @@ -92,6 +91,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa InstalledVersion: installed, FixedVersion: fixedVersion.String(), PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/alpine/alpine.go b/pkg/detector/ospkg/alpine/alpine.go index 45be59c1ea6a..aa50ef35ba1e 100644 --- a/pkg/detector/ospkg/alpine/alpine.go +++ b/pkg/detector/ospkg/alpine/alpine.go @@ -131,6 +131,7 @@ func (s *Scanner) Detect(osVer string, repo *ftypes.Repository, pkgs []ftypes.Pa FixedVersion: adv.FixedVersion, Layer: pkg.Layer, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, }) diff --git a/pkg/detector/ospkg/amazon/amazon.go b/pkg/detector/ospkg/amazon/amazon.go index 5d28dce0a17e..4be7ab8080ae 100644 --- a/pkg/detector/ospkg/amazon/amazon.go +++ b/pkg/detector/ospkg/amazon/amazon.go @@ -104,6 +104,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa InstalledVersion: installed, FixedVersion: adv.FixedVersion, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/chainguard/chainguard.go b/pkg/detector/ospkg/chainguard/chainguard.go index 9a6d5e752f4b..a818de11cbfe 100644 --- a/pkg/detector/ospkg/chainguard/chainguard.go +++ b/pkg/detector/ospkg/chainguard/chainguard.go @@ -82,6 +82,7 @@ func (s *Scanner) Detect(_ string, _ *ftypes.Repository, pkgs []ftypes.Package) FixedVersion: adv.FixedVersion, Layer: pkg.Layer, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, }) diff --git a/pkg/detector/ospkg/debian/debian.go b/pkg/detector/ospkg/debian/debian.go index 32526e9bbffe..90a91af42b27 100644 --- a/pkg/detector/ospkg/debian/debian.go +++ b/pkg/detector/ospkg/debian/debian.go @@ -104,6 +104,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa InstalledVersion: utils.FormatVersion(pkg), FixedVersion: adv.FixedVersion, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Status: adv.Status, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/mariner/mariner.go b/pkg/detector/ospkg/mariner/mariner.go index 6d88f3a3320e..0b780b9f2d71 100644 --- a/pkg/detector/ospkg/mariner/mariner.go +++ b/pkg/detector/ospkg/mariner/mariner.go @@ -50,6 +50,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, } diff --git a/pkg/detector/ospkg/oracle/oracle.go b/pkg/detector/ospkg/oracle/oracle.go index ccffc56eb1f5..0f07d9873526 100644 --- a/pkg/detector/ospkg/oracle/oracle.go +++ b/pkg/detector/ospkg/oracle/oracle.go @@ -87,6 +87,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/photon/photon.go b/pkg/detector/ospkg/photon/photon.go index df9822dd5b3e..ac7eb501f102 100644 --- a/pkg/detector/ospkg/photon/photon.go +++ b/pkg/detector/ospkg/photon/photon.go @@ -82,6 +82,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/redhat/redhat.go b/pkg/detector/ospkg/redhat/redhat.go index 8e419c93a45e..9420e9cdbb1c 100644 --- a/pkg/detector/ospkg/redhat/redhat.go +++ b/pkg/detector/ospkg/redhat/redhat.go @@ -158,6 +158,7 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Status: adv.Status, Layer: pkg.Layer, SeveritySource: vulnerability.RedHat, diff --git a/pkg/detector/ospkg/rocky/rocky.go b/pkg/detector/ospkg/rocky/rocky.go index 25efce4cb865..9a57cf7974cf 100644 --- a/pkg/detector/ospkg/rocky/rocky.go +++ b/pkg/detector/ospkg/rocky/rocky.go @@ -91,6 +91,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa InstalledVersion: installed, FixedVersion: fixedVersion.String(), PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/suse/suse.go b/pkg/detector/ospkg/suse/suse.go index c846867d73ca..267c8940ef0b 100644 --- a/pkg/detector/ospkg/suse/suse.go +++ b/pkg/detector/ospkg/suse/suse.go @@ -134,6 +134,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/ubuntu/ubuntu.go b/pkg/detector/ospkg/ubuntu/ubuntu.go index 836f26999077..d2f76a2e67d0 100644 --- a/pkg/detector/ospkg/ubuntu/ubuntu.go +++ b/pkg/detector/ospkg/ubuntu/ubuntu.go @@ -124,6 +124,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa InstalledVersion: utils.FormatVersion(pkg), FixedVersion: adv.FixedVersion, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/wolfi/wolfi.go b/pkg/detector/ospkg/wolfi/wolfi.go index 466ea20e5049..c7d4ca1a1c4f 100644 --- a/pkg/detector/ospkg/wolfi/wolfi.go +++ b/pkg/detector/ospkg/wolfi/wolfi.go @@ -82,6 +82,7 @@ func (s *Scanner) Detect(_ string, _ *ftypes.Repository, pkgs []ftypes.Package) FixedVersion: adv.FixedVersion, Layer: pkg.Layer, PkgRef: pkg.Ref, + PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, }) diff --git a/pkg/fanal/analyzer/imgconf/apk/apk.go b/pkg/fanal/analyzer/imgconf/apk/apk.go index 7d2a88e84bff..43f6cc278023 100644 --- a/pkg/fanal/analyzer/imgconf/apk/apk.go +++ b/pkg/fanal/analyzer/imgconf/apk/apk.go @@ -13,6 +13,7 @@ import ( "time" v1 "github.com/google/go-containerregistry/pkg/v1" + "golang.org/x/exp/maps" "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/fanal/analyzer" @@ -56,11 +57,11 @@ type archive struct { } type provide struct { - SO map[string]pkg // package which provides the shared object - Package map[string]pkg // package which provides the package + SO map[string]apk // package which provides the shared object + Package map[string]apk // package which provides the package } -type pkg struct { +type apk struct { Package string Versions version } @@ -135,11 +136,8 @@ func (a alpineCmdAnalyzer) parseConfig(apkIndexArchive *apkIndex, config *v1.Con uniqPkgs[result.Name] = result } } - for _, pkg := range uniqPkgs { - packages = append(packages, pkg) - } - return packages + return maps.Values(uniqPkgs) } func (a alpineCmdAnalyzer) parseCommand(command string, envs map[string]string) (pkgs []string) { diff --git a/pkg/fanal/analyzer/imgconf/apk/apk_test.go b/pkg/fanal/analyzer/imgconf/apk/apk_test.go index 1cb0e10064da..8f3856e2fde4 100644 --- a/pkg/fanal/analyzer/imgconf/apk/apk_test.go +++ b/pkg/fanal/analyzer/imgconf/apk/apk_test.go @@ -1070,11 +1070,11 @@ func TestAnalyze(t *testing.T) { args: args{ targetOS: types.OS{ Family: "alpine", - Name: "", + Name: "3.9.1", }, config: alpineConfig, }, - apkIndexArchivePath: testServer.URL + "%v", + apkIndexArchivePath: testServer.URL + "/%v", want: wantPkgs, }, } diff --git a/pkg/fanal/analyzer/language/analyze.go b/pkg/fanal/analyzer/language/analyze.go index 61d9492aa68c..8c0499b26ef6 100644 --- a/pkg/fanal/analyzer/language/analyze.go +++ b/pkg/fanal/analyzer/language/analyze.go @@ -116,7 +116,8 @@ func toApplication(fileType types.LangType, filePath, libFilePath string, r dio. if lib.FilePath != "" { libPath = lib.FilePath } - pkgs = append(pkgs, types.Package{ + + newPkg := types.Package{ ID: lib.ID, Name: lib.Name, Version: lib.Version, @@ -127,7 +128,8 @@ func toApplication(fileType types.LangType, filePath, libFilePath string, r dio. DependsOn: deps[lib.ID], Locations: locs, Digest: d, - }) + } + pkgs = append(pkgs, newPkg) } return &types.Application{ diff --git a/pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go b/pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go index 0a1ae4e10f54..4dc627823200 100644 --- a/pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go +++ b/pkg/fanal/analyzer/pkg/dpkg/dpkg_test.go @@ -623,8 +623,9 @@ func Test_dpkgAnalyzer_Analyze(t *testing.T) { Arch: "amd64", }, { - ID: "libgpg-error0@1.27-6", - Name: "libgpg-error0", + ID: "libgpg-error0@1.27-6", + Name: "libgpg-error0", + Version: "1.27", Release: "6", SrcName: "libgpg-error", diff --git a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go index aebb70928fb1..7e99cc601d61 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go @@ -3,14 +3,15 @@ package rpm import ( "context" "errors" + "os" + "strings" + "testing" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/fanal/types" rpmdb "github.com/knqyf263/go-rpmdb/pkg" "github.com/samber/lo" "github.com/stretchr/testify/require" - "os" - "strings" - "testing" "github.com/stretchr/testify/assert" ) diff --git a/pkg/fanal/analyzer/pkg/rpm/rpmqa.go b/pkg/fanal/analyzer/pkg/rpm/rpmqa.go index 4c96ab4fb9ef..4a312961c2c2 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpmqa.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpmqa.go @@ -68,7 +68,7 @@ func (a rpmqaPkgAnalyzer) parseRpmqaManifest(r io.ReadSeekerAt) ([]types.Package if err != nil { return nil, xerrors.Errorf("failed to split source rpm: %w", err) } - pkg := types.Package{ + pkgs = append(pkgs, types.Package{ Name: name, Version: ver, Release: rel, @@ -76,8 +76,7 @@ func (a rpmqaPkgAnalyzer) parseRpmqaManifest(r io.ReadSeekerAt) ([]types.Package SrcName: srcName, SrcVersion: srcVer, SrcRelease: srcRel, - } - pkgs = append(pkgs, pkg) + }) } return pkgs, nil } diff --git a/pkg/fanal/analyzer/sbom/sbom.go b/pkg/fanal/analyzer/sbom/sbom.go index 1f8b62af2fd6..51b5178c781c 100644 --- a/pkg/fanal/analyzer/sbom/sbom.go +++ b/pkg/fanal/analyzer/sbom/sbom.go @@ -86,7 +86,11 @@ func handleBitnamiImages(componentPath string, bom types.SBOM) { // e.g. modules/apm/elastic-apm-agent-1.36.0.jar // => opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar // If the file path is empty, the file path will be set to the component dir path. - bom.Applications[i].Libraries[j].FilePath = path.Join(componentPath, pkg.FilePath) + filePath := path.Join(componentPath, pkg.FilePath) + bom.Applications[i].Libraries[j].FilePath = filePath + if pkg.Identifier.PURL != nil && pkg.Identifier.PURL.FilePath != "" { + bom.Applications[i].Libraries[j].Identifier.PURL.FilePath = filePath + } } } } diff --git a/pkg/fanal/analyzer/sbom/sbom_test.go b/pkg/fanal/analyzer/sbom/sbom_test.go index fe00d31a6ae7..e475e1b363bb 100644 --- a/pkg/fanal/analyzer/sbom/sbom_test.go +++ b/pkg/fanal/analyzer/sbom/sbom_test.go @@ -2,6 +2,7 @@ package sbom import ( "context" + "github.com/package-url/packageurl-go" "os" "testing" @@ -34,24 +35,64 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", FilePath: "opt/bitnami/elasticsearch", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", + }, + }, + }, }, { Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", FilePath: "opt/bitnami/elasticsearch", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", + }, + }, + }, }, { Name: "co.elastic.apm:apm-agent-common", Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent-common@1.36.0", FilePath: "opt/bitnami/elasticsearch", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-common", + Version: "1.36.0", + }, + }, + }, }, { Name: "co.elastic.apm:apm-agent-core", Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent-core@1.36.0", FilePath: "opt/bitnami/elasticsearch", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-core", + Version: "1.36.0", + }, + }, + }, }, }, }, @@ -65,6 +106,21 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Ref: "pkg:bitnami/elasticsearch@8.9.1?arch=arm64", Arch: "arm64", Licenses: []string{"Elastic-2.0"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "elasticsearch", + Version: "8.9.1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "arm64", + }, + }, + }, + }, + }, }, }, }, @@ -86,12 +142,34 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Name: "co.elastic.apm:apm-agent", Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", + }, + FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", + }, + }, }, { FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", + }, + FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", + }, + }, }, }, }, @@ -114,24 +192,60 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "3.7.1", Ref: "pkg:bitnami/gdal@3.7.1", Licenses: []string{"MIT"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "gdal", + Version: "3.7.1", + }, + }, + }, }, { Name: "geos", Version: "3.8.3", Ref: "pkg:bitnami/geos@3.8.3", Licenses: []string{"LGPL-2.1-only"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "geos", + Version: "3.8.3", + }, + }, + }, }, { Name: "postgresql", Version: "15.3.0", Ref: "pkg:bitnami/postgresql@15.3.0", Licenses: []string{"PostgreSQL"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "postgresql", + Version: "15.3.0", + }, + }, + }, }, { Name: "proj", Version: "6.3.2", Ref: "pkg:bitnami/proj@6.3.2", Licenses: []string{"MIT"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "proj", + Version: "6.3.2", + }, + }, + }, }, }, }, diff --git a/pkg/fanal/applier/applier_test.go b/pkg/fanal/applier/applier_test.go index 315a042cb279..0994d46bfc39 100644 --- a/pkg/fanal/applier/applier_test.go +++ b/pkg/fanal/applier/applier_test.go @@ -1,6 +1,7 @@ package applier_test import ( + "github.com/package-url/packageurl-go" "sort" "testing" @@ -149,6 +150,22 @@ func TestApplier_ApplyLayers(t *testing.T) { Version: "2.24-11+deb9u4", SrcName: "glibc", SrcVersion: "2.24-11+deb9u4", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "libc6", + Version: "2.24-11+deb9u4", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-9.9", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", @@ -159,6 +176,22 @@ func TestApplier_ApplyLayers(t *testing.T) { Version: "2019a-0+deb9u1", SrcName: "tzdata", SrcVersion: "2019a-0+deb9u1", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "tzdata", + Version: "2019a-0+deb9u1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-9.9", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -177,6 +210,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", + }, + }, + }, }, { Name: "symfony/process", @@ -185,6 +228,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", + }, + }, + }, }, }, }, @@ -299,6 +352,22 @@ func TestApplier_ApplyLayers(t *testing.T) { { Name: "busybox", Version: "1.30.1-r3", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "busybox", + Version: "1.30.1-r3", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -307,6 +376,22 @@ func TestApplier_ApplyLayers(t *testing.T) { { Name: "libcrypto1.1", Version: "1.1.1d-r2", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "libcrypto1.1", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -315,6 +400,22 @@ func TestApplier_ApplyLayers(t *testing.T) { { Name: "libssl1.1", Version: "1.1.1d-r2", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "libssl1.1", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -323,6 +424,22 @@ func TestApplier_ApplyLayers(t *testing.T) { { Name: "musl", Version: "1.1.22-r3", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.1.22-r3", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -331,6 +448,23 @@ func TestApplier_ApplyLayers(t *testing.T) { { Name: "openssl", Version: "1.1.1d-r2", + Identifier: types.PkgIdentifier{ + //PURL: "pkg:apk/alpine/openssl@1.1.1d-r2?distro=3.10.4", + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "openssl", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", DiffID: "sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028", @@ -549,6 +683,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", + }, + }, + }, }, { Name: "symfony/process", @@ -557,6 +701,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203", DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", + }, + }, + }, }, }, }, @@ -741,6 +895,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", + }, + }, + }, }, { Name: "symfony/process", @@ -749,6 +913,16 @@ func TestApplier_ApplyLayers(t *testing.T) { Digest: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", + }, + }, + }, }, }, }, diff --git a/pkg/fanal/applier/docker.go b/pkg/fanal/applier/docker.go index b0f42d957eec..68de804c89b1 100644 --- a/pkg/fanal/applier/docker.go +++ b/pkg/fanal/applier/docker.go @@ -8,7 +8,10 @@ import ( "github.com/knqyf263/nested" "github.com/samber/lo" - "github.com/aquasecurity/trivy/pkg/fanal/types" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/purl" + "github.com/aquasecurity/trivy/pkg/types" ) type Config struct { @@ -25,7 +28,7 @@ type History struct { CreatedBy string `json:"created_by"` } -func containsPackage(e types.Package, s []types.Package) bool { +func containsPackage(e ftypes.Package, s []ftypes.Package) bool { for _, a := range s { if a.Name == e.Name && a.Version == e.Version && a.Release == e.Release { return true @@ -34,7 +37,7 @@ func containsPackage(e types.Package, s []types.Package) bool { return false } -func lookupOriginLayerForPkg(pkg types.Package, layers []types.BlobInfo) (string, string, *types.BuildInfo) { +func lookupOriginLayerForPkg(pkg ftypes.Package, layers []ftypes.BlobInfo) (string, string, *ftypes.BuildInfo) { for i, layer := range layers { for _, info := range layer.PackageInfos { if containsPackage(pkg, info.Packages) { @@ -46,7 +49,7 @@ func lookupOriginLayerForPkg(pkg types.Package, layers []types.BlobInfo) (string } // lookupBuildInfo looks up Red Hat content sets from all layers -func lookupBuildInfo(index int, layers []types.BlobInfo) *types.BuildInfo { +func lookupBuildInfo(index int, layers []ftypes.BlobInfo) *ftypes.BuildInfo { if layers[index].BuildInfo != nil { return layers[index].BuildInfo } @@ -70,7 +73,7 @@ func lookupBuildInfo(index int, layers []types.BlobInfo) *types.BuildInfo { return nil } -func lookupOriginLayerForLib(filePath string, lib types.Package, layers []types.BlobInfo) (string, string) { +func lookupOriginLayerForLib(filePath string, lib ftypes.Package, layers []ftypes.BlobInfo) (string, string) { for _, layer := range layers { for _, layerApp := range layer.Applications { if filePath != layerApp.FilePath { @@ -86,11 +89,11 @@ func lookupOriginLayerForLib(filePath string, lib types.Package, layers []types. // ApplyLayers returns the merged layer // nolint: gocyclo -func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { +func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail { sep := "/" nestedMap := nested.Nested{} - secretsMap := make(map[string]types.Secret) - var mergedLayer types.ArtifactDetail + secretsMap := make(map[string]ftypes.Secret) + var mergedLayer ftypes.ArtifactDetail for _, layer := range layers { for _, opqDir := range layer.OpaqueDirs { @@ -121,7 +124,7 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // Apply misconfigurations for _, config := range layer.Misconfigurations { - config.Layer = types.Layer{ + config.Layer = ftypes.Layer{ Digest: layer.Digest, DiffID: layer.DiffID, } @@ -131,7 +134,7 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // Apply secrets for _, secret := range layer.Secrets { - l := types.Layer{ + l := ftypes.Layer{ Digest: layer.Digest, DiffID: layer.DiffID, CreatedBy: layer.CreatedBy, @@ -141,7 +144,7 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // Apply license files for _, license := range layer.Licenses { - license.Layer = types.Layer{ + license.Layer = ftypes.Layer{ Digest: layer.Digest, DiffID: layer.DiffID, } @@ -152,7 +155,7 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // Apply custom resources for _, customResource := range layer.CustomResources { key := fmt.Sprintf("%s/custom:%s", customResource.FilePath, customResource.Type) - customResource.Layer = types.Layer{ + customResource.Layer = ftypes.Layer{ Digest: layer.Digest, DiffID: layer.DiffID, } @@ -163,15 +166,15 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // nolint _ = nestedMap.Walk(func(keys []string, value interface{}) error { switch v := value.(type) { - case types.PackageInfo: + case ftypes.PackageInfo: mergedLayer.Packages = append(mergedLayer.Packages, v.Packages...) - case types.Application: + case ftypes.Application: mergedLayer.Applications = append(mergedLayer.Applications, v) - case types.Misconfiguration: + case ftypes.Misconfiguration: mergedLayer.Misconfigurations = append(mergedLayer.Misconfigurations, v) - case types.LicenseFile: + case ftypes.LicenseFile: mergedLayer.Licenses = append(mergedLayer.Licenses, v) - case types.CustomResource: + case ftypes.CustomResource: mergedLayer.CustomResources = append(mergedLayer.CustomResources, v) } return nil @@ -185,14 +188,14 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { // The license information is not stored in the dpkg database and in a separate file, // so we have to merge the license information into the package. dpkgLicenses := make(map[string][]string) - mergedLayer.Licenses = lo.Reject(mergedLayer.Licenses, func(license types.LicenseFile, _ int) bool { - if license.Type != types.LicenseTypeDpkg { + mergedLayer.Licenses = lo.Reject(mergedLayer.Licenses, func(license ftypes.LicenseFile, _ int) bool { + if license.Type != ftypes.LicenseTypeDpkg { return false } // e.g. // "adduser" => {"GPL-2"} // "openssl" => {"MIT", "BSD"} - dpkgLicenses[license.PkgName] = lo.Map(license.Findings, func(finding types.LicenseFinding, _ int) string { + dpkgLicenses[license.PkgName] = lo.Map(license.Findings, func(finding ftypes.LicenseFinding, _ int) string { return finding.Name }) // Remove this license in the merged result as it is merged into the package information. @@ -208,11 +211,14 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { continue } originLayerDigest, originLayerDiffID, buildInfo := lookupOriginLayerForPkg(pkg, layers) - mergedLayer.Packages[i].Layer = types.Layer{ + mergedLayer.Packages[i].Layer = ftypes.Layer{ Digest: originLayerDigest, DiffID: originLayerDiffID, } mergedLayer.Packages[i].BuildInfo = buildInfo + if mergedLayer.OS.Family != "" { + mergedLayer.Packages[i].Identifier.PURL = newPURL(mergedLayer.OS.Family, types.Metadata{OS: &mergedLayer.OS}, pkg) + } // Only debian packages if licenses, ok := dpkgLicenses[pkg.Name]; ok { @@ -227,10 +233,13 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { continue } originLayerDigest, originLayerDiffID := lookupOriginLayerForLib(app.FilePath, lib, layers) - app.Libraries[i].Layer = types.Layer{ + app.Libraries[i].Layer = ftypes.Layer{ Digest: originLayerDigest, DiffID: originLayerDiffID, } + if lib.Identifier.PURL == nil { + app.Libraries[i].Identifier.PURL = newPURL(app.Type, types.Metadata{}, lib) + } } } @@ -240,16 +249,24 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail { return mergedLayer } +func newPURL(pkgType ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) *ftypes.PackageURL { + p, err := purl.New(pkgType, metadata, pkg) + if err != nil { + log.Logger.Errorf("Failed to create PackageURL: %s", err) + } + return p +} + // aggregate merges all packages installed by pip/gem/npm/jar/conda into each application -func aggregate(detail *types.ArtifactDetail) { - var apps []types.Application - - aggregatedApps := map[types.LangType]*types.Application{ - types.PythonPkg: {Type: types.PythonPkg}, - types.CondaPkg: {Type: types.CondaPkg}, - types.GemSpec: {Type: types.GemSpec}, - types.NodePkg: {Type: types.NodePkg}, - types.Jar: {Type: types.Jar}, +func aggregate(detail *ftypes.ArtifactDetail) { + var apps []ftypes.Application + + aggregatedApps := map[ftypes.LangType]*ftypes.Application{ + ftypes.PythonPkg: {Type: ftypes.PythonPkg}, + ftypes.CondaPkg: {Type: ftypes.CondaPkg}, + ftypes.GemSpec: {Type: ftypes.GemSpec}, + ftypes.NodePkg: {Type: ftypes.NodePkg}, + ftypes.Jar: {Type: ftypes.Jar}, } for _, app := range detail.Applications { @@ -273,7 +290,7 @@ func aggregate(detail *types.ArtifactDetail) { // We must save secrets from all layers even though they are removed in the uppler layer. // If the secret was changed at the top level, we need to overwrite it. -func mergeSecrets(secretsMap map[string]types.Secret, newSecret types.Secret, layer types.Layer) map[string]types.Secret { +func mergeSecrets(secretsMap map[string]ftypes.Secret, newSecret ftypes.Secret, layer ftypes.Layer) map[string]ftypes.Secret { for i := range newSecret.Findings { // add layer to the Findings from the new secret newSecret.Findings[i].Layer = layer } @@ -294,7 +311,7 @@ func mergeSecrets(secretsMap map[string]types.Secret, newSecret types.Secret, la return secretsMap } -func secretFindingsContains(findings []types.SecretFinding, finding types.SecretFinding) bool { +func secretFindingsContains(findings []ftypes.SecretFinding, finding ftypes.SecretFinding) bool { for _, f := range findings { if f.RuleID == finding.RuleID { return true diff --git a/pkg/fanal/applier/docker_test.go b/pkg/fanal/applier/docker_test.go index dbd2c3c4a9fb..fc04b7654070 100644 --- a/pkg/fanal/applier/docker_test.go +++ b/pkg/fanal/applier/docker_test.go @@ -1,6 +1,7 @@ package applier_test import ( + "github.com/package-url/packageurl-go" "sort" "testing" @@ -143,6 +144,22 @@ func TestApplyLayers(t *testing.T) { Name: "musl", Version: "1.2.4", Release: "4.5.8", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.4-4.5.8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -152,6 +169,22 @@ func TestApplyLayers(t *testing.T) { Name: "openssl", Version: "1.2.3", Release: "4.5.6", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "openssl", + Version: "1.2.3-4.5.6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -170,6 +203,16 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "activesupport", + Version: "6.0.2.1", + }, + FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", + }, + }, }, { Name: "gon", @@ -179,6 +222,16 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "gon", + Version: "6.3.2", + }, + FilePath: "usr/local/bundle/specifications/gon-6.3.2.gemspec", + }, + }, }, }, }, @@ -193,6 +246,15 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "gemlibrary1", + Version: "1.2.3", + }, + }, + }, }, }, }, @@ -413,6 +475,15 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "rack", + Version: "4.0.0", + }, + }, + }, }, { Name: "rails", @@ -421,6 +492,15 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "rails", + Version: "6.0.0", + }, + }, + }, }, }, }, @@ -435,6 +515,15 @@ func TestApplyLayers(t *testing.T) { Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Name: "phplibrary1", + Version: "6.6.6", + }, + }, + }, }, }, }, @@ -691,6 +780,22 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.4", Release: "4.5.7", Licenses: []string{"GPL-2"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "libc", + Version: "1.2.4-4.5.7", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-8", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -701,6 +806,22 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.3", Release: "4.5.6", Licenses: []string{"OpenSSL"}, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "openssl", + Version: "1.2.3-4.5.6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-8", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", @@ -837,6 +958,22 @@ func TestApplyLayers(t *testing.T) { Name: "bash", Version: "5.6.7", Release: "8", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "bash", + Version: "5.6.7-8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -850,6 +987,22 @@ func TestApplyLayers(t *testing.T) { Name: "libc", Version: "1.2.4", Release: "5", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "libc", + Version: "1.2.4-5", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", @@ -865,6 +1018,22 @@ func TestApplyLayers(t *testing.T) { Name: "openssl", Version: "1.2.3", Release: "4", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "openssl", + Version: "1.2.3-4", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", + }, + }, + }, + }, + }, Layer: types.Layer{ Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", diff --git a/pkg/fanal/artifact/image/remote_sbom_test.go b/pkg/fanal/artifact/image/remote_sbom_test.go index 07f1a3829e8e..b924a6efa6a3 100644 --- a/pkg/fanal/artifact/image/remote_sbom_test.go +++ b/pkg/fanal/artifact/image/remote_sbom_test.go @@ -2,6 +2,7 @@ package image_test import ( "context" + "github.com/package-url/packageurl-go" "net/http" "net/http/httptest" "net/url" @@ -69,7 +70,7 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { putBlobExpectations: []cache.ArtifactCachePutBlobExpectation{ { Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:9c23872047046e145f49fb5533b63ace0cbf819f5b68e33f69f4e9bbab4c517e", + BlobID: "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -80,8 +81,24 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { { Packages: types.Packages{ { - Name: "musl", - Version: "1.2.3-r0", + Name: "musl", + Version: "1.2.3-r0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.2", + }, + }, + }, + }, + }, SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, @@ -104,9 +121,9 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { want: types.ArtifactReference{ Name: "test/image:10", Type: types.ArtifactCycloneDX, - ID: "sha256:9c23872047046e145f49fb5533b63ace0cbf819f5b68e33f69f4e9bbab4c517e", + ID: "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", BlobIDs: []string{ - "sha256:9c23872047046e145f49fb5533b63ace0cbf819f5b68e33f69f4e9bbab4c517e", + "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", }, }, }, @@ -173,7 +190,6 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { case "/v2/test/image/blobs/sha256:9e05dda2a2dcdd526c9204be8645ae48742861c27f093bf496a6397834acecf2": http.ServeFile(w, r, "testdata/cyclonedx.json") } - return })) defer ts.Close() @@ -208,7 +224,7 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { putBlobExpectations: []cache.ArtifactCachePutBlobExpectation{ { Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:d07a1894bfd283b4ac26682ab48f12ad22cdc4fef9cf8b4c09056f631d3667a5", + BlobID: "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, Applications: []types.Application{ @@ -218,12 +234,32 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { { Name: "github.com/opencontainers/go-digest", Version: "v1.0.0", - Ref: "pkg:golang/github.com/opencontainers/go-digest@v1.0.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/opencontainers", + Name: "go-digest", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:golang/github.com/opencontainers/go-digest@v1.0.0", }, { Name: "golang.org/x/sync", Version: "v0.1.0", - Ref: "pkg:golang/golang.org/x/sync@v0.1.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "sync", + Version: "v0.1.0", + }, + }, + }, + Ref: "pkg:golang/golang.org/x/sync@v0.1.0", }, }, }, @@ -235,9 +271,9 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { want: types.ArtifactReference{ Name: registry + "/test/image:10", Type: types.ArtifactCycloneDX, - ID: "sha256:d07a1894bfd283b4ac26682ab48f12ad22cdc4fef9cf8b4c09056f631d3667a5", + ID: "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", BlobIDs: []string{ - "sha256:d07a1894bfd283b4ac26682ab48f12ad22cdc4fef9cf8b4c09056f631d3667a5", + "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", }, }, }, diff --git a/pkg/fanal/artifact/local/fs_test.go b/pkg/fanal/artifact/local/fs_test.go index 21049d566f2a..200aa970bfb9 100644 --- a/pkg/fanal/artifact/local/fs_test.go +++ b/pkg/fanal/artifact/local/fs_test.go @@ -47,7 +47,7 @@ func TestArtifact_Inspect(t *testing.T) { }, putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055", + BlobID: "sha256:ff28bff7756fb32d0a060b3b474b31a781a2d365dcd2789f47b4ae556a34947e", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -82,9 +82,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: "host", Type: types.ArtifactFilesystem, - ID: "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055", + ID: "sha256:ff28bff7756fb32d0a060b3b474b31a781a2d365dcd2789f47b4ae556a34947e", BlobIDs: []string{ - "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055", + "sha256:ff28bff7756fb32d0a060b3b474b31a781a2d365dcd2789f47b4ae556a34947e", }, }, }, @@ -125,7 +125,7 @@ func TestArtifact_Inspect(t *testing.T) { }, putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055", + BlobID: "sha256:ff28bff7756fb32d0a060b3b474b31a781a2d365dcd2789f47b4ae556a34947e", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -175,7 +175,7 @@ func TestArtifact_Inspect(t *testing.T) { }, putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + BlobID: "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, Applications: []types.Application{ @@ -197,9 +197,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: "testdata/requirements.txt", Type: types.ArtifactFilesystem, - ID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + ID: "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", BlobIDs: []string{ - "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", }, }, }, @@ -210,7 +210,7 @@ func TestArtifact_Inspect(t *testing.T) { }, putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + BlobID: "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, Applications: []types.Application{ @@ -232,9 +232,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: "testdata/requirements.txt", Type: types.ArtifactFilesystem, - ID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + ID: "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", BlobIDs: []string{ - "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1", + "sha256:09aa251b64e824d0ec71a8c469619e57c9bd91d885f26e4a840de94209acbe4f", }, }, }, diff --git a/pkg/fanal/artifact/sbom/sbom_test.go b/pkg/fanal/artifact/sbom/sbom_test.go index 9817c1a845fc..036574b63d13 100644 --- a/pkg/fanal/artifact/sbom/sbom_test.go +++ b/pkg/fanal/artifact/sbom/sbom_test.go @@ -3,6 +3,7 @@ package sbom_test import ( "context" "errors" + "github.com/package-url/packageurl-go" "path/filepath" "strings" "testing" @@ -29,7 +30,7 @@ func TestArtifact_Inspect(t *testing.T) { filePath: filepath.Join("testdata", "bom.json"), putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + BlobID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -49,6 +50,22 @@ func TestArtifact_Inspect(t *testing.T) { Layer: types.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", + }, + }, + }, + }, + }, }, }, }, @@ -65,6 +82,16 @@ func TestArtifact_Inspect(t *testing.T) { Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, }, { @@ -74,6 +101,16 @@ func TestArtifact_Inspect(t *testing.T) { Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, }, }, }, @@ -88,6 +125,16 @@ func TestArtifact_Inspect(t *testing.T) { Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", + }, + }, + }, }, }, }, @@ -103,6 +150,17 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, FilePath: "app/maven/target/child-project-1.0.jar", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", + }, + FilePath: "app/maven/target/child-project-1.0.jar", + }, + }, }, }, }, @@ -119,6 +177,16 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, FilePath: "app/app/package.json", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", + }, + FilePath: "app/app/package.json", + }, + }, }, }, }, @@ -130,9 +198,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: filepath.Join("testdata", "bom.json"), Type: types.ArtifactCycloneDX, - ID: "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + ID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", BlobIDs: []string{ - "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", }, }, }, @@ -141,7 +209,7 @@ func TestArtifact_Inspect(t *testing.T) { filePath: filepath.Join("testdata", "sbom.cdx.intoto.jsonl"), putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + BlobID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -157,7 +225,23 @@ func TestArtifact_Inspect(t *testing.T) { SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", + }, + }, + }, + }, + }, + Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: types.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -173,7 +257,17 @@ func TestArtifact_Inspect(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -182,7 +276,17 @@ func TestArtifact_Inspect(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -196,7 +300,17 @@ func TestArtifact_Inspect(t *testing.T) { { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", + }, + }, + }, + Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -209,8 +323,19 @@ func TestArtifact_Inspect(t *testing.T) { Libraries: types.Packages{ { Name: "org.codehaus.mojo:child-project", - Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Version: "1.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", + }, + FilePath: "app/maven/target/child-project-1.0.jar", + }, + }, + Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -223,8 +348,18 @@ func TestArtifact_Inspect(t *testing.T) { FilePath: "", Libraries: types.Packages{ { - Name: "bootstrap", - Version: "5.0.2", + Name: "bootstrap", + Version: "5.0.2", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", + }, + FilePath: "app/app/package.json", + }, + }, Ref: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", Licenses: []string{"MIT"}, Layer: types.Layer{ @@ -242,9 +377,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: filepath.Join("testdata", "sbom.cdx.intoto.jsonl"), Type: types.ArtifactCycloneDX, - ID: "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + ID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", BlobIDs: []string{ - "sha256:3dca5f9082ac4e9669b5e461ae54ffe70db4ea275a09506014b17e012687e855", + "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", }, }, }, diff --git a/pkg/fanal/artifact/vm/vm_test.go b/pkg/fanal/artifact/vm/vm_test.go index 42ec47c07973..891b23797746 100644 --- a/pkg/fanal/artifact/vm/vm_test.go +++ b/pkg/fanal/artifact/vm/vm_test.go @@ -121,7 +121,7 @@ func TestArtifact_Inspect(t *testing.T) { rootDir: "testdata/alpine", putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:aeadb167e49ab2616738bc1d8b39f742968bef78baed984cf5801c678d6750ce", + BlobID: "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", BlobInfo: expectedBlobInfo, }, Returns: cache.ArtifactCachePutBlobReturns{}, @@ -129,7 +129,7 @@ func TestArtifact_Inspect(t *testing.T) { putArtifactExpectations: []cache.ArtifactCachePutArtifactExpectation{ { Args: cache.ArtifactCachePutArtifactArgs{ - ArtifactID: "sha256:aeadb167e49ab2616738bc1d8b39f742968bef78baed984cf5801c678d6750ce", + ArtifactID: "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", ArtifactInfo: types.ArtifactInfo{ SchemaVersion: types.ArtifactJSONSchemaVersion, }, @@ -139,9 +139,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: "rawdata.img", Type: types.ArtifactVM, - ID: "sha256:aeadb167e49ab2616738bc1d8b39f742968bef78baed984cf5801c678d6750ce", + ID: "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", BlobIDs: []string{ - "sha256:aeadb167e49ab2616738bc1d8b39f742968bef78baed984cf5801c678d6750ce", + "sha256:84a726d23c36d0e1857101969b257c1199de5432489d44581750d54ea8eff8cd", }, }, }, diff --git a/pkg/fanal/cache/fs_test.go b/pkg/fanal/cache/fs_test.go index fe93adb41f55..eaa050096d24 100644 --- a/pkg/fanal/cache/fs_test.go +++ b/pkg/fanal/cache/fs_test.go @@ -225,6 +225,7 @@ func TestFSCache_PutBlob(t *testing.T) { { "Name": "musl", "Version": "1.1.22-r3", + "Identifier": {}, "Layer": {} } ] @@ -238,11 +239,13 @@ func TestFSCache_PutBlob(t *testing.T) { { "Name":"guzzlehttp/guzzle", "Version":"6.2.0", + "Identifier": {}, "Layer": {} }, { "Name":"guzzlehttp/promises", "Version":"v1.3.1", + "Identifier": {}, "Layer": {} } ] @@ -341,6 +344,7 @@ func TestFSCache_PutArtifact(t *testing.T) { { "Name": "musl", "Version": "1.2.3", + "Identifier": {}, "Layer": {} } ] diff --git a/pkg/fanal/cache/mock_artifact_cache.go b/pkg/fanal/cache/mock_artifact_cache.go index 39fb5525c710..c73786021a58 100644 --- a/pkg/fanal/cache/mock_artifact_cache.go +++ b/pkg/fanal/cache/mock_artifact_cache.go @@ -193,7 +193,7 @@ type ArtifactCachePutBlobExpectation struct { Returns ArtifactCachePutBlobReturns } -func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpectation) { +func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpectation) *mock.Call{ var args []interface{} if e.Args.BlobIDAnything { args = append(args, mock.Anything) @@ -205,7 +205,8 @@ func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpec } else { args = append(args, e.Args.BlobInfo) } - _m.On("PutBlob", args...).Return(e.Returns.Err) + return _m.On("PutBlob", args...).Return(e.Returns.Err) + //return _m.On("PutBlob", mock.AnythingOfType("string"), mock.Anything).Return(e.Returns.Err) } func (_m *MockArtifactCache) ApplyPutBlobExpectations(expectations []ArtifactCachePutBlobExpectation) { diff --git a/pkg/fanal/handler/sysfile/filter_test.go b/pkg/fanal/handler/sysfile/filter_test.go index 6dc8d5af7b03..1b987fd5823f 100644 --- a/pkg/fanal/handler/sysfile/filter_test.go +++ b/pkg/fanal/handler/sysfile/filter_test.go @@ -178,7 +178,7 @@ func Test_systemFileFilterHook_Hook(t *testing.T) { }, }, { - name: "distoless", + name: "distroless", result: &analyzer.AnalysisResult{}, blob: &types.BlobInfo{ Applications: []types.Application{ diff --git a/pkg/fanal/handler/unpackaged/unpackaged_test.go b/pkg/fanal/handler/unpackaged/unpackaged_test.go index 8813e0eb3558..483e45b81b71 100644 --- a/pkg/fanal/handler/unpackaged/unpackaged_test.go +++ b/pkg/fanal/handler/unpackaged/unpackaged_test.go @@ -2,6 +2,7 @@ package unpackaged_test import ( "context" + "github.com/package-url/packageurl-go" "testing" "github.com/stretchr/testify/assert" @@ -45,6 +46,16 @@ func Test_unpackagedHook_Handle(t *testing.T) { Name: "github.com/spf13/cobra", Version: "1.5.0", Ref: "pkg:golang/github.com/spf13/cobra@1.5.0", + Identifier: types.PkgIdentifier{ + PURL: &types.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/spf13", + Name: "cobra", + Version: "1.5.0", + }, + }, + }, }, }, }, diff --git a/pkg/fanal/test/integration/library_test.go b/pkg/fanal/test/integration/library_test.go index e8be494a57d5..b802084ba314 100644 --- a/pkg/fanal/test/integration/library_test.go +++ b/pkg/fanal/test/integration/library_test.go @@ -362,6 +362,14 @@ func checkLangPkgs(detail types.ArtifactDetail, t *testing.T, tc testCase) { func checkPackageFromCommands(t *testing.T, detail types.ArtifactDetail, tc testCase) { if tc.wantPkgsFromCmds != "" { + if *update { + sort.Sort(types.Packages(detail.ImageConfig.Packages)) + b, err := json.MarshalIndent(detail.ImageConfig.Packages, "", " ") + require.NoError(t, err) + err = os.WriteFile(tc.wantPkgsFromCmds, b, 0666) + require.NoError(t, err) + return + } data, _ := os.ReadFile(tc.wantPkgsFromCmds) var expectedPkgsFromCmds []types.Package diff --git a/pkg/fanal/test/integration/testdata/goldens/packages/alpine-310.json.golden b/pkg/fanal/test/integration/testdata/goldens/packages/alpine-310.json.golden index 801661d8deed..ff6de7ec239e 100644 --- a/pkg/fanal/test/integration/testdata/goldens/packages/alpine-310.json.golden +++ b/pkg/fanal/test/integration/testdata/goldens/packages/alpine-310.json.golden @@ -2,6 +2,9 @@ { "ID": "alpine-baselayout@3.1.2-r0", "Name": "alpine-baselayout", + "Identifier": { + "PURL": "pkg:apk/alpine/alpine-baselayout@3.1.2-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "3.1.2-r0", "Arch": "x86_64", "SrcName": "alpine-baselayout", @@ -49,6 +52,9 @@ { "ID": "alpine-keys@2.1-r2", "Name": "alpine-keys", + "Identifier": { + "PURL": "pkg:apk/alpine/alpine-keys@2.1-r2?arch=x86_64\u0026distro=3.10.2" + }, "Version": "2.1-r2", "Arch": "x86_64", "SrcName": "alpine-keys", @@ -85,6 +91,9 @@ { "ID": "apk-tools@2.10.4-r2", "Name": "apk-tools", + "Identifier": { + "PURL": "pkg:apk/alpine/apk-tools@2.10.4-r2?arch=x86_64\u0026distro=3.10.2" + }, "Version": "2.10.4-r2", "Arch": "x86_64", "SrcName": "apk-tools", @@ -110,6 +119,9 @@ { "ID": "busybox@1.30.1-r2", "Name": "busybox", + "Identifier": { + "PURL": "pkg:apk/alpine/busybox@1.30.1-r2?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.30.1-r2", "Arch": "x86_64", "SrcName": "busybox", @@ -137,6 +149,9 @@ { "ID": "ca-certificates-cacert@20190108-r0", "Name": "ca-certificates-cacert", + "Identifier": { + "PURL": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "20190108-r0", "Arch": "x86_64", "SrcName": "ca-certificates", @@ -157,6 +172,9 @@ { "ID": "libc-utils@0.7.1-r0", "Name": "libc-utils", + "Identifier": { + "PURL": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "0.7.1-r0", "Arch": "x86_64", "SrcName": "libc-dev", @@ -176,6 +194,9 @@ { "ID": "libcrypto1.1@1.1.1c-r0", "Name": "libcrypto1.1", + "Identifier": { + "PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.1.1c-r0", "Arch": "x86_64", "SrcName": "openssl", @@ -209,6 +230,9 @@ { "ID": "libssl1.1@1.1.1c-r0", "Name": "libssl1.1", + "Identifier": { + "PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.1.1c-r0", "Arch": "x86_64", "SrcName": "openssl", @@ -233,6 +257,9 @@ { "ID": "libtls-standalone@2.9.1-r0", "Name": "libtls-standalone", + "Identifier": { + "PURL": "pkg:apk/alpine/libtls-standalone@2.9.1-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "2.9.1-r0", "Arch": "x86_64", "SrcName": "libtls-standalone", @@ -259,6 +286,9 @@ { "ID": "musl@1.1.22-r3", "Name": "musl", + "Identifier": { + "PURL": "pkg:apk/alpine/musl@1.1.22-r3?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.1.22-r3", "Arch": "x86_64", "SrcName": "musl", @@ -279,6 +309,9 @@ { "ID": "musl-utils@1.1.22-r3", "Name": "musl-utils", + "Identifier": { + "PURL": "pkg:apk/alpine/musl-utils@1.1.22-r3?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.1.22-r3", "Arch": "x86_64", "SrcName": "musl", @@ -308,6 +341,9 @@ { "ID": "scanelf@1.2.3-r0", "Name": "scanelf", + "Identifier": { + "PURL": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.2.3-r0", "Arch": "x86_64", "SrcName": "pax-utils", @@ -330,6 +366,9 @@ { "ID": "ssl_client@1.30.1-r2", "Name": "ssl_client", + "Identifier": { + "PURL": "pkg:apk/alpine/ssl_client@1.30.1-r2?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.30.1-r2", "Arch": "x86_64", "SrcName": "busybox", @@ -353,6 +392,9 @@ { "ID": "zlib@1.2.11-r1", "Name": "zlib", + "Identifier": { + "PURL": "pkg:apk/alpine/zlib@1.2.11-r1?arch=x86_64\u0026distro=3.10.2" + }, "Version": "1.2.11-r1", "Arch": "x86_64", "SrcName": "zlib", diff --git a/pkg/fanal/test/integration/testdata/goldens/packages/vulnimage.json.golden b/pkg/fanal/test/integration/testdata/goldens/packages/vulnimage.json.golden index a4ca8c82c17d..d6e7df5676d6 100644 --- a/pkg/fanal/test/integration/testdata/goldens/packages/vulnimage.json.golden +++ b/pkg/fanal/test/integration/testdata/goldens/packages/vulnimage.json.golden @@ -2,6 +2,9 @@ { "ID": ".composer-phpext-rundeps@0", "Name": ".composer-phpext-rundeps", + "Identifier": { + "PURL": "pkg:apk/alpine/.composer-phpext-rundeps@0?arch=noarch\u0026distro=3.7.1" + }, "Version": "0", "Arch": "noarch", "DependsOn": [ @@ -18,6 +21,9 @@ { "ID": ".persistent-deps@0", "Name": ".persistent-deps", + "Identifier": { + "PURL": "pkg:apk/alpine/.persistent-deps@0?arch=noarch\u0026distro=3.7.1" + }, "Version": "0", "Arch": "noarch", "DependsOn": [ @@ -36,6 +42,9 @@ { "ID": ".php-rundeps@0", "Name": ".php-rundeps", + "Identifier": { + "PURL": "pkg:apk/alpine/.php-rundeps@0?arch=noarch\u0026distro=3.7.1" + }, "Version": "0", "Arch": "noarch", "DependsOn": [ @@ -57,6 +66,9 @@ { "ID": "alpine-baselayout@3.0.5-r2", "Name": "alpine-baselayout", + "Identifier": { + "PURL": "pkg:apk/alpine/alpine-baselayout@3.0.5-r2?arch=x86_64\u0026distro=3.7.1" + }, "Version": "3.0.5-r2", "Arch": "x86_64", "SrcName": "alpine-baselayout", @@ -105,6 +117,9 @@ { "ID": "alpine-keys@2.1-r1", "Name": "alpine-keys", + "Identifier": { + "PURL": "pkg:apk/alpine/alpine-keys@2.1-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.1-r1", "Arch": "x86_64", "SrcName": "alpine-keys", @@ -141,6 +156,9 @@ { "ID": "apk-tools@2.10.1-r0", "Name": "apk-tools", + "Identifier": { + "PURL": "pkg:apk/alpine/apk-tools@2.10.1-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.10.1-r0", "Arch": "x86_64", "SrcName": "apk-tools", @@ -166,6 +184,9 @@ { "ID": "apr@1.6.3-r0", "Name": "apr", + "Identifier": { + "PURL": "pkg:apk/alpine/apr@1.6.3-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.6.3-r0", "Arch": "x86_64", "SrcName": "apr", @@ -191,6 +212,9 @@ { "ID": "apr-util@1.6.1-r1", "Name": "apr-util", + "Identifier": { + "PURL": "pkg:apk/alpine/apr-util@1.6.1-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.6.1-r1", "Arch": "x86_64", "SrcName": "apr-util", @@ -219,6 +243,9 @@ { "ID": "bash@4.4.19-r1", "Name": "bash", + "Identifier": { + "PURL": "pkg:apk/alpine/bash@4.4.19-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "4.4.19-r1", "Arch": "x86_64", "SrcName": "bash", @@ -330,6 +357,9 @@ { "ID": "busybox@1.27.2-r11", "Name": "busybox", + "Identifier": { + "PURL": "pkg:apk/alpine/busybox@1.27.2-r11?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.27.2-r11", "Arch": "x86_64", "SrcName": "busybox", @@ -357,6 +387,9 @@ { "ID": "ca-certificates@20171114-r0", "Name": "ca-certificates", + "Identifier": { + "PURL": "pkg:apk/alpine/ca-certificates@20171114-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "20171114-r0", "Arch": "x86_64", "SrcName": "ca-certificates", @@ -537,6 +570,9 @@ { "ID": "curl@7.61.0-r0", "Name": "curl", + "Identifier": { + "PURL": "pkg:apk/alpine/curl@7.61.0-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.61.0-r0", "Arch": "x86_64", "SrcName": "curl", @@ -562,6 +598,9 @@ { "ID": "db@5.3.28-r0", "Name": "db", + "Identifier": { + "PURL": "pkg:apk/alpine/db@5.3.28-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "5.3.28-r0", "Arch": "x86_64", "SrcName": "db", @@ -584,6 +623,9 @@ { "ID": "expat@2.2.5-r0", "Name": "expat", + "Identifier": { + "PURL": "pkg:apk/alpine/expat@2.2.5-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.2.5-r0", "Arch": "x86_64", "SrcName": "expat", @@ -608,6 +650,9 @@ { "ID": "gdbm@1.13-r1", "Name": "gdbm", + "Identifier": { + "PURL": "pkg:apk/alpine/gdbm@1.13-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.13-r1", "Arch": "x86_64", "SrcName": "gdbm", @@ -636,6 +681,9 @@ { "ID": "git@2.15.2-r0", "Name": "git", + "Identifier": { + "PURL": "pkg:apk/alpine/git@2.15.2-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.15.2-r0", "Arch": "x86_64", "SrcName": "git", @@ -852,6 +900,9 @@ { "ID": "libbz2@1.0.6-r6", "Name": "libbz2", + "Identifier": { + "PURL": "pkg:apk/alpine/libbz2@1.0.6-r6?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.0.6-r6", "Arch": "x86_64", "SrcName": "bzip2", @@ -875,6 +926,9 @@ { "ID": "libc-utils@0.7.1-r0", "Name": "libc-utils", + "Identifier": { + "PURL": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "0.7.1-r0", "Arch": "x86_64", "SrcName": "libc-dev", @@ -894,6 +948,9 @@ { "ID": "libcurl@7.61.1-r0", "Name": "libcurl", + "Identifier": { + "PURL": "pkg:apk/alpine/libcurl@7.61.1-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.61.1-r0", "Arch": "x86_64", "SrcName": "curl", @@ -922,6 +979,9 @@ { "ID": "libedit@20170329.3.1-r3", "Name": "libedit", + "Identifier": { + "PURL": "pkg:apk/alpine/libedit@20170329.3.1-r3?arch=x86_64\u0026distro=3.7.1" + }, "Version": "20170329.3.1-r3", "Arch": "x86_64", "SrcName": "libedit", @@ -946,6 +1006,9 @@ { "ID": "libffi@3.2.1-r4", "Name": "libffi", + "Identifier": { + "PURL": "pkg:apk/alpine/libffi@3.2.1-r4?arch=x86_64\u0026distro=3.7.1" + }, "Version": "3.2.1-r4", "Arch": "x86_64", "SrcName": "libffi", @@ -969,6 +1032,9 @@ { "ID": "libressl@2.6.5-r0", "Name": "libressl", + "Identifier": { + "PURL": "pkg:apk/alpine/libressl@2.6.5-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.6.5-r0", "Arch": "x86_64", "SrcName": "libressl", @@ -995,6 +1061,9 @@ { "ID": "libressl2.6-libcrypto@2.6.5-r0", "Name": "libressl2.6-libcrypto", + "Identifier": { + "PURL": "pkg:apk/alpine/libressl2.6-libcrypto@2.6.5-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.6.5-r0", "Arch": "x86_64", "SrcName": "libressl", @@ -1023,6 +1092,9 @@ { "ID": "libressl2.6-libssl@2.6.5-r0", "Name": "libressl2.6-libssl", + "Identifier": { + "PURL": "pkg:apk/alpine/libressl2.6-libssl@2.6.5-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.6.5-r0", "Arch": "x86_64", "SrcName": "libressl", @@ -1049,6 +1121,9 @@ { "ID": "libressl2.6-libtls@2.6.5-r0", "Name": "libressl2.6-libtls", + "Identifier": { + "PURL": "pkg:apk/alpine/libressl2.6-libtls@2.6.5-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.6.5-r0", "Arch": "x86_64", "SrcName": "libressl", @@ -1076,6 +1151,9 @@ { "ID": "libsasl@2.1.26-r11", "Name": "libsasl", + "Identifier": { + "PURL": "pkg:apk/alpine/libsasl@2.1.26-r11?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.1.26-r11", "Arch": "x86_64", "SrcName": "cyrus-sasl", @@ -1109,6 +1187,9 @@ { "ID": "libsodium@1.0.15-r0", "Name": "libsodium", + "Identifier": { + "PURL": "pkg:apk/alpine/libsodium@1.0.15-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.0.15-r0", "Arch": "x86_64", "SrcName": "libsodium", @@ -1132,6 +1213,9 @@ { "ID": "libssh2@1.8.0-r2", "Name": "libssh2", + "Identifier": { + "PURL": "pkg:apk/alpine/libssh2@1.8.0-r2?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.8.0-r2", "Arch": "x86_64", "SrcName": "libssh2", @@ -1157,6 +1241,9 @@ { "ID": "libuuid@2.31-r0", "Name": "libuuid", + "Identifier": { + "PURL": "pkg:apk/alpine/libuuid@2.31-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.31-r0", "Arch": "x86_64", "SrcName": "util-linux", @@ -1185,6 +1272,9 @@ { "ID": "libxml2@2.9.7-r0", "Name": "libxml2", + "Identifier": { + "PURL": "pkg:apk/alpine/libxml2@2.9.7-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.9.7-r0", "Arch": "x86_64", "SrcName": "libxml2", @@ -1209,6 +1299,9 @@ { "ID": "mercurial@4.5.2-r0", "Name": "mercurial", + "Identifier": { + "PURL": "pkg:apk/alpine/mercurial@4.5.2-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "4.5.2-r0", "Arch": "x86_64", "SrcName": "mercurial", @@ -1950,6 +2043,9 @@ { "ID": "musl@1.1.18-r3", "Name": "musl", + "Identifier": { + "PURL": "pkg:apk/alpine/musl@1.1.18-r3?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.1.18-r3", "Arch": "x86_64", "SrcName": "musl", @@ -1970,6 +2066,9 @@ { "ID": "musl-utils@1.1.18-r3", "Name": "musl-utils", + "Identifier": { + "PURL": "pkg:apk/alpine/musl-utils@1.1.18-r3?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.1.18-r3", "Arch": "x86_64", "SrcName": "musl", @@ -1999,6 +2098,9 @@ { "ID": "ncurses-libs@6.0_p20171125-r1", "Name": "ncurses-libs", + "Identifier": { + "PURL": "pkg:apk/alpine/ncurses-libs@6.0_p20171125-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "6.0_p20171125-r1", "Arch": "x86_64", "SrcName": "ncurses", @@ -2031,6 +2133,9 @@ { "ID": "ncurses-terminfo@6.0_p20171125-r1", "Name": "ncurses-terminfo", + "Identifier": { + "PURL": "pkg:apk/alpine/ncurses-terminfo@6.0_p20171125-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "6.0_p20171125-r1", "Arch": "x86_64", "SrcName": "ncurses", @@ -4781,6 +4886,9 @@ { "ID": "ncurses-terminfo-base@6.0_p20171125-r1", "Name": "ncurses-terminfo-base", + "Identifier": { + "PURL": "pkg:apk/alpine/ncurses-terminfo-base@6.0_p20171125-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "6.0_p20171125-r1", "Arch": "x86_64", "SrcName": "ncurses", @@ -4813,6 +4921,9 @@ { "ID": "openssh@7.5_p1-r9", "Name": "openssh", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4839,6 +4950,9 @@ { "ID": "openssh-client@7.5_p1-r9", "Name": "openssh-client", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh-client@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4874,6 +4988,9 @@ { "ID": "openssh-keygen@7.5_p1-r9", "Name": "openssh-keygen", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh-keygen@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4897,6 +5014,9 @@ { "ID": "openssh-server@7.5_p1-r9", "Name": "openssh-server", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh-server@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4923,6 +5043,9 @@ { "ID": "openssh-server-common@7.5_p1-r9", "Name": "openssh-server-common", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh-server-common@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4944,6 +5067,9 @@ { "ID": "openssh-sftp-server@7.5_p1-r9", "Name": "openssh-sftp-server", + "Identifier": { + "PURL": "pkg:apk/alpine/openssh-sftp-server@7.5_p1-r9?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.5_p1-r9", "Arch": "x86_64", "SrcName": "openssh", @@ -4966,6 +5092,9 @@ { "ID": "patch@2.7.5-r2", "Name": "patch", + "Identifier": { + "PURL": "pkg:apk/alpine/patch@2.7.5-r2?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.7.5-r2", "Arch": "x86_64", "SrcName": "patch", @@ -4988,6 +5117,9 @@ { "ID": "pcre2@10.30-r0", "Name": "pcre2", + "Identifier": { + "PURL": "pkg:apk/alpine/pcre2@10.30-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "10.30-r0", "Arch": "x86_64", "SrcName": "pcre2", @@ -5013,6 +5145,9 @@ { "ID": "pkgconf@1.3.10-r0", "Name": "pkgconf", + "Identifier": { + "PURL": "pkg:apk/alpine/pkgconf@1.3.10-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.3.10-r0", "Arch": "x86_64", "SrcName": "pkgconf", @@ -5039,6 +5174,9 @@ { "ID": "python2@2.7.15-r2", "Name": "python2", + "Identifier": { + "PURL": "pkg:apk/alpine/python2@2.7.15-r2?arch=x86_64\u0026distro=3.7.1" + }, "Version": "2.7.15-r2", "Arch": "x86_64", "SrcName": "python2", @@ -7481,6 +7619,9 @@ { "ID": "readline@7.0.003-r0", "Name": "readline", + "Identifier": { + "PURL": "pkg:apk/alpine/readline@7.0.003-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "7.0.003-r0", "Arch": "x86_64", "SrcName": "readline", @@ -7505,6 +7646,9 @@ { "ID": "scanelf@1.2.2-r1", "Name": "scanelf", + "Identifier": { + "PURL": "pkg:apk/alpine/scanelf@1.2.2-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.2.2-r1", "Arch": "x86_64", "SrcName": "pax-utils", @@ -7527,6 +7671,9 @@ { "ID": "serf@1.3.9-r3", "Name": "serf", + "Identifier": { + "PURL": "pkg:apk/alpine/serf@1.3.9-r3?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.3.9-r3", "Arch": "x86_64", "SrcName": "serf", @@ -7555,6 +7702,9 @@ { "ID": "sqlite-libs@3.21.0-r1", "Name": "sqlite-libs", + "Identifier": { + "PURL": "pkg:apk/alpine/sqlite-libs@3.21.0-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "3.21.0-r1", "Arch": "x86_64", "SrcName": "sqlite", @@ -7578,6 +7728,9 @@ { "ID": "ssl_client@1.27.2-r11", "Name": "ssl_client", + "Identifier": { + "PURL": "pkg:apk/alpine/ssl_client@1.27.2-r11?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.27.2-r11", "Arch": "x86_64", "SrcName": "busybox", @@ -7601,6 +7754,9 @@ { "ID": "subversion@1.9.7-r0", "Name": "subversion", + "Identifier": { + "PURL": "pkg:apk/alpine/subversion@1.9.7-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.9.7-r0", "Arch": "x86_64", "SrcName": "subversion", @@ -7656,6 +7812,9 @@ { "ID": "subversion-libs@1.9.7-r0", "Name": "subversion-libs", + "Identifier": { + "PURL": "pkg:apk/alpine/subversion-libs@1.9.7-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.9.7-r0", "Arch": "x86_64", "SrcName": "subversion", @@ -7716,6 +7875,9 @@ { "ID": "tar@1.29-r1", "Name": "tar", + "Identifier": { + "PURL": "pkg:apk/alpine/tar@1.29-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.29-r1", "Arch": "x86_64", "SrcName": "tar", @@ -7740,6 +7902,9 @@ { "ID": "tini@0.16.1-r0", "Name": "tini", + "Identifier": { + "PURL": "pkg:apk/alpine/tini@0.16.1-r0?arch=x86_64\u0026distro=3.7.1" + }, "Version": "0.16.1-r0", "Arch": "x86_64", "SrcName": "tini", @@ -7762,6 +7927,9 @@ { "ID": "xz@5.2.3-r1", "Name": "xz", + "Identifier": { + "PURL": "pkg:apk/alpine/xz@5.2.3-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "5.2.3-r1", "Arch": "x86_64", "SrcName": "xz", @@ -7807,6 +7975,9 @@ { "ID": "xz-libs@5.2.3-r1", "Name": "xz-libs", + "Identifier": { + "PURL": "pkg:apk/alpine/xz-libs@5.2.3-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "5.2.3-r1", "Arch": "x86_64", "SrcName": "xz", @@ -7830,6 +8001,9 @@ { "ID": "zlib@1.2.11-r1", "Name": "zlib", + "Identifier": { + "PURL": "pkg:apk/alpine/zlib@1.2.11-r1?arch=x86_64\u0026distro=3.7.1" + }, "Version": "1.2.11-r1", "Arch": "x86_64", "SrcName": "zlib", diff --git a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden index f1c30482504e..fdd72301280c 100644 --- a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden +++ b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden @@ -6,6 +6,9 @@ { "ID": "actioncable@5.2.3", "Name": "actioncable", + "Identifier": { + "PURL": "pkg:gem/actioncable@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -24,6 +27,9 @@ { "ID": "actionmailer@5.2.3", "Name": "actionmailer", + "Identifier": { + "PURL": "pkg:gem/actionmailer@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -44,6 +50,9 @@ { "ID": "actionpack@5.2.3", "Name": "actionpack", + "Identifier": { + "PURL": "pkg:gem/actionpack@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -65,6 +74,9 @@ { "ID": "actionview@5.2.3", "Name": "actionview", + "Identifier": { + "PURL": "pkg:gem/actionview@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -85,6 +97,9 @@ { "ID": "activejob@5.2.3", "Name": "activejob", + "Identifier": { + "PURL": "pkg:gem/activejob@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -102,6 +117,9 @@ { "ID": "activemodel@5.2.3", "Name": "activemodel", + "Identifier": { + "PURL": "pkg:gem/activemodel@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -118,6 +136,9 @@ { "ID": "activerecord@5.2.3", "Name": "activerecord", + "Identifier": { + "PURL": "pkg:gem/activerecord@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -136,6 +157,9 @@ { "ID": "activestorage@5.2.3", "Name": "activestorage", + "Identifier": { + "PURL": "pkg:gem/activestorage@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -154,6 +178,9 @@ { "ID": "activesupport@5.2.3", "Name": "activesupport", + "Identifier": { + "PURL": "pkg:gem/activesupport@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -173,6 +200,9 @@ { "ID": "arel@9.0.0", "Name": "arel", + "Identifier": { + "PURL": "pkg:gem/arel@9.0.0" + }, "Version": "9.0.0", "Indirect": true, "Layer": {}, @@ -186,6 +216,9 @@ { "ID": "ast@2.4.0", "Name": "ast", + "Identifier": { + "PURL": "pkg:gem/ast@2.4.0" + }, "Version": "2.4.0", "Indirect": true, "Layer": {}, @@ -199,6 +232,9 @@ { "ID": "builder@3.2.3", "Name": "builder", + "Identifier": { + "PURL": "pkg:gem/builder@3.2.3" + }, "Version": "3.2.3", "Indirect": true, "Layer": {}, @@ -212,6 +248,9 @@ { "ID": "coderay@1.1.2", "Name": "coderay", + "Identifier": { + "PURL": "pkg:gem/coderay@1.1.2" + }, "Version": "1.1.2", "Indirect": true, "Layer": {}, @@ -225,6 +264,9 @@ { "ID": "concurrent-ruby@1.1.5", "Name": "concurrent-ruby", + "Identifier": { + "PURL": "pkg:gem/concurrent-ruby@1.1.5" + }, "Version": "1.1.5", "Indirect": true, "Layer": {}, @@ -238,6 +280,9 @@ { "ID": "crass@1.0.4", "Name": "crass", + "Identifier": { + "PURL": "pkg:gem/crass@1.0.4" + }, "Version": "1.0.4", "Indirect": true, "Layer": {}, @@ -251,6 +296,9 @@ { "ID": "dotenv@2.7.2", "Name": "dotenv", + "Identifier": { + "PURL": "pkg:gem/dotenv@2.7.2" + }, "Version": "2.7.2", "Layer": {}, "Locations": [ @@ -263,6 +311,9 @@ { "ID": "erubi@1.8.0", "Name": "erubi", + "Identifier": { + "PURL": "pkg:gem/erubi@1.8.0" + }, "Version": "1.8.0", "Indirect": true, "Layer": {}, @@ -276,6 +327,9 @@ { "ID": "faker@1.9.3", "Name": "faker", + "Identifier": { + "PURL": "pkg:gem/faker@1.9.3" + }, "Version": "1.9.3", "DependsOn": [ "i18n@1.6.0" @@ -291,6 +345,9 @@ { "ID": "globalid@0.4.2", "Name": "globalid", + "Identifier": { + "PURL": "pkg:gem/globalid@0.4.2" + }, "Version": "0.4.2", "Indirect": true, "DependsOn": [ @@ -307,6 +364,9 @@ { "ID": "i18n@1.6.0", "Name": "i18n", + "Identifier": { + "PURL": "pkg:gem/i18n@1.6.0" + }, "Version": "1.6.0", "Indirect": true, "DependsOn": [ @@ -323,6 +383,9 @@ { "ID": "jaro_winkler@1.5.2", "Name": "jaro_winkler", + "Identifier": { + "PURL": "pkg:gem/jaro_winkler@1.5.2" + }, "Version": "1.5.2", "Indirect": true, "Layer": {}, @@ -336,6 +399,9 @@ { "ID": "json@2.2.0", "Name": "json", + "Identifier": { + "PURL": "pkg:gem/json@2.2.0" + }, "Version": "2.2.0", "Layer": {}, "Locations": [ @@ -348,6 +414,9 @@ { "ID": "loofah@2.2.3", "Name": "loofah", + "Identifier": { + "PURL": "pkg:gem/loofah@2.2.3" + }, "Version": "2.2.3", "Indirect": true, "DependsOn": [ @@ -365,6 +434,9 @@ { "ID": "mail@2.7.1", "Name": "mail", + "Identifier": { + "PURL": "pkg:gem/mail@2.7.1" + }, "Version": "2.7.1", "Indirect": true, "DependsOn": [ @@ -381,6 +453,9 @@ { "ID": "marcel@0.3.3", "Name": "marcel", + "Identifier": { + "PURL": "pkg:gem/marcel@0.3.3" + }, "Version": "0.3.3", "Indirect": true, "DependsOn": [ @@ -397,6 +472,9 @@ { "ID": "method_source@0.9.2", "Name": "method_source", + "Identifier": { + "PURL": "pkg:gem/method_source@0.9.2" + }, "Version": "0.9.2", "Indirect": true, "Layer": {}, @@ -410,6 +488,9 @@ { "ID": "mimemagic@0.3.3", "Name": "mimemagic", + "Identifier": { + "PURL": "pkg:gem/mimemagic@0.3.3" + }, "Version": "0.3.3", "Indirect": true, "Layer": {}, @@ -423,6 +504,9 @@ { "ID": "mini_mime@1.0.1", "Name": "mini_mime", + "Identifier": { + "PURL": "pkg:gem/mini_mime@1.0.1" + }, "Version": "1.0.1", "Indirect": true, "Layer": {}, @@ -436,6 +520,9 @@ { "ID": "mini_portile2@2.4.0", "Name": "mini_portile2", + "Identifier": { + "PURL": "pkg:gem/mini_portile2@2.4.0" + }, "Version": "2.4.0", "Indirect": true, "Layer": {}, @@ -449,6 +536,9 @@ { "ID": "minitest@5.11.3", "Name": "minitest", + "Identifier": { + "PURL": "pkg:gem/minitest@5.11.3" + }, "Version": "5.11.3", "Indirect": true, "Layer": {}, @@ -462,6 +552,9 @@ { "ID": "nio4r@2.3.1", "Name": "nio4r", + "Identifier": { + "PURL": "pkg:gem/nio4r@2.3.1" + }, "Version": "2.3.1", "Indirect": true, "Layer": {}, @@ -475,6 +568,9 @@ { "ID": "nokogiri@1.10.3", "Name": "nokogiri", + "Identifier": { + "PURL": "pkg:gem/nokogiri@1.10.3" + }, "Version": "1.10.3", "Indirect": true, "DependsOn": [ @@ -491,6 +587,9 @@ { "ID": "parallel@1.17.0", "Name": "parallel", + "Identifier": { + "PURL": "pkg:gem/parallel@1.17.0" + }, "Version": "1.17.0", "Indirect": true, "Layer": {}, @@ -504,6 +603,9 @@ { "ID": "parser@2.6.3.0", "Name": "parser", + "Identifier": { + "PURL": "pkg:gem/parser@2.6.3.0" + }, "Version": "2.6.3.0", "Indirect": true, "DependsOn": [ @@ -520,6 +622,9 @@ { "ID": "pry@0.12.2", "Name": "pry", + "Identifier": { + "PURL": "pkg:gem/pry@0.12.2" + }, "Version": "0.12.2", "DependsOn": [ "coderay@1.1.2", @@ -536,6 +641,9 @@ { "ID": "psych@3.1.0", "Name": "psych", + "Identifier": { + "PURL": "pkg:gem/psych@3.1.0" + }, "Version": "3.1.0", "Indirect": true, "Layer": {}, @@ -549,6 +657,9 @@ { "ID": "rack@2.0.7", "Name": "rack", + "Identifier": { + "PURL": "pkg:gem/rack@2.0.7" + }, "Version": "2.0.7", "Indirect": true, "Layer": {}, @@ -562,6 +673,9 @@ { "ID": "rack-test@1.1.0", "Name": "rack-test", + "Identifier": { + "PURL": "pkg:gem/rack-test@1.1.0" + }, "Version": "1.1.0", "Indirect": true, "DependsOn": [ @@ -578,6 +692,9 @@ { "ID": "rails@5.2.0", "Name": "rails", + "Identifier": { + "PURL": "pkg:gem/rails@5.2.0" + }, "Version": "5.2.0", "DependsOn": [ "actioncable@5.2.3", @@ -603,6 +720,9 @@ { "ID": "rails-dom-testing@2.0.3", "Name": "rails-dom-testing", + "Identifier": { + "PURL": "pkg:gem/rails-dom-testing@2.0.3" + }, "Version": "2.0.3", "Indirect": true, "DependsOn": [ @@ -620,6 +740,9 @@ { "ID": "rails-html-sanitizer@1.0.3", "Name": "rails-html-sanitizer", + "Identifier": { + "PURL": "pkg:gem/rails-html-sanitizer@1.0.3" + }, "Version": "1.0.3", "Indirect": true, "DependsOn": [ @@ -636,6 +759,9 @@ { "ID": "railties@5.2.3", "Name": "railties", + "Identifier": { + "PURL": "pkg:gem/railties@5.2.3" + }, "Version": "5.2.3", "Indirect": true, "DependsOn": [ @@ -656,6 +782,9 @@ { "ID": "rainbow@3.0.0", "Name": "rainbow", + "Identifier": { + "PURL": "pkg:gem/rainbow@3.0.0" + }, "Version": "3.0.0", "Indirect": true, "Layer": {}, @@ -669,6 +798,9 @@ { "ID": "rake@12.3.2", "Name": "rake", + "Identifier": { + "PURL": "pkg:gem/rake@12.3.2" + }, "Version": "12.3.2", "Indirect": true, "Layer": {}, @@ -682,6 +814,9 @@ { "ID": "rubocop@0.67.2", "Name": "rubocop", + "Identifier": { + "PURL": "pkg:gem/rubocop@0.67.2" + }, "Version": "0.67.2", "DependsOn": [ "jaro_winkler@1.5.2", @@ -703,6 +838,9 @@ { "ID": "ruby-progressbar@1.10.0", "Name": "ruby-progressbar", + "Identifier": { + "PURL": "pkg:gem/ruby-progressbar@1.10.0" + }, "Version": "1.10.0", "Indirect": true, "Layer": {}, @@ -716,6 +854,9 @@ { "ID": "sprockets@3.7.2", "Name": "sprockets", + "Identifier": { + "PURL": "pkg:gem/sprockets@3.7.2" + }, "Version": "3.7.2", "Indirect": true, "DependsOn": [ @@ -733,6 +874,9 @@ { "ID": "sprockets-rails@3.2.1", "Name": "sprockets-rails", + "Identifier": { + "PURL": "pkg:gem/sprockets-rails@3.2.1" + }, "Version": "3.2.1", "Indirect": true, "DependsOn": [ @@ -751,6 +895,9 @@ { "ID": "thor@0.20.3", "Name": "thor", + "Identifier": { + "PURL": "pkg:gem/thor@0.20.3" + }, "Version": "0.20.3", "Indirect": true, "Layer": {}, @@ -764,6 +911,9 @@ { "ID": "thread_safe@0.3.6", "Name": "thread_safe", + "Identifier": { + "PURL": "pkg:gem/thread_safe@0.3.6" + }, "Version": "0.3.6", "Indirect": true, "Layer": {}, @@ -777,6 +927,9 @@ { "ID": "tzinfo@1.2.5", "Name": "tzinfo", + "Identifier": { + "PURL": "pkg:gem/tzinfo@1.2.5" + }, "Version": "1.2.5", "Indirect": true, "DependsOn": [ @@ -793,6 +946,9 @@ { "ID": "unicode-display_width@1.5.0", "Name": "unicode-display_width", + "Identifier": { + "PURL": "pkg:gem/unicode-display_width@1.5.0" + }, "Version": "1.5.0", "Indirect": true, "Layer": {}, @@ -806,6 +962,9 @@ { "ID": "websocket-driver@0.7.0", "Name": "websocket-driver", + "Identifier": { + "PURL": "pkg:gem/websocket-driver@0.7.0" + }, "Version": "0.7.0", "Indirect": true, "DependsOn": [ @@ -822,6 +981,9 @@ { "ID": "websocket-extensions@0.1.3", "Name": "websocket-extensions", + "Identifier": { + "PURL": "pkg:gem/websocket-extensions@0.1.3" + }, "Version": "0.1.3", "Indirect": true, "Layer": {}, @@ -841,6 +1003,9 @@ { "ID": "ammonia@1.9.0", "Name": "ammonia", + "Identifier": { + "PURL": "pkg:cargo/ammonia@1.9.0" + }, "Version": "1.9.0", "DependsOn": [ "html5ever@0.23.0", @@ -861,6 +1026,9 @@ { "ID": "autocfg@0.1.2", "Name": "autocfg", + "Identifier": { + "PURL": "pkg:cargo/autocfg@0.1.2" + }, "Version": "0.1.2", "Layer": {}, "Locations": [ @@ -873,6 +1041,9 @@ { "ID": "bitflags@0.7.0", "Name": "bitflags", + "Identifier": { + "PURL": "pkg:cargo/bitflags@0.7.0" + }, "Version": "0.7.0", "Layer": {}, "Locations": [ @@ -885,6 +1056,9 @@ { "ID": "bitflags@1.0.4", "Name": "bitflags", + "Identifier": { + "PURL": "pkg:cargo/bitflags@1.0.4" + }, "Version": "1.0.4", "Layer": {}, "Locations": [ @@ -897,6 +1071,9 @@ { "ID": "cfg-if@0.1.7", "Name": "cfg-if", + "Identifier": { + "PURL": "pkg:cargo/cfg-if@0.1.7" + }, "Version": "0.1.7", "Layer": {}, "Locations": [ @@ -909,6 +1086,9 @@ { "ID": "cloudabi@0.0.3", "Name": "cloudabi", + "Identifier": { + "PURL": "pkg:cargo/cloudabi@0.0.3" + }, "Version": "0.0.3", "DependsOn": [ "bitflags@1.0.4" @@ -924,6 +1104,9 @@ { "ID": "fuchsia-cprng@0.1.1", "Name": "fuchsia-cprng", + "Identifier": { + "PURL": "pkg:cargo/fuchsia-cprng@0.1.1" + }, "Version": "0.1.1", "Layer": {}, "Locations": [ @@ -936,6 +1119,9 @@ { "ID": "futf@0.1.4", "Name": "futf", + "Identifier": { + "PURL": "pkg:cargo/futf@0.1.4" + }, "Version": "0.1.4", "DependsOn": [ "mac@0.1.1", @@ -952,6 +1138,9 @@ { "ID": "gdi32-sys@0.2.0", "Name": "gdi32-sys", + "Identifier": { + "PURL": "pkg:cargo/gdi32-sys@0.2.0" + }, "Version": "0.2.0", "DependsOn": [ "winapi-build@0.1.1", @@ -968,6 +1157,9 @@ { "ID": "html5ever@0.23.0", "Name": "html5ever", + "Identifier": { + "PURL": "pkg:cargo/html5ever@0.23.0" + }, "Version": "0.23.0", "DependsOn": [ "log@0.4.6", @@ -988,6 +1180,9 @@ { "ID": "idna@0.1.5", "Name": "idna", + "Identifier": { + "PURL": "pkg:cargo/idna@0.1.5" + }, "Version": "0.1.5", "DependsOn": [ "matches@0.1.8", @@ -1005,6 +1200,9 @@ { "ID": "itoa@0.4.4", "Name": "itoa", + "Identifier": { + "PURL": "pkg:cargo/itoa@0.4.4" + }, "Version": "0.4.4", "Layer": {}, "Locations": [ @@ -1017,6 +1215,9 @@ { "ID": "kernel32-sys@0.2.2", "Name": "kernel32-sys", + "Identifier": { + "PURL": "pkg:cargo/kernel32-sys@0.2.2" + }, "Version": "0.2.2", "DependsOn": [ "winapi-build@0.1.1", @@ -1033,6 +1234,9 @@ { "ID": "lazy_static@0.2.11", "Name": "lazy_static", + "Identifier": { + "PURL": "pkg:cargo/lazy_static@0.2.11" + }, "Version": "0.2.11", "Layer": {}, "Locations": [ @@ -1045,6 +1249,9 @@ { "ID": "lazy_static@1.3.0", "Name": "lazy_static", + "Identifier": { + "PURL": "pkg:cargo/lazy_static@1.3.0" + }, "Version": "1.3.0", "Layer": {}, "Locations": [ @@ -1057,6 +1264,9 @@ { "ID": "libc@0.2.54", "Name": "libc", + "Identifier": { + "PURL": "pkg:cargo/libc@0.2.54" + }, "Version": "0.2.54", "Layer": {}, "Locations": [ @@ -1069,6 +1279,9 @@ { "ID": "libressl-pnacl-sys@2.1.6", "Name": "libressl-pnacl-sys", + "Identifier": { + "PURL": "pkg:cargo/libressl-pnacl-sys@2.1.6" + }, "Version": "2.1.6", "DependsOn": [ "pnacl-build-helper@1.4.11" @@ -1084,6 +1297,9 @@ { "ID": "log@0.4.6", "Name": "log", + "Identifier": { + "PURL": "pkg:cargo/log@0.4.6" + }, "Version": "0.4.6", "DependsOn": [ "cfg-if@0.1.7" @@ -1099,6 +1315,9 @@ { "ID": "mac@0.1.1", "Name": "mac", + "Identifier": { + "PURL": "pkg:cargo/mac@0.1.1" + }, "Version": "0.1.1", "Layer": {}, "Locations": [ @@ -1111,6 +1330,9 @@ { "ID": "maplit@1.0.1", "Name": "maplit", + "Identifier": { + "PURL": "pkg:cargo/maplit@1.0.1" + }, "Version": "1.0.1", "Layer": {}, "Locations": [ @@ -1123,6 +1345,9 @@ { "ID": "markup5ever@0.8.1", "Name": "markup5ever", + "Identifier": { + "PURL": "pkg:cargo/markup5ever@0.8.1" + }, "Version": "0.8.1", "DependsOn": [ "log@0.4.6", @@ -1146,6 +1371,9 @@ { "ID": "matches@0.1.8", "Name": "matches", + "Identifier": { + "PURL": "pkg:cargo/matches@0.1.8" + }, "Version": "0.1.8", "Layer": {}, "Locations": [ @@ -1158,6 +1386,9 @@ { "ID": "new_debug_unreachable@1.0.3", "Name": "new_debug_unreachable", + "Identifier": { + "PURL": "pkg:cargo/new_debug_unreachable@1.0.3" + }, "Version": "1.0.3", "Layer": {}, "Locations": [ @@ -1170,6 +1401,9 @@ { "ID": "normal@0.1.0", "Name": "normal", + "Identifier": { + "PURL": "pkg:cargo/normal@0.1.0" + }, "Version": "0.1.0", "DependsOn": [ "ammonia@2.0.0", @@ -1187,6 +1421,9 @@ { "ID": "openssl@0.8.3", "Name": "openssl", + "Identifier": { + "PURL": "pkg:cargo/openssl@0.8.3" + }, "Version": "0.8.3", "DependsOn": [ "bitflags@0.7.0", @@ -1205,6 +1442,9 @@ { "ID": "openssl-sys@0.7.17", "Name": "openssl-sys", + "Identifier": { + "PURL": "pkg:cargo/openssl-sys@0.7.17" + }, "Version": "0.7.17", "DependsOn": [ "gdi32-sys@0.2.0", @@ -1224,6 +1464,9 @@ { "ID": "percent-encoding@1.0.1", "Name": "percent-encoding", + "Identifier": { + "PURL": "pkg:cargo/percent-encoding@1.0.1" + }, "Version": "1.0.1", "Layer": {}, "Locations": [ @@ -1236,6 +1479,9 @@ { "ID": "phf@0.7.24", "Name": "phf", + "Identifier": { + "PURL": "pkg:cargo/phf@0.7.24" + }, "Version": "0.7.24", "DependsOn": [ "phf_shared@0.7.24" @@ -1251,6 +1497,9 @@ { "ID": "phf_codegen@0.7.24", "Name": "phf_codegen", + "Identifier": { + "PURL": "pkg:cargo/phf_codegen@0.7.24" + }, "Version": "0.7.24", "DependsOn": [ "phf_generator@0.7.24", @@ -1267,6 +1516,9 @@ { "ID": "phf_generator@0.7.24", "Name": "phf_generator", + "Identifier": { + "PURL": "pkg:cargo/phf_generator@0.7.24" + }, "Version": "0.7.24", "DependsOn": [ "phf_shared@0.7.24", @@ -1283,6 +1535,9 @@ { "ID": "phf_shared@0.7.24", "Name": "phf_shared", + "Identifier": { + "PURL": "pkg:cargo/phf_shared@0.7.24" + }, "Version": "0.7.24", "DependsOn": [ "siphasher@0.2.3" @@ -1298,6 +1553,9 @@ { "ID": "pkg-config@0.3.14", "Name": "pkg-config", + "Identifier": { + "PURL": "pkg:cargo/pkg-config@0.3.14" + }, "Version": "0.3.14", "Layer": {}, "Locations": [ @@ -1310,6 +1568,9 @@ { "ID": "pnacl-build-helper@1.4.11", "Name": "pnacl-build-helper", + "Identifier": { + "PURL": "pkg:cargo/pnacl-build-helper@1.4.11" + }, "Version": "1.4.11", "DependsOn": [ "tempdir@0.3.7", @@ -1326,6 +1587,9 @@ { "ID": "precomputed-hash@0.1.1", "Name": "precomputed-hash", + "Identifier": { + "PURL": "pkg:cargo/precomputed-hash@0.1.1" + }, "Version": "0.1.1", "Layer": {}, "Locations": [ @@ -1338,6 +1602,9 @@ { "ID": "proc-macro2@0.4.30", "Name": "proc-macro2", + "Identifier": { + "PURL": "pkg:cargo/proc-macro2@0.4.30" + }, "Version": "0.4.30", "DependsOn": [ "unicode-xid@0.1.0" @@ -1353,6 +1620,9 @@ { "ID": "quote@0.6.12", "Name": "quote", + "Identifier": { + "PURL": "pkg:cargo/quote@0.6.12" + }, "Version": "0.6.12", "DependsOn": [ "proc-macro2@0.4.30" @@ -1368,6 +1638,9 @@ { "ID": "rand@0.4.6", "Name": "rand", + "Identifier": { + "PURL": "pkg:cargo/rand@0.4.6" + }, "Version": "0.4.6", "DependsOn": [ "fuchsia-cprng@0.1.1", @@ -1387,6 +1660,9 @@ { "ID": "rand@0.6.5", "Name": "rand", + "Identifier": { + "PURL": "pkg:cargo/rand@0.6.5" + }, "Version": "0.6.5", "DependsOn": [ "autocfg@0.1.2", @@ -1412,6 +1688,9 @@ { "ID": "rand_chacha@0.1.1", "Name": "rand_chacha", + "Identifier": { + "PURL": "pkg:cargo/rand_chacha@0.1.1" + }, "Version": "0.1.1", "DependsOn": [ "autocfg@0.1.2", @@ -1428,6 +1707,9 @@ { "ID": "rand_core@0.3.1", "Name": "rand_core", + "Identifier": { + "PURL": "pkg:cargo/rand_core@0.3.1" + }, "Version": "0.3.1", "DependsOn": [ "rand_core@0.4.0" @@ -1443,6 +1725,9 @@ { "ID": "rand_core@0.4.0", "Name": "rand_core", + "Identifier": { + "PURL": "pkg:cargo/rand_core@0.4.0" + }, "Version": "0.4.0", "Layer": {}, "Locations": [ @@ -1455,6 +1740,9 @@ { "ID": "rand_hc@0.1.0", "Name": "rand_hc", + "Identifier": { + "PURL": "pkg:cargo/rand_hc@0.1.0" + }, "Version": "0.1.0", "DependsOn": [ "rand_core@0.3.1" @@ -1470,6 +1758,9 @@ { "ID": "rand_isaac@0.1.1", "Name": "rand_isaac", + "Identifier": { + "PURL": "pkg:cargo/rand_isaac@0.1.1" + }, "Version": "0.1.1", "DependsOn": [ "rand_core@0.3.1" @@ -1485,6 +1776,9 @@ { "ID": "rand_jitter@0.1.4", "Name": "rand_jitter", + "Identifier": { + "PURL": "pkg:cargo/rand_jitter@0.1.4" + }, "Version": "0.1.4", "DependsOn": [ "libc@0.2.54", @@ -1502,6 +1796,9 @@ { "ID": "rand_os@0.1.3", "Name": "rand_os", + "Identifier": { + "PURL": "pkg:cargo/rand_os@0.1.3" + }, "Version": "0.1.3", "DependsOn": [ "cloudabi@0.0.3", @@ -1522,6 +1819,9 @@ { "ID": "rand_pcg@0.1.2", "Name": "rand_pcg", + "Identifier": { + "PURL": "pkg:cargo/rand_pcg@0.1.2" + }, "Version": "0.1.2", "DependsOn": [ "autocfg@0.1.2", @@ -1538,6 +1838,9 @@ { "ID": "rand_xorshift@0.1.1", "Name": "rand_xorshift", + "Identifier": { + "PURL": "pkg:cargo/rand_xorshift@0.1.1" + }, "Version": "0.1.1", "DependsOn": [ "rand_core@0.3.1" @@ -1553,6 +1856,9 @@ { "ID": "rdrand@0.4.0", "Name": "rdrand", + "Identifier": { + "PURL": "pkg:cargo/rdrand@0.4.0" + }, "Version": "0.4.0", "DependsOn": [ "rand_core@0.3.1" @@ -1568,6 +1874,9 @@ { "ID": "remove_dir_all@0.5.1", "Name": "remove_dir_all", + "Identifier": { + "PURL": "pkg:cargo/remove_dir_all@0.5.1" + }, "Version": "0.5.1", "DependsOn": [ "winapi@0.3.7" @@ -1583,6 +1892,9 @@ { "ID": "ryu@0.2.8", "Name": "ryu", + "Identifier": { + "PURL": "pkg:cargo/ryu@0.2.8" + }, "Version": "0.2.8", "Layer": {}, "Locations": [ @@ -1595,6 +1907,9 @@ { "ID": "same-file@0.1.3", "Name": "same-file", + "Identifier": { + "PURL": "pkg:cargo/same-file@0.1.3" + }, "Version": "0.1.3", "DependsOn": [ "kernel32-sys@0.2.2", @@ -1611,6 +1926,9 @@ { "ID": "serde@1.0.91", "Name": "serde", + "Identifier": { + "PURL": "pkg:cargo/serde@1.0.91" + }, "Version": "1.0.91", "Layer": {}, "Locations": [ @@ -1623,6 +1941,9 @@ { "ID": "serde_derive@1.0.91", "Name": "serde_derive", + "Identifier": { + "PURL": "pkg:cargo/serde_derive@1.0.91" + }, "Version": "1.0.91", "DependsOn": [ "proc-macro2@0.4.30", @@ -1640,6 +1961,9 @@ { "ID": "serde_json@1.0.39", "Name": "serde_json", + "Identifier": { + "PURL": "pkg:cargo/serde_json@1.0.39" + }, "Version": "1.0.39", "DependsOn": [ "itoa@0.4.4", @@ -1657,6 +1981,9 @@ { "ID": "siphasher@0.2.3", "Name": "siphasher", + "Identifier": { + "PURL": "pkg:cargo/siphasher@0.2.3" + }, "Version": "0.2.3", "Layer": {}, "Locations": [ @@ -1669,6 +1996,9 @@ { "ID": "smallvec@0.6.9", "Name": "smallvec", + "Identifier": { + "PURL": "pkg:cargo/smallvec@0.6.9" + }, "Version": "0.6.9", "Layer": {}, "Locations": [ @@ -1681,6 +2011,9 @@ { "ID": "string_cache@0.7.3", "Name": "string_cache", + "Identifier": { + "PURL": "pkg:cargo/string_cache@0.7.3" + }, "Version": "0.7.3", "DependsOn": [ "lazy_static@1.3.0", @@ -1702,6 +2035,9 @@ { "ID": "string_cache_codegen@0.4.2", "Name": "string_cache_codegen", + "Identifier": { + "PURL": "pkg:cargo/string_cache_codegen@0.4.2" + }, "Version": "0.4.2", "DependsOn": [ "phf_generator@0.7.24", @@ -1721,6 +2057,9 @@ { "ID": "string_cache_shared@0.3.0", "Name": "string_cache_shared", + "Identifier": { + "PURL": "pkg:cargo/string_cache_shared@0.3.0" + }, "Version": "0.3.0", "Layer": {}, "Locations": [ @@ -1733,6 +2072,9 @@ { "ID": "syn@0.15.34", "Name": "syn", + "Identifier": { + "PURL": "pkg:cargo/syn@0.15.34" + }, "Version": "0.15.34", "DependsOn": [ "proc-macro2@0.4.30", @@ -1750,6 +2092,9 @@ { "ID": "tempdir@0.3.7", "Name": "tempdir", + "Identifier": { + "PURL": "pkg:cargo/tempdir@0.3.7" + }, "Version": "0.3.7", "DependsOn": [ "rand@0.4.6", @@ -1766,6 +2111,9 @@ { "ID": "tendril@0.4.1", "Name": "tendril", + "Identifier": { + "PURL": "pkg:cargo/tendril@0.4.1" + }, "Version": "0.4.1", "DependsOn": [ "futf@0.1.4", @@ -1783,6 +2131,9 @@ { "ID": "unicode-bidi@0.3.4", "Name": "unicode-bidi", + "Identifier": { + "PURL": "pkg:cargo/unicode-bidi@0.3.4" + }, "Version": "0.3.4", "DependsOn": [ "matches@0.1.8" @@ -1798,6 +2149,9 @@ { "ID": "unicode-normalization@0.1.8", "Name": "unicode-normalization", + "Identifier": { + "PURL": "pkg:cargo/unicode-normalization@0.1.8" + }, "Version": "0.1.8", "DependsOn": [ "smallvec@0.6.9" @@ -1813,6 +2167,9 @@ { "ID": "unicode-xid@0.1.0", "Name": "unicode-xid", + "Identifier": { + "PURL": "pkg:cargo/unicode-xid@0.1.0" + }, "Version": "0.1.0", "Layer": {}, "Locations": [ @@ -1825,6 +2182,9 @@ { "ID": "url@1.7.2", "Name": "url", + "Identifier": { + "PURL": "pkg:cargo/url@1.7.2" + }, "Version": "1.7.2", "DependsOn": [ "idna@0.1.5", @@ -1842,6 +2202,9 @@ { "ID": "user32-sys@0.2.0", "Name": "user32-sys", + "Identifier": { + "PURL": "pkg:cargo/user32-sys@0.2.0" + }, "Version": "0.2.0", "DependsOn": [ "winapi-build@0.1.1", @@ -1858,6 +2221,9 @@ { "ID": "utf-8@0.7.5", "Name": "utf-8", + "Identifier": { + "PURL": "pkg:cargo/utf-8@0.7.5" + }, "Version": "0.7.5", "Layer": {}, "Locations": [ @@ -1870,6 +2236,9 @@ { "ID": "walkdir@1.0.7", "Name": "walkdir", + "Identifier": { + "PURL": "pkg:cargo/walkdir@1.0.7" + }, "Version": "1.0.7", "DependsOn": [ "kernel32-sys@0.2.2", @@ -1887,6 +2256,9 @@ { "ID": "winapi@0.2.8", "Name": "winapi", + "Identifier": { + "PURL": "pkg:cargo/winapi@0.2.8" + }, "Version": "0.2.8", "Layer": {}, "Locations": [ @@ -1899,6 +2271,9 @@ { "ID": "winapi@0.3.7", "Name": "winapi", + "Identifier": { + "PURL": "pkg:cargo/winapi@0.3.7" + }, "Version": "0.3.7", "DependsOn": [ "winapi-i686-pc-windows-gnu@0.4.0", @@ -1915,6 +2290,9 @@ { "ID": "winapi-build@0.1.1", "Name": "winapi-build", + "Identifier": { + "PURL": "pkg:cargo/winapi-build@0.1.1" + }, "Version": "0.1.1", "Layer": {}, "Locations": [ @@ -1927,6 +2305,9 @@ { "ID": "winapi-i686-pc-windows-gnu@0.4.0", "Name": "winapi-i686-pc-windows-gnu", + "Identifier": { + "PURL": "pkg:cargo/winapi-i686-pc-windows-gnu@0.4.0" + }, "Version": "0.4.0", "Layer": {}, "Locations": [ @@ -1939,6 +2320,9 @@ { "ID": "winapi-x86_64-pc-windows-gnu@0.4.0", "Name": "winapi-x86_64-pc-windows-gnu", + "Identifier": { + "PURL": "pkg:cargo/winapi-x86_64-pc-windows-gnu@0.4.0" + }, "Version": "0.4.0", "Layer": {}, "Locations": [ @@ -1957,6 +2341,9 @@ { "ID": "guzzlehttp/guzzle@6.2.0", "Name": "guzzlehttp/guzzle", + "Identifier": { + "PURL": "pkg:composer/guzzlehttp/guzzle@6.2.0" + }, "Version": "6.2.0", "Licenses": [ "MIT" @@ -1976,6 +2363,9 @@ { "ID": "guzzlehttp/promises@v1.3.1", "Name": "guzzlehttp/promises", + "Identifier": { + "PURL": "pkg:composer/guzzlehttp/promises@v1.3.1" + }, "Version": "v1.3.1", "Licenses": [ "MIT" @@ -1991,6 +2381,9 @@ { "ID": "guzzlehttp/psr7@1.5.2", "Name": "guzzlehttp/psr7", + "Identifier": { + "PURL": "pkg:composer/guzzlehttp/psr7@1.5.2" + }, "Version": "1.5.2", "Licenses": [ "MIT" @@ -2010,6 +2403,9 @@ { "ID": "laravel/installer@v2.0.1", "Name": "laravel/installer", + "Identifier": { + "PURL": "pkg:composer/laravel/installer@v2.0.1" + }, "Version": "v2.0.1", "Licenses": [ "MIT" @@ -2031,6 +2427,9 @@ { "ID": "pear/log@1.13.1", "Name": "pear/log", + "Identifier": { + "PURL": "pkg:composer/pear/log@1.13.1" + }, "Version": "1.13.1", "Licenses": [ "MIT" @@ -2049,6 +2448,9 @@ { "ID": "pear/pear_exception@v1.0.0", "Name": "pear/pear_exception", + "Identifier": { + "PURL": "pkg:composer/pear/pear_exception@v1.0.0" + }, "Version": "v1.0.0", "Licenses": [ "BSD-2-Clause" @@ -2064,6 +2466,9 @@ { "ID": "psr/http-message@1.0.1", "Name": "psr/http-message", + "Identifier": { + "PURL": "pkg:composer/psr/http-message@1.0.1" + }, "Version": "1.0.1", "Licenses": [ "MIT" @@ -2079,6 +2484,9 @@ { "ID": "ralouphie/getallheaders@2.0.5", "Name": "ralouphie/getallheaders", + "Identifier": { + "PURL": "pkg:composer/ralouphie/getallheaders@2.0.5" + }, "Version": "2.0.5", "Licenses": [ "MIT" @@ -2094,6 +2502,9 @@ { "ID": "symfony/console@v4.2.7", "Name": "symfony/console", + "Identifier": { + "PURL": "pkg:composer/symfony/console@v4.2.7" + }, "Version": "v4.2.7", "Licenses": [ "MIT" @@ -2113,6 +2524,9 @@ { "ID": "symfony/contracts@v1.0.2", "Name": "symfony/contracts", + "Identifier": { + "PURL": "pkg:composer/symfony/contracts@v1.0.2" + }, "Version": "v1.0.2", "Licenses": [ "MIT" @@ -2128,6 +2542,9 @@ { "ID": "symfony/filesystem@v4.2.7", "Name": "symfony/filesystem", + "Identifier": { + "PURL": "pkg:composer/symfony/filesystem@v4.2.7" + }, "Version": "v4.2.7", "Licenses": [ "MIT" @@ -2146,6 +2563,9 @@ { "ID": "symfony/polyfill-ctype@v1.11.0", "Name": "symfony/polyfill-ctype", + "Identifier": { + "PURL": "pkg:composer/symfony/polyfill-ctype@v1.11.0" + }, "Version": "v1.11.0", "Licenses": [ "MIT" @@ -2161,6 +2581,9 @@ { "ID": "symfony/polyfill-mbstring@v1.11.0", "Name": "symfony/polyfill-mbstring", + "Identifier": { + "PURL": "pkg:composer/symfony/polyfill-mbstring@v1.11.0" + }, "Version": "v1.11.0", "Licenses": [ "MIT" @@ -2176,6 +2599,9 @@ { "ID": "symfony/process@v4.2.7", "Name": "symfony/process", + "Identifier": { + "PURL": "pkg:composer/symfony/process@v4.2.7" + }, "Version": "v4.2.7", "Licenses": [ "MIT" @@ -2197,6 +2623,9 @@ { "ID": "asap@2.0.6", "Name": "asap", + "Identifier": { + "PURL": "pkg:npm/asap@2.0.6" + }, "Version": "2.0.6", "Indirect": true, "Layer": {}, @@ -2210,6 +2639,9 @@ { "ID": "jquery@3.3.9", "Name": "jquery", + "Identifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, "Version": "3.3.9", "Indirect": true, "Layer": {}, @@ -2223,6 +2655,9 @@ { "ID": "js-tokens@4.0.0", "Name": "js-tokens", + "Identifier": { + "PURL": "pkg:npm/js-tokens@4.0.0" + }, "Version": "4.0.0", "Indirect": true, "Layer": {}, @@ -2236,6 +2671,9 @@ { "ID": "lodash@4.17.4", "Name": "lodash", + "Identifier": { + "PURL": "pkg:npm/lodash@4.17.4" + }, "Version": "4.17.4", "Indirect": true, "Layer": {}, @@ -2249,6 +2687,9 @@ { "ID": "loose-envify@1.4.0", "Name": "loose-envify", + "Identifier": { + "PURL": "pkg:npm/loose-envify@1.4.0" + }, "Version": "1.4.0", "Indirect": true, "DependsOn": [ @@ -2265,6 +2706,9 @@ { "ID": "object-assign@4.1.1", "Name": "object-assign", + "Identifier": { + "PURL": "pkg:npm/object-assign@4.1.1" + }, "Version": "4.1.1", "Indirect": true, "Layer": {}, @@ -2278,6 +2722,9 @@ { "ID": "promise@8.0.3", "Name": "promise", + "Identifier": { + "PURL": "pkg:npm/promise@8.0.3" + }, "Version": "8.0.3", "Indirect": true, "DependsOn": [ @@ -2294,6 +2741,9 @@ { "ID": "prop-types@15.7.2", "Name": "prop-types", + "Identifier": { + "PURL": "pkg:npm/prop-types@15.7.2" + }, "Version": "15.7.2", "Indirect": true, "DependsOn": [ @@ -2312,6 +2762,9 @@ { "ID": "react@16.8.6", "Name": "react", + "Identifier": { + "PURL": "pkg:npm/react@16.8.6" + }, "Version": "16.8.6", "Indirect": true, "DependsOn": [ @@ -2331,6 +2784,9 @@ { "ID": "react-is@16.8.6", "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@16.8.6" + }, "Version": "16.8.6", "Indirect": true, "Layer": {}, @@ -2344,6 +2800,9 @@ { "ID": "redux@4.0.1", "Name": "redux", + "Identifier": { + "PURL": "pkg:npm/redux@4.0.1" + }, "Version": "4.0.1", "Indirect": true, "DependsOn": [ @@ -2361,6 +2820,9 @@ { "ID": "scheduler@0.13.6", "Name": "scheduler", + "Identifier": { + "PURL": "pkg:npm/scheduler@0.13.6" + }, "Version": "0.13.6", "Indirect": true, "DependsOn": [ @@ -2378,6 +2840,9 @@ { "ID": "symbol-observable@1.2.0", "Name": "symbol-observable", + "Identifier": { + "PURL": "pkg:npm/symbol-observable@1.2.0" + }, "Version": "1.2.0", "Indirect": true, "Layer": {}, @@ -2396,6 +2861,9 @@ "Libraries": [ { "Name": "amqp", + "Identifier": { + "PURL": "pkg:pypi/amqp@2.4.2" + }, "Version": "2.4.2", "Layer": {}, "Locations": [ @@ -2407,6 +2875,9 @@ }, { "Name": "autopep8", + "Identifier": { + "PURL": "pkg:pypi/autopep8@1.4.3" + }, "Version": "1.4.3", "Layer": {}, "Locations": [ @@ -2418,6 +2889,9 @@ }, { "Name": "babel", + "Identifier": { + "PURL": "pkg:pypi/babel@2.6.0" + }, "Version": "2.6.0", "Layer": {}, "Locations": [ @@ -2429,6 +2903,9 @@ }, { "Name": "billiard", + "Identifier": { + "PURL": "pkg:pypi/billiard@3.6.0.0" + }, "Version": "3.6.0.0", "Layer": {}, "Locations": [ @@ -2440,6 +2917,9 @@ }, { "Name": "boto3", + "Identifier": { + "PURL": "pkg:pypi/boto3@1.9.130" + }, "Version": "1.9.130", "Layer": {}, "Locations": [ @@ -2451,6 +2931,9 @@ }, { "Name": "botocore", + "Identifier": { + "PURL": "pkg:pypi/botocore@1.12.130" + }, "Version": "1.12.130", "Layer": {}, "Locations": [ @@ -2462,6 +2945,9 @@ }, { "Name": "celery", + "Identifier": { + "PURL": "pkg:pypi/celery@4.3.0" + }, "Version": "4.3.0", "Layer": {}, "Locations": [ @@ -2473,6 +2959,9 @@ }, { "Name": "certifi", + "Identifier": { + "PURL": "pkg:pypi/certifi@2019.3.9" + }, "Version": "2019.3.9", "Layer": {}, "Locations": [ @@ -2484,6 +2973,9 @@ }, { "Name": "chardet", + "Identifier": { + "PURL": "pkg:pypi/chardet@3.0.4" + }, "Version": "3.0.4", "Layer": {}, "Locations": [ @@ -2495,6 +2987,9 @@ }, { "Name": "decorator", + "Identifier": { + "PURL": "pkg:pypi/decorator@4.4.0" + }, "Version": "4.4.0", "Layer": {}, "Locations": [ @@ -2506,6 +3001,9 @@ }, { "Name": "django", + "Identifier": { + "PURL": "pkg:pypi/django@2.0.9" + }, "Version": "2.0.9", "Layer": {}, "Locations": [ @@ -2517,6 +3015,9 @@ }, { "Name": "django-celery-beat", + "Identifier": { + "PURL": "pkg:pypi/django-celery-beat@1.4.0" + }, "Version": "1.4.0", "Layer": {}, "Locations": [ @@ -2528,6 +3029,9 @@ }, { "Name": "django-cors-headers", + "Identifier": { + "PURL": "pkg:pypi/django-cors-headers@2.5.2" + }, "Version": "2.5.2", "Layer": {}, "Locations": [ @@ -2539,6 +3043,9 @@ }, { "Name": "django-extensions", + "Identifier": { + "PURL": "pkg:pypi/django-extensions@2.1.6" + }, "Version": "2.1.6", "Layer": {}, "Locations": [ @@ -2550,6 +3057,9 @@ }, { "Name": "django-postgres-extra", + "Identifier": { + "PURL": "pkg:pypi/django-postgres-extra" + }, "Layer": {}, "Locations": [ { @@ -2560,6 +3070,9 @@ }, { "Name": "django-redis-cache", + "Identifier": { + "PURL": "pkg:pypi/django-redis-cache@2.0.0" + }, "Version": "2.0.0", "Layer": {}, "Locations": [ @@ -2571,6 +3084,9 @@ }, { "Name": "django-silk", + "Identifier": { + "PURL": "pkg:pypi/django-silk@3.0.1" + }, "Version": "3.0.1", "Layer": {}, "Locations": [ @@ -2582,6 +3098,9 @@ }, { "Name": "django-timezone-field", + "Identifier": { + "PURL": "pkg:pypi/django-timezone-field@3.0" + }, "Version": "3.0", "Layer": {}, "Locations": [ @@ -2593,6 +3112,9 @@ }, { "Name": "djangorestframework", + "Identifier": { + "PURL": "pkg:pypi/djangorestframework@3.9.2" + }, "Version": "3.9.2", "Layer": {}, "Locations": [ @@ -2604,6 +3126,9 @@ }, { "Name": "djangorestframework-jwt", + "Identifier": { + "PURL": "pkg:pypi/djangorestframework-jwt@1.11.0" + }, "Version": "1.11.0", "Layer": {}, "Locations": [ @@ -2615,6 +3140,9 @@ }, { "Name": "docutils", + "Identifier": { + "PURL": "pkg:pypi/docutils@0.14" + }, "Version": "0.14", "Layer": {}, "Locations": [ @@ -2626,6 +3154,9 @@ }, { "Name": "flower", + "Identifier": { + "PURL": "pkg:pypi/flower@0.9.3" + }, "Version": "0.9.3", "Layer": {}, "Locations": [ @@ -2637,6 +3168,9 @@ }, { "Name": "gprof2dot", + "Identifier": { + "PURL": "pkg:pypi/gprof2dot@2016.10.13" + }, "Version": "2016.10.13", "Layer": {}, "Locations": [ @@ -2648,6 +3182,9 @@ }, { "Name": "gunicorn", + "Identifier": { + "PURL": "pkg:pypi/gunicorn@19.9.0" + }, "Version": "19.9.0", "Layer": {}, "Locations": [ @@ -2659,6 +3196,9 @@ }, { "Name": "hiredis", + "Identifier": { + "PURL": "pkg:pypi/hiredis@1.0.0" + }, "Version": "1.0.0", "Layer": {}, "Locations": [ @@ -2670,6 +3210,9 @@ }, { "Name": "httplib2", + "Identifier": { + "PURL": "pkg:pypi/httplib2@0.12.1" + }, "Version": "0.12.1", "Layer": {}, "Locations": [ @@ -2681,6 +3224,9 @@ }, { "Name": "idna", + "Identifier": { + "PURL": "pkg:pypi/idna@2.8" + }, "Version": "2.8", "Layer": {}, "Locations": [ @@ -2692,6 +3238,9 @@ }, { "Name": "jinja2", + "Identifier": { + "PURL": "pkg:pypi/jinja2@2.10.1" + }, "Version": "2.10.1", "Layer": {}, "Locations": [ @@ -2703,6 +3252,9 @@ }, { "Name": "jmespath", + "Identifier": { + "PURL": "pkg:pypi/jmespath@0.9.4" + }, "Version": "0.9.4", "Layer": {}, "Locations": [ @@ -2714,6 +3266,9 @@ }, { "Name": "kombu", + "Identifier": { + "PURL": "pkg:pypi/kombu@4.5.0" + }, "Version": "4.5.0", "Layer": {}, "Locations": [ @@ -2725,6 +3280,9 @@ }, { "Name": "markupsafe", + "Identifier": { + "PURL": "pkg:pypi/markupsafe@1.1.1" + }, "Version": "1.1.1", "Layer": {}, "Locations": [ @@ -2736,6 +3294,9 @@ }, { "Name": "oauth2", + "Identifier": { + "PURL": "pkg:pypi/oauth2@1.9.0.post1" + }, "Version": "1.9.0.post1", "Layer": {}, "Locations": [ @@ -2747,6 +3308,9 @@ }, { "Name": "psycopg2-binary", + "Identifier": { + "PURL": "pkg:pypi/psycopg2-binary@2.8.1" + }, "Version": "2.8.1", "Layer": {}, "Locations": [ @@ -2758,6 +3322,9 @@ }, { "Name": "py", + "Identifier": { + "PURL": "pkg:pypi/py@1.8.0" + }, "Version": "1.8.0", "Layer": {}, "Locations": [ @@ -2769,6 +3336,9 @@ }, { "Name": "pycodestyle", + "Identifier": { + "PURL": "pkg:pypi/pycodestyle@2.5.0" + }, "Version": "2.5.0", "Layer": {}, "Locations": [ @@ -2780,6 +3350,9 @@ }, { "Name": "pycurl", + "Identifier": { + "PURL": "pkg:pypi/pycurl@7.43.0.2" + }, "Version": "7.43.0.2", "Layer": {}, "Locations": [ @@ -2791,6 +3364,9 @@ }, { "Name": "pygments", + "Identifier": { + "PURL": "pkg:pypi/pygments@2.3.1" + }, "Version": "2.3.1", "Layer": {}, "Locations": [ @@ -2802,6 +3378,9 @@ }, { "Name": "pyjwt", + "Identifier": { + "PURL": "pkg:pypi/pyjwt@1.7.1" + }, "Version": "1.7.1", "Layer": {}, "Locations": [ @@ -2813,6 +3392,9 @@ }, { "Name": "python-crontab", + "Identifier": { + "PURL": "pkg:pypi/python-crontab@2.3.6" + }, "Version": "2.3.6", "Layer": {}, "Locations": [ @@ -2824,6 +3406,9 @@ }, { "Name": "python-dateutil", + "Identifier": { + "PURL": "pkg:pypi/python-dateutil@2.8.0" + }, "Version": "2.8.0", "Layer": {}, "Locations": [ @@ -2835,6 +3420,9 @@ }, { "Name": "python-http-client", + "Identifier": { + "PURL": "pkg:pypi/python-http-client@3.1.0" + }, "Version": "3.1.0", "Layer": {}, "Locations": [ @@ -2846,6 +3434,9 @@ }, { "Name": "pytz", + "Identifier": { + "PURL": "pkg:pypi/pytz@2019.1" + }, "Version": "2019.1", "Layer": {}, "Locations": [ @@ -2857,6 +3448,9 @@ }, { "Name": "pyyaml", + "Identifier": { + "PURL": "pkg:pypi/pyyaml@5.1" + }, "Version": "5.1", "Layer": {}, "Locations": [ @@ -2868,6 +3462,9 @@ }, { "Name": "redis", + "Identifier": { + "PURL": "pkg:pypi/redis@3.2.1" + }, "Version": "3.2.1", "Layer": {}, "Locations": [ @@ -2879,6 +3476,9 @@ }, { "Name": "requests", + "Identifier": { + "PURL": "pkg:pypi/requests@2.21.0" + }, "Version": "2.21.0", "Layer": {}, "Locations": [ @@ -2890,6 +3490,9 @@ }, { "Name": "retry", + "Identifier": { + "PURL": "pkg:pypi/retry@0.9.2" + }, "Version": "0.9.2", "Layer": {}, "Locations": [ @@ -2901,6 +3504,9 @@ }, { "Name": "s3transfer", + "Identifier": { + "PURL": "pkg:pypi/s3transfer@0.2.0" + }, "Version": "0.2.0", "Layer": {}, "Locations": [ @@ -2912,6 +3518,9 @@ }, { "Name": "sendgrid", + "Identifier": { + "PURL": "pkg:pypi/sendgrid@6.0.4" + }, "Version": "6.0.4", "Layer": {}, "Locations": [ @@ -2923,6 +3532,9 @@ }, { "Name": "sentry-sdk", + "Identifier": { + "PURL": "pkg:pypi/sentry-sdk@0.7.10" + }, "Version": "0.7.10", "Layer": {}, "Locations": [ @@ -2934,6 +3546,9 @@ }, { "Name": "six", + "Identifier": { + "PURL": "pkg:pypi/six@1.12.0" + }, "Version": "1.12.0", "Layer": {}, "Locations": [ @@ -2945,6 +3560,9 @@ }, { "Name": "sqlparse", + "Identifier": { + "PURL": "pkg:pypi/sqlparse@0.3.0" + }, "Version": "0.3.0", "Layer": {}, "Locations": [ @@ -2956,6 +3574,9 @@ }, { "Name": "tornado", + "Identifier": { + "PURL": "pkg:pypi/tornado@5.1.1" + }, "Version": "5.1.1", "Layer": {}, "Locations": [ @@ -2967,6 +3588,9 @@ }, { "Name": "urllib3", + "Identifier": { + "PURL": "pkg:pypi/urllib3@1.24.1" + }, "Version": "1.24.1", "Layer": {}, "Locations": [ @@ -2978,6 +3602,9 @@ }, { "Name": "vine", + "Identifier": { + "PURL": "pkg:pypi/vine@1.3.0" + }, "Version": "1.3.0", "Layer": {}, "Locations": [ @@ -2989,6 +3616,9 @@ }, { "Name": "xmltodict", + "Identifier": { + "PURL": "pkg:pypi/xmltodict@0.12.0" + }, "Version": "0.12.0", "Layer": {}, "Locations": [ diff --git a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedpkgsfromcmds.golden b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedpkgsfromcmds.golden index 2f2b554c38ee..818db8d5c29d 100644 --- a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedpkgsfromcmds.golden +++ b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedpkgsfromcmds.golden @@ -1,998 +1,500 @@ [ { - "Name": "m4", - "Version": "1.4.18-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" - }, - { - "Name": "binutils-libs", - "Version": "2.30-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "acl", + "Identifier": {}, + "Version": "2.2.52-r3", + "Layer": {} }, { - "Name": "ncurses-dev", - "Version": "6.0_p20171125-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "apr", + "Identifier": {}, + "Version": "1.6.3-r0", + "Layer": {} }, { - "Name": "python2", - "Version": "2.7.15-r2", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "apr-util", + "Identifier": {}, + "Version": "1.6.1-r1", + "Layer": {} }, { - "Name": "libressl2.6-libcrypto", - "Version": "2.6.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "attr", + "Identifier": {}, + "Version": "2.4.47-r6", + "Layer": {} }, { - "Name": "cyrus-sasl", - "Version": "2.1.26-r11", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "autoconf", + "Identifier": {}, + "Version": "2.69-r0", + "Layer": {} }, { - "Name": "libgcc", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "bash", + "Identifier": {}, + "Version": "4.4.19-r1", + "Layer": {} }, { - "Name": "dpkg-dev", - "Version": "1.18.24-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "binutils", + "Identifier": {}, + "Version": "2.30-r1", + "Layer": {} }, { - "Name": "mpc1", - "Version": "1.0.3-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "binutils-libs", + "Identifier": {}, + "Version": "2.30-r1", + "Layer": {} }, { - "Name": "dpkg", - "Version": "1.18.24-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "busybox", + "Identifier": {}, + "Version": "1.27.2-r11", + "Layer": {} }, { - "Name": "libacl", - "Version": "2.2.52-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "bzip2", + "Identifier": {}, + "Version": "1.0.6-r6", + "Layer": {} }, { - "Name": "musl-dev", - "Version": "1.1.18-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ca-certificates", + "Identifier": {}, + "Version": "20171114-r0", + "Layer": {} }, { - "Name": "ncurses-terminfo", - "Version": "6.0_p20171125-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "coreutils", + "Identifier": {}, + "Version": "8.28-r0", + "Layer": {} }, { - "Name": "libunistring", - "Version": "0.9.7-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "cyrus-sasl", + "Identifier": {}, + "Version": "2.1.26-r11", + "Layer": {} }, { "Name": "db", + "Identifier": {}, "Version": "5.3.28-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" - }, - { - "Name": "libressl-dev", - "Version": "2.6.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Layer": {} }, { - "Name": "npth", - "Version": "1.5-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "dpkg", + "Identifier": {}, + "Version": "1.18.24-r0", + "Layer": {} }, { - "Name": "pcre2", - "Version": "10.30-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "dpkg-dev", + "Identifier": {}, + "Version": "1.18.24-r0", + "Layer": {} }, { - "Name": "zlib", - "Version": "1.2.11-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "expat", + "Identifier": {}, + "Version": "2.2.5-r0", + "Layer": {} }, { - "Name": "busybox", - "Version": "1.27.2-r11", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "file", + "Identifier": {}, + "Version": "5.32-r0", + "Layer": {} }, { - "Name": "nettle", - "Version": "3.3-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "g++", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "libtasn1", - "Version": "4.12-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "gcc", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "libstdc++", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "gdbm", + "Identifier": {}, + "Version": "1.13-r1", + "Layer": {} }, { - "Name": "libressl2.6-libssl", - "Version": "2.6.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "gmp", + "Identifier": {}, + "Version": "6.1.2-r1", + "Layer": {} }, { - "Name": "xz", - "Version": "5.2.3-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "gnupg", + "Identifier": {}, + "Version": "2.2.3-r1", + "Layer": {} }, { "Name": "gnutls", + "Identifier": {}, "Version": "3.6.1-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" - }, - { - "Name": "file", - "Version": "5.32-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Layer": {} }, { - "Name": "libffi", - "Version": "3.2.1-r4", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "isl", + "Identifier": {}, + "Version": "0.18-r0", + "Layer": {} }, { - "Name": "ncurses-libs", - "Version": "6.0_p20171125-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libacl", + "Identifier": {}, + "Version": "2.2.52-r3", + "Layer": {} }, { - "Name": "gdbm", - "Version": "1.13-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libassuan", + "Identifier": {}, + "Version": "2.4.4-r0", + "Layer": {} }, { - "Name": "libgcrypt", - "Version": "1.8.3-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libatomic", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "g++", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libattr", + "Identifier": {}, + "Version": "2.4.47-r6", + "Layer": {} }, { - "Name": "mercurial", - "Version": "4.5.2-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libbz2", + "Identifier": {}, + "Version": "1.0.6-r6", + "Layer": {} }, { - "Name": "zlib-dev", - "Version": "1.2.11-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libc-dev", + "Identifier": {}, + "Version": "0.7.1-r0", + "Layer": {} }, { - "Name": "pkgconf", - "Version": "1.3.10-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libcap", + "Identifier": {}, + "Version": "2.25-r1", + "Layer": {} }, { - "Name": "isl", - "Version": "0.18-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libedit", + "Identifier": {}, + "Version": "20170329.3.1-r3", + "Layer": {} }, { - "Name": "libmagic", - "Version": "5.32-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libedit-dev", + "Identifier": {}, + "Version": "20170329.3.1-r3", + "Layer": {} }, { - "Name": "xz-libs", - "Version": "5.2.3-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libffi", + "Identifier": {}, + "Version": "3.2.1-r4", + "Layer": {} }, { - "Name": "ncurses", - "Version": "6.0_p20171125-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libgcc", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "ncurses-terminfo-base", - "Version": "6.0_p20171125-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libgcrypt", + "Identifier": {}, + "Version": "1.8.3-r0", + "Layer": {} }, { - "Name": "libassuan", - "Version": "2.4.4-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libgomp", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "subversion-libs", - "Version": "1.9.7-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libgpg-error", + "Identifier": {}, + "Version": "1.27-r1", + "Layer": {} }, { - "Name": "libressl2.6-libtls", - "Version": "2.6.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libksba", + "Identifier": {}, + "Version": "1.3.5-r0", + "Layer": {} }, { "Name": "libldap", + "Identifier": {}, "Version": "2.4.45-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Layer": {} }, { - "Name": "gmp", - "Version": "6.1.2-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libmagic", + "Identifier": {}, + "Version": "5.32-r0", + "Layer": {} }, { - "Name": "libbz2", - "Version": "1.0.6-r6", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libressl", + "Identifier": {}, + "Version": "2.6.5-r0", + "Layer": {} }, { - "Name": "libc-dev", - "Version": "0.7.1-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libressl-dev", + "Identifier": {}, + "Version": "2.6.5-r0", + "Layer": {} }, { - "Name": "binutils", - "Version": "2.30-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libressl2.6-libcrypto", + "Identifier": {}, + "Version": "2.6.5-r0", + "Layer": {} }, { - "Name": "libsodium-dev", - "Version": "1.0.15-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libressl2.6-libssl", + "Identifier": {}, + "Version": "2.6.5-r0", + "Layer": {} }, { - "Name": "musl", - "Version": "1.1.18-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libressl2.6-libtls", + "Identifier": {}, + "Version": "2.6.5-r0", + "Layer": {} }, { - "Name": "pinentry", - "Version": "1.0.0-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libsasl", + "Identifier": {}, + "Version": "2.1.26-r11", + "Layer": {} }, { - "Name": "openldap", - "Version": "2.4.45-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libsodium", + "Identifier": {}, + "Version": "1.0.15-r0", + "Layer": {} }, { - "Name": "libedit-dev", - "Version": "20170329.3.1-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libsodium-dev", + "Identifier": {}, + "Version": "1.0.15-r0", + "Layer": {} }, { - "Name": "bash", - "Version": "4.4.19-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libstdc++", + "Identifier": {}, + "Version": "6.4.0-r5", + "Layer": {} }, { - "Name": "apr", - "Version": "1.6.3-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libtasn1", + "Identifier": {}, + "Version": "4.12-r3", + "Layer": {} }, { - "Name": "ca-certificates", - "Version": "20171114-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "libunistring", + "Identifier": {}, + "Version": "0.9.7-r0", + "Layer": {} }, { - "Name": "libcap", - "Version": "2.25-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "m4", + "Identifier": {}, + "Version": "1.4.18-r0", + "Layer": {} }, { - "Name": "libedit", - "Version": "20170329.3.1-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "make", + "Identifier": {}, + "Version": "4.2.1-r0", + "Layer": {} }, { - "Name": "acl", - "Version": "2.2.52-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "mercurial", + "Identifier": {}, + "Version": "4.5.2-r0", + "Layer": {} }, { - "Name": "libsasl", - "Version": "2.1.26-r11", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "mpc1", + "Identifier": {}, + "Version": "1.0.3-r1", + "Layer": {} }, { - "Name": "gnupg", - "Version": "2.2.3-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "mpfr3", + "Identifier": {}, + "Version": "3.1.5-r1", + "Layer": {} }, { - "Name": "readline", - "Version": "7.0.003-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "musl", + "Identifier": {}, + "Version": "1.1.18-r3", + "Layer": {} }, { - "Name": "apr-util", - "Version": "1.6.1-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "musl-dev", + "Identifier": {}, + "Version": "1.1.18-r3", + "Layer": {} }, { - "Name": "patch", - "Version": "2.7.5-r2", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ncurses", + "Identifier": {}, + "Version": "6.0_p20171125-r1", + "Layer": {} }, { - "Name": "libsodium", - "Version": "1.0.15-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ncurses-dev", + "Identifier": {}, + "Version": "6.0_p20171125-r1", + "Layer": {} }, { - "Name": "mpfr3", - "Version": "3.1.5-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ncurses-libs", + "Identifier": {}, + "Version": "6.0_p20171125-r1", + "Layer": {} }, { - "Name": "libattr", - "Version": "2.4.47-r6", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ncurses-terminfo", + "Identifier": {}, + "Version": "6.0_p20171125-r1", + "Layer": {} }, { - "Name": "attr", - "Version": "2.4.47-r6", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "ncurses-terminfo-base", + "Identifier": {}, + "Version": "6.0_p20171125-r1", + "Layer": {} }, { - "Name": "make", - "Version": "4.2.1-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "nettle", + "Identifier": {}, + "Version": "3.3-r0", + "Layer": {} }, { - "Name": "serf", - "Version": "1.3.9-r3", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "npth", + "Identifier": {}, + "Version": "1.5-r1", + "Layer": {} }, { - "Name": "libressl", - "Version": "2.6.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "openldap", + "Identifier": {}, + "Version": "2.4.45-r3", + "Layer": {} }, { - "Name": "libksba", - "Version": "1.3.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "p11-kit", + "Identifier": {}, + "Version": "0.23.2-r2", + "Layer": {} }, { - "Name": "bzip2", - "Version": "1.0.6-r6", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "patch", + "Identifier": {}, + "Version": "2.7.5-r2", + "Layer": {} }, { - "Name": "libgomp", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "pcre2", + "Identifier": {}, + "Version": "10.30-r0", + "Layer": {} }, { - "Name": "libatomic", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "pinentry", + "Identifier": {}, + "Version": "1.0.0-r0", + "Layer": {} + }, + { + "Name": "pkgconf", + "Identifier": {}, + "Version": "1.3.10-r0", + "Layer": {} + }, + { + "Name": "python2", + "Identifier": {}, + "Version": "2.7.15-r2", + "Layer": {} }, { "Name": "re2c", + "Identifier": {}, "Version": "1.0.2-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Layer": {} }, { - "Name": "coreutils", - "Version": "8.28-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "readline", + "Identifier": {}, + "Version": "7.0.003-r0", + "Layer": {} }, { - "Name": "expat", - "Version": "2.2.5-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "serf", + "Identifier": {}, + "Version": "1.3.9-r3", + "Layer": {} }, { - "Name": "libgpg-error", - "Version": "1.27-r1", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "subversion", + "Identifier": {}, + "Version": "1.9.7-r0", + "Layer": {} }, { - "Name": "p11-kit", - "Version": "0.23.2-r2", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "subversion-libs", + "Identifier": {}, + "Version": "1.9.7-r0", + "Layer": {} }, { - "Name": "gcc", - "Version": "6.4.0-r5", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "xz", + "Identifier": {}, + "Version": "5.2.3-r1", + "Layer": {} }, { - "Name": "autoconf", - "Version": "2.69-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "xz-libs", + "Identifier": {}, + "Version": "5.2.3-r1", + "Layer": {} }, { - "Name": "subversion", - "Version": "1.9.7-r0", - "Release": "", - "Epoch": 0, - "Arch": "", - "SrcName": "", - "SrcVersion": "", - "SrcRelease": "", - "SrcEpoch":0, - "LayerID":"" + "Name": "zlib", + "Identifier": {}, + "Version": "1.2.11-r1", + "Layer": {} + }, + { + "Name": "zlib-dev", + "Identifier": {}, + "Version": "1.2.11-r1", + "Layer": {} } ] \ No newline at end of file diff --git a/pkg/fanal/types/artifact.go b/pkg/fanal/types/artifact.go index 7db2cdbf1949..a6d9e5372a95 100644 --- a/pkg/fanal/types/artifact.go +++ b/pkg/fanal/types/artifact.go @@ -62,25 +62,32 @@ type Layer struct { } type Package struct { - ID string `json:",omitempty"` - Name string `json:",omitempty"` - Version string `json:",omitempty"` - Release string `json:",omitempty"` - Epoch int `json:",omitempty"` - Arch string `json:",omitempty"` - Dev bool `json:",omitempty"` - SrcName string `json:",omitempty"` - SrcVersion string `json:",omitempty"` - SrcRelease string `json:",omitempty"` - SrcEpoch int `json:",omitempty"` - Licenses []string `json:",omitempty"` - Maintainer string `json:",omitempty"` + ID string `json:",omitempty"` + Name string `json:",omitempty"` + Identifier PkgIdentifier `json:",omitempty"` + Version string `json:",omitempty"` + Release string `json:",omitempty"` + Epoch int `json:",omitempty"` + Arch string `json:",omitempty"` + Dev bool `json:",omitempty"` + SrcName string `json:",omitempty"` + SrcVersion string `json:",omitempty"` + SrcRelease string `json:",omitempty"` + SrcEpoch int `json:",omitempty"` + Licenses []string `json:",omitempty"` + Maintainer string `json:",omitempty"` Modularitylabel string `json:",omitempty"` // only for Red Hat based distributions BuildInfo *BuildInfo `json:",omitempty"` // only for Red Hat + Indirect bool `json:",omitempty"` // this package is direct dependency of the project or not - Ref string `json:",omitempty"` // identifier which can be used to reference the component elsewhere - Indirect bool `json:",omitempty"` // this package is direct dependency of the project or not + // TO BE DEPRECATED - use Identifier instead + // Only used when scanning SBOM and contains the reference ID used in it. + // It could be PURL, UUID, etc. + // e.g. + // - pkg:npm/acme/component@1.0.0 + // - b2a46a4b-8367-4bae-9820-95557cfe03a8 + Ref string `json:",omitempty"` // Dependencies of this package // Note: it may have interdependencies, which may lead to infinite loops. @@ -101,6 +108,16 @@ type Package struct { InstalledFiles []string `json:",omitempty"` } +// PkgIdentifier represents a software identifiers in one of more of the supported formats. +type PkgIdentifier struct { + // PURL is a package URL + PURL *PackageURL `json:",omitempty"` +} + +func (id *PkgIdentifier) Empty() bool { + return id.PURL == nil +} + type Location struct { StartLine int `json:",omitempty"` EndLine int `json:",omitempty"` diff --git a/pkg/fanal/types/handler.go b/pkg/fanal/types/handler.go index 7d60d1d68dd0..d53847c896c4 100644 --- a/pkg/fanal/types/handler.go +++ b/pkg/fanal/types/handler.go @@ -9,6 +9,5 @@ const ( // SystemFileFilteringPostHandlerPriority should be higher than other handlers. // Otherwise, other handlers need to process unnecessary files. SystemFileFilteringPostHandlerPriority = 100 - - UnpackagedPostHandlerPriority = 50 + UnpackagedPostHandlerPriority = 50 ) diff --git a/pkg/fanal/types/purl.go b/pkg/fanal/types/purl.go new file mode 100644 index 000000000000..53ad1cbdc0ec --- /dev/null +++ b/pkg/fanal/types/purl.go @@ -0,0 +1,78 @@ +package types + +import ( + "encoding/json" + + "github.com/package-url/packageurl-go" + "golang.org/x/xerrors" +) + +type PackageURL struct { + packageurl.PackageURL + FilePath string +} + +func (p *PackageURL) BOMRef() string { + // 'bom-ref' must be unique within BOM, but PURLs may conflict + // when the same packages are installed in an artifact. + // In that case, we prefer to make PURLs unique by adding file paths, + // rather than using UUIDs, even if it is not PURL technically. + // ref. https://cyclonedx.org/use-cases/#dependency-graph + purl := p.PackageURL // so that it will not override the qualifiers below + if p.FilePath != "" { + purl.Qualifiers = append(purl.Qualifiers, + packageurl.Qualifier{ + Key: "file_path", + Value: p.FilePath, + }, + ) + } + return purl.String() +} + +func (p *PackageURL) MarshalJSON() ([]byte, error) { + if p == nil { + return nil, nil + } + return json.Marshal(p.String()) +} + +func (p *PackageURL) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + purl, err := NewPackageURL(s) + if err != nil { + return xerrors.Errorf("failed to parse purl(%s): %w", string(b), err) + } + *p = *purl + return nil +} + +func NewPackageURL(s string) (*PackageURL, error) { + p, err := packageurl.FromString(s) + if err != nil { + return nil, xerrors.Errorf("failed to parse purl(%s): %w", s, err) + } + + // Take out and delete the file path from qualifiers + var filePath string + for i, q := range p.Qualifiers { + if q.Key != "file_path" { + continue + } + filePath = q.Value + p.Qualifiers = append(p.Qualifiers[:i], p.Qualifiers[i+1:]...) + break + } + + if len(p.Qualifiers) == 0 { + p.Qualifiers = nil + } + + return &PackageURL{ + PackageURL: p, + FilePath: filePath, + }, nil +} diff --git a/pkg/k8s/scanner/scanner.go b/pkg/k8s/scanner/scanner.go index 8e624dd4a9a6..bbc7913ae745 100644 --- a/pkg/k8s/scanner/scanner.go +++ b/pkg/k8s/scanner/scanner.go @@ -394,7 +394,7 @@ func clusterInfoToReportResources(allArtifact []*artifacts.Artifact) (*core.Comp } ver := sanitizedVersion(c.Version) - imagePURL, err := purl.NewPackageURL(purl.TypeOCI, types.Metadata{ + imagePURL, err := purl.New(purl.TypeOCI, types.Metadata{ RepoDigests: []string{ fmt.Sprintf("%s@%s", name, cDigest), }, @@ -577,7 +577,7 @@ func nodeComponent(nf bom.NodeInfo) *core.Component { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: *packageurl.NewPackageURL(golang, "", runtimeName, runtimeVersion, packageurl.Qualifiers{}, ""), }, }, @@ -601,7 +601,7 @@ func toProperties(props map[string]string, namespace string) []core.Property { return properties } -func generatePURL(name, ver, nodeName string) *purl.PackageURL { +func generatePURL(name, ver, nodeName string) *ftypes.PackageURL { var namespace string // Identify k8s distribution. An empty namespace means upstream. @@ -611,7 +611,7 @@ func generatePURL(name, ver, nodeName string) *purl.PackageURL { namespace = "" } - return &purl.PackageURL{ + return &ftypes.PackageURL{ PackageURL: *packageurl.NewPackageURL(purl.TypeK8s, namespace, name, ver, nil, ""), } } diff --git a/pkg/k8s/scanner/scanner_test.go b/pkg/k8s/scanner/scanner_test.go index ec6d78f73c05..5f70facd3cf6 100644 --- a/pkg/k8s/scanner/scanner_test.go +++ b/pkg/k8s/scanner/scanner_test.go @@ -2,6 +2,7 @@ package scanner import ( "context" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "sort" "testing" @@ -97,7 +98,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/kubernetes", @@ -109,7 +110,7 @@ func TestScanner_Scan(t *testing.T) { Type: cdx.ComponentTypeApplication, Name: "k8s.io/apiserver", Version: "1.21.1", - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/apiserver", @@ -122,7 +123,7 @@ func TestScanner_Scan(t *testing.T) { Type: cdx.ComponentTypeContainer, Name: "k8s.gcr.io/kube-apiserver", Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f", - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "oci", Name: "kube-apiserver", @@ -233,7 +234,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "k8s", Name: "k8s.io/kubelet", @@ -257,7 +258,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "github.com/containerd/containerd", diff --git a/pkg/module/serialize/types_easyjson.go b/pkg/module/serialize/types_easyjson.go index bbbc0290de1e..fc28d5e0f758 100644 --- a/pkg/module/serialize/types_easyjson.go +++ b/pkg/module/serialize/types_easyjson.go @@ -1616,6 +1616,8 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgTypes(in *jlexer.Lexer, out.PkgName = string(in.String()) case "PkgPath": out.PkgPath = string(in.String()) + case "PkgIdentifier": + easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, &out.PkgIdentifier) case "InstalledVersion": out.InstalledVersion = string(in.String()) case "FixedVersion": @@ -1835,6 +1837,16 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgTypes(out *jwriter.Write } out.String(string(in.PkgPath)) } + if true { + const prefix string = ",\"PkgIdentifier\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, in.PkgIdentifier) + } if in.InstalledVersion != "" { const prefix string = ",\"InstalledVersion\":" if first { @@ -2215,6 +2227,59 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyDbPkgTypes(out *jwriter.Wri } out.RawByte('}') } +func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.Lexer, out *types1.PkgIdentifier) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "PURL": + if in.IsNull() { + in.Skip() + out.PURL = nil + } else { + if out.PURL == nil { + out.PURL = new(types1.PackageURL) + } + if data := in.Raw(); in.Ok() { + in.AddError((*out.PURL).UnmarshalJSON(data)) + } + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter.Writer, in types1.PkgIdentifier) { + out.RawByte('{') + first := true + _ = first + if in.PURL != nil { + const prefix string = ",\"PURL\":" + first = false + out.RawString(prefix[1:]) + out.Raw((*in.PURL).MarshalJSON()) + } + out.RawByte('}') +} func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Lexer, out *types1.Package) { isTopLevel := in.IsStart() if in.IsNull() { @@ -2238,6 +2303,8 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le out.ID = string(in.String()) case "Name": out.Name = string(in.String()) + case "Identifier": + easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, &out.Identifier) case "Version": out.Version = string(in.String()) case "Release": @@ -2291,12 +2358,12 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le if out.BuildInfo == nil { out.BuildInfo = new(types1.BuildInfo) } - easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, out.BuildInfo) + easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes10(in, out.BuildInfo) } - case "Ref": - out.Ref = string(in.String()) case "Indirect": out.Indirect = bool(in.Bool()) + case "Ref": + out.Ref = string(in.String()) case "DependsOn": if in.IsNull() { in.Skip() @@ -2349,6 +2416,29 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le } in.Delim(']') } + case "InstalledFiles": + if in.IsNull() { + in.Skip() + out.InstalledFiles = nil + } else { + in.Delim('[') + if out.InstalledFiles == nil { + if !in.IsDelim(']') { + out.InstalledFiles = make([]string, 0, 4) + } else { + out.InstalledFiles = []string{} + } + } else { + out.InstalledFiles = (out.InstalledFiles)[:0] + } + for !in.IsDelim(']') { + var v53 string + v53 = string(in.String()) + out.InstalledFiles = append(out.InstalledFiles, v53) + in.WantComma() + } + in.Delim(']') + } default: in.SkipRecursive() } @@ -2379,6 +2469,16 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } out.String(string(in.Name)) } + if true { + const prefix string = ",\"Identifier\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, in.Identifier) + } if in.Version != "" { const prefix string = ",\"Version\":" if first { @@ -2479,11 +2579,11 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } { out.RawByte('[') - for v53, v54 := range in.Licenses { - if v53 > 0 { + for v54, v55 := range in.Licenses { + if v54 > 0 { out.RawByte(',') } - out.String(string(v54)) + out.String(string(v55)) } out.RawByte(']') } @@ -2516,27 +2616,27 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } else { out.RawString(prefix) } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, *in.BuildInfo) + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes10(out, *in.BuildInfo) } - if in.Ref != "" { - const prefix string = ",\"Ref\":" + if in.Indirect { + const prefix string = ",\"Indirect\":" if first { first = false out.RawString(prefix[1:]) } else { out.RawString(prefix) } - out.String(string(in.Ref)) + out.Bool(bool(in.Indirect)) } - if in.Indirect { - const prefix string = ",\"Indirect\":" + if in.Ref != "" { + const prefix string = ",\"Ref\":" if first { first = false out.RawString(prefix[1:]) } else { out.RawString(prefix) } - out.Bool(bool(in.Indirect)) + out.String(string(in.Ref)) } if len(in.DependsOn) != 0 { const prefix string = ",\"DependsOn\":" @@ -2548,11 +2648,11 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } { out.RawByte('[') - for v55, v56 := range in.DependsOn { - if v55 > 0 { + for v56, v57 := range in.DependsOn { + if v56 > 0 { out.RawByte(',') } - out.String(string(v56)) + out.String(string(v57)) } out.RawByte(']') } @@ -2597,18 +2697,37 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } { out.RawByte('[') - for v57, v58 := range in.Locations { - if v57 > 0 { + for v58, v59 := range in.Locations { + if v58 > 0 { out.RawByte(',') } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes8(out, v58) + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes8(out, v59) + } + out.RawByte(']') + } + } + if len(in.InstalledFiles) != 0 { + const prefix string = ",\"InstalledFiles\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('[') + for v60, v61 := range in.InstalledFiles { + if v60 > 0 { + out.RawByte(',') + } + out.String(string(v61)) } out.RawByte(']') } } out.RawByte('}') } -func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.Lexer, out *types1.BuildInfo) { +func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes10(in *jlexer.Lexer, out *types1.BuildInfo) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -2643,9 +2762,9 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.L out.ContentSets = (out.ContentSets)[:0] } for !in.IsDelim(']') { - var v59 string - v59 = string(in.String()) - out.ContentSets = append(out.ContentSets, v59) + var v62 string + v62 = string(in.String()) + out.ContentSets = append(out.ContentSets, v62) in.WantComma() } in.Delim(']') @@ -2664,7 +2783,7 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.L in.Consumed() } } -func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter.Writer, in types1.BuildInfo) { +func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes10(out *jwriter.Writer, in types1.BuildInfo) { out.RawByte('{') first := true _ = first @@ -2674,11 +2793,11 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter out.RawString(prefix[1:]) { out.RawByte('[') - for v60, v61 := range in.ContentSets { - if v60 > 0 { + for v63, v64 := range in.ContentSets { + if v63 > 0 { out.RawByte(',') } - out.String(string(v61)) + out.String(string(v64)) } out.RawByte(']') } @@ -2742,9 +2861,9 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgModuleSerialize3(in *jle out.IDs = (out.IDs)[:0] } for !in.IsDelim(']') { - var v62 string - v62 = string(in.String()) - out.IDs = append(out.IDs, v62) + var v65 string + v65 = string(in.String()) + out.IDs = append(out.IDs, v65) in.WantComma() } in.Delim(']') @@ -2775,11 +2894,11 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgModuleSerialize3(out *jw out.RawString("null") } else { out.RawByte('[') - for v63, v64 := range in.IDs { - if v63 > 0 { + for v66, v67 := range in.IDs { + if v66 > 0 { out.RawByte(',') } - out.String(string(v64)) + out.String(string(v67)) } out.RawByte(']') } @@ -2845,9 +2964,9 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgModuleSerialize4(in *jle out.CustomResources = (out.CustomResources)[:0] } for !in.IsDelim(']') { - var v65 CustomResource - easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgModuleSerialize5(in, &v65) - out.CustomResources = append(out.CustomResources, v65) + var v68 CustomResource + easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgModuleSerialize5(in, &v68) + out.CustomResources = append(out.CustomResources, v68) in.WantComma() } in.Delim(']') @@ -2873,11 +2992,11 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgModuleSerialize4(out *jw out.RawString("null") } else { out.RawByte('[') - for v66, v67 := range in.CustomResources { - if v66 > 0 { + for v69, v70 := range in.CustomResources { + if v69 > 0 { out.RawByte(',') } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgModuleSerialize5(out, v67) + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgModuleSerialize5(out, v70) } out.RawByte(']') } diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index 582647166ab2..c63c4fbb849f 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -43,76 +43,13 @@ const ( TypeUnknown = "unknown" ) -type PackageURL struct { - packageurl.PackageURL - FilePath string -} - -func FromString(purl string) (*PackageURL, error) { - p, err := packageurl.FromString(purl) - if err != nil { - return nil, xerrors.Errorf("failed to parse purl(%s): %w", purl, err) - } - - return &PackageURL{ - PackageURL: p, - }, nil -} - -func (p *PackageURL) Package() *ftypes.Package { - pkg := &ftypes.Package{ - Name: p.Name, - Version: p.Version, - } - for _, q := range p.Qualifiers { - switch q.Key { - case "arch": - pkg.Arch = q.Value - case "modularitylabel": - pkg.Modularitylabel = q.Value - case "epoch": - epoch, err := strconv.Atoi(q.Value) - if err == nil { - pkg.Epoch = epoch - } - } - } - - // CocoaPods purl has no namespace, but has subpath - // https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#cocoapods - if p.Type == packageurl.TypeCocoapods && p.Subpath != "" { - // CocoaPods uses / format for package name - // e.g. `pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib` => `GoogleUtilities/NSData+zlib` - pkg.Name = p.Name + "/" + p.Subpath - } - - if p.Type == packageurl.TypeRPM { - rpmVer := version.NewVersion(p.Version) - pkg.Release = rpmVer.Release() - pkg.Version = rpmVer.Version() - } - - // Return packages without namespace. - // OS packages are not supposed to have namespace. - if p.Namespace == "" || p.Class() == types.ClassOSPkg { - return pkg - } - - // TODO: replace with packageurl.TypeGradle once they add it. - if p.Type == packageurl.TypeMaven || p.Type == string(ftypes.Gradle) { - // Maven and Gradle packages separate ":" - // e.g. org.springframework:spring-core - pkg.Name = p.Namespace + ":" + p.Name - } else { - pkg.Name = p.Namespace + "/" + p.Name - } - - return pkg +func FromString(s string) (*ftypes.PackageURL, error) { + return ftypes.NewPackageURL(s) } // LangType returns an application type in Trivy // nolint: gocyclo -func (p *PackageURL) LangType() ftypes.LangType { +func LangType(p *ftypes.PackageURL) ftypes.LangType { switch p.Type { case packageurl.TypeComposer: return ftypes.Composer @@ -165,13 +102,13 @@ func (p *PackageURL) LangType() ftypes.LangType { } } -func (p *PackageURL) Class() types.ResultClass { +func Class(p *ftypes.PackageURL) types.ResultClass { switch p.Type { case packageurl.TypeApk, packageurl.TypeDebian, packageurl.TypeRPM: // OS packages return types.ClassOSPkg default: - if p.LangType() == TypeUnknown { + if LangType(p) == TypeUnknown { return types.ClassUnknown } // Language-specific packages @@ -179,31 +116,61 @@ func (p *PackageURL) Class() types.ResultClass { } } -func (p *PackageURL) BOMRef() string { - // 'bom-ref' must be unique within BOM, but PURLs may conflict - // when the same packages are installed in an artifact. - // In that case, we prefer to make PURLs unique by adding file paths, - // rather than using UUIDs, even if it is not PURL technically. - // ref. https://cyclonedx.org/use-cases/#dependency-graph - purl := p.PackageURL // so that it will not override the qualifiers below - if p.FilePath != "" { - purl.Qualifiers = append(purl.Qualifiers, - packageurl.Qualifier{ - Key: "file_path", - Value: p.FilePath, - }, - ) +func ToPackage(p *ftypes.PackageURL) *ftypes.Package { + pkg := &ftypes.Package{ + Name: p.Name, + Version: p.Version, + } + for _, q := range p.Qualifiers { + switch q.Key { + case "arch": + pkg.Arch = q.Value + case "modularitylabel": + pkg.Modularitylabel = q.Value + case "epoch": + epoch, err := strconv.Atoi(q.Value) + if err == nil { + pkg.Epoch = epoch + } + } + } + + // CocoaPods purl has no namespace, but has subpath + // https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#cocoapods + if p.Type == packageurl.TypeCocoapods && p.Subpath != "" { + // CocoaPods uses / format for package name + // e.g. `pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib` => `GoogleUtilities/NSData+zlib` + pkg.Name = p.Name + "/" + p.Subpath } - return purl.String() + + if p.Type == packageurl.TypeRPM { + rpmVer := version.NewVersion(p.Version) + pkg.Release = rpmVer.Release() + pkg.Version = rpmVer.Version() + } + + // Return packages without namespace. + // OS packages are not supposed to have namespace. + if p.Namespace == "" || Class(p) == types.ClassOSPkg { + return pkg + } + + // TODO: replace with packageurl.TypeGradle once they add it. + if p.Type == packageurl.TypeMaven || p.Type == packageurl.TypeGradle { + // Maven and Gradle packages separate ":" + // e.g. org.springframework:spring-core + pkg.Name = p.Namespace + ":" + p.Name + } else { + pkg.Name = p.Namespace + "/" + p.Name + } + + return pkg } // nolint: gocyclo -func NewPackageURL(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (*PackageURL, error) { - var qualifiers packageurl.Qualifiers - if metadata.OS != nil { - qualifiers = parseQualifier(pkg) - pkg.Epoch = 0 // we moved Epoch to qualifiers so we don't need it in version - } +func New(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (*ftypes.PackageURL, error) { + qualifiers := parseQualifier(pkg) + pkg.Epoch = 0 // we moved Epoch to qualifiers so we don't need it in version ptype := purlType(t) name := pkg.Name @@ -250,10 +217,10 @@ func NewPackageURL(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Pack if purl.Type == "" { return nil, nil } - return &PackageURL{PackageURL: purl}, nil + return &ftypes.PackageURL{PackageURL: purl}, nil } - return &PackageURL{ + return &ftypes.PackageURL{ PackageURL: *packageurl.NewPackageURL(ptype, namespace, name, ver, qualifiers, subpath), FilePath: pkg.FilePath, }, nil @@ -449,7 +416,7 @@ func purlType(t ftypes.TargetType) string { } func parseQualifier(pkg ftypes.Package) packageurl.Qualifiers { - qualifiers := packageurl.Qualifiers{} + var qualifiers packageurl.Qualifiers if pkg.Arch != "" { qualifiers = append(qualifiers, packageurl.Qualifier{ Key: "arch", @@ -462,6 +429,7 @@ func parseQualifier(pkg ftypes.Package) packageurl.Qualifiers { Value: strconv.Itoa(pkg.Epoch), }) } + return qualifiers } diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index 9847ff57d5ce..16c32cdf056c 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -20,7 +20,7 @@ func TestNewPackageURL(t *testing.T) { typ ftypes.TargetType pkg ftypes.Package metadata types.Metadata - want *purl.PackageURL + want *ftypes.PackageURL wantErr string }{ { @@ -30,7 +30,7 @@ func TestNewPackageURL(t *testing.T) { Name: "org.springframework:spring-core", Version: "5.3.14", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -46,7 +46,7 @@ func TestNewPackageURL(t *testing.T) { Name: "org.springframework:spring-core", Version: "5.3.14", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -62,7 +62,7 @@ func TestNewPackageURL(t *testing.T) { Name: "@xtuc/ieee754", Version: "1.2.0", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Namespace: "@xtuc", @@ -78,7 +78,7 @@ func TestNewPackageURL(t *testing.T) { Name: "lodash", Version: "4.17.21", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "lodash", @@ -93,7 +93,7 @@ func TestNewPackageURL(t *testing.T) { Name: "@xtuc/ieee754", Version: "1.2.0", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Namespace: "@xtuc", @@ -109,7 +109,7 @@ func TestNewPackageURL(t *testing.T) { Name: "lodash", Version: "4.17.21", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "lodash", @@ -124,7 +124,7 @@ func TestNewPackageURL(t *testing.T) { Name: "Django_test", Version: "1.2.0", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypePyPi, Name: "django-test", @@ -139,7 +139,7 @@ func TestNewPackageURL(t *testing.T) { Name: "absl-py", Version: "0.4.1", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeConda, Name: "absl-py", @@ -154,7 +154,7 @@ func TestNewPackageURL(t *testing.T) { Name: "symfony/contracts", Version: "v1.0.2", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeComposer, Namespace: "symfony", @@ -170,7 +170,7 @@ func TestNewPackageURL(t *testing.T) { Name: "github.com/go-sql-driver/Mysql", Version: "v1.5.0", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/go-sql-driver", @@ -202,7 +202,7 @@ func TestNewPackageURL(t *testing.T) { }, }, }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeHex, Name: "bunt", @@ -217,7 +217,7 @@ func TestNewPackageURL(t *testing.T) { Name: "http", Version: "0.13.2", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypePub, Name: "http", @@ -233,7 +233,7 @@ func TestNewPackageURL(t *testing.T) { Name: "github.com/apple/swift-atomics", Version: "1.1.0", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeSwift, Namespace: "github.com/apple", @@ -250,7 +250,7 @@ func TestNewPackageURL(t *testing.T) { Name: "GoogleUtilities/NSData+zlib", Version: "7.5.2", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCocoapods, Name: "GoogleUtilities", @@ -267,7 +267,7 @@ func TestNewPackageURL(t *testing.T) { Name: "abomination", Version: "0.7.3", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCargo, Name: "abomination", @@ -283,7 +283,7 @@ func TestNewPackageURL(t *testing.T) { Name: "Newtonsoft.Json", Version: "9.0.1", }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNuget, Name: "Newtonsoft.Json", @@ -313,7 +313,7 @@ func TestNewPackageURL(t *testing.T) { Name: "8", }, }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -351,7 +351,7 @@ func TestNewPackageURL(t *testing.T) { Architecture: "amd64", }, }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeOCI, Namespace: "", @@ -399,7 +399,7 @@ func TestNewPackageURL(t *testing.T) { Architecture: "amd64", }, }, - want: &purl.PackageURL{ + want: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeOCI, Namespace: "", @@ -435,7 +435,7 @@ func TestNewPackageURL(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - packageURL, err := purl.NewPackageURL(tc.typ, tc.metadata, tc.pkg) + packageURL, err := purl.New(tc.typ, tc.metadata, tc.pkg) if tc.wantErr != "" { require.Error(t, err) assert.Contains(t, err.Error(), tc.wantErr) @@ -451,19 +451,18 @@ func TestFromString(t *testing.T) { testCases := []struct { name string purl string - want purl.PackageURL + want ftypes.PackageURL wantErr string }{ { name: "happy path for maven", purl: "pkg:maven/org.springframework/spring-core@5.0.4.RELEASE", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework", - Version: "5.0.4.RELEASE", - Name: "spring-core", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Version: "5.0.4.RELEASE", + Name: "spring-core", }, FilePath: "", }, @@ -471,61 +470,53 @@ func TestFromString(t *testing.T) { { name: "happy path for npm", purl: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "bootstrap", Version: "5.0.2", - Qualifiers: packageurl.Qualifiers{ - { - Key: "file_path", - Value: "app/app/package.json", - }, - }, }, + FilePath: "app/app/package.json", }, }, { name: "happy path for coocapods", purl: "pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeCocoapods, - Name: "GoogleUtilities", - Version: "7.5.2", - Subpath: "NSData+zlib", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeCocoapods, + Name: "GoogleUtilities", + Version: "7.5.2", + Subpath: "NSData+zlib", }, }, }, { name: "happy path for hex", purl: "pkg:hex/plug@1.14.0", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeHex, - Name: "plug", - Version: "1.14.0", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeHex, + Name: "plug", + Version: "1.14.0", }, }, }, { name: "happy path for dart", purl: "pkg:pub/http@0.13.2", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypePub, - Name: "http", - Version: "0.13.2", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypePub, + Name: "http", + Version: "0.13.2", }, }, }, { name: "happy path for apk", purl: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?distro=3.14.2&epoch=1", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: string(analyzer.TypeApk), Namespace: "alpine", @@ -547,38 +538,35 @@ func TestFromString(t *testing.T) { { name: "happy path for rpm", purl: "pkg:rpm/redhat/containers-common@0.1.14", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "redhat", - Name: "containers-common", - Version: "0.1.14", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "containers-common", + Version: "0.1.14", }, }, }, { name: "happy path for conda", purl: "pkg:conda/absl-py@0.4.1", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeConda, - Name: "absl-py", - Version: "0.4.1", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeConda, + Name: "absl-py", + Version: "0.4.1", }, }, }, { name: "bad rpm", purl: "pkg:rpm/redhat/a--@1.0.0", - want: purl.PackageURL{ + want: ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "redhat", - Name: "a--", - Version: "1.0.0", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "a--", + Version: "1.0.0", }, }, }, @@ -588,8 +576,7 @@ func TestFromString(t *testing.T) { t.Run(tc.name, func(t *testing.T) { pkg, err := purl.FromString(tc.purl) if tc.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tc.wantErr) + assert.ErrorContains(t, err, tc.wantErr) return } assert.NoError(t, err) @@ -598,15 +585,15 @@ func TestFromString(t *testing.T) { } } -func TestPackage(t *testing.T) { +func TestToPackage(t *testing.T) { tests := []struct { name string - pkgURL *purl.PackageURL + pkgURL *ftypes.PackageURL wantPkg *ftypes.Package }{ { name: "rpm + Qualifiers", - pkgURL: &purl.PackageURL{ + pkgURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -643,7 +630,7 @@ func TestPackage(t *testing.T) { }, { name: "composer with namespace", - pkgURL: &purl.PackageURL{ + pkgURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeComposer, Namespace: "symfony", @@ -658,13 +645,12 @@ func TestPackage(t *testing.T) { }, { name: "maven with namespace", - pkgURL: &purl.PackageURL{ + pkgURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework", - Name: "spring-core", - Version: "5.0.4.RELEASE", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-core", + Version: "5.0.4.RELEASE", }, }, wantPkg: &ftypes.Package{ @@ -674,13 +660,12 @@ func TestPackage(t *testing.T) { }, { name: "cocoapods with subpath", - pkgURL: &purl.PackageURL{ + pkgURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeCocoapods, - Version: "4.2.0", - Name: "AppCenter", - Subpath: "Analytics", - Qualifiers: packageurl.Qualifiers{}, + Type: packageurl.TypeCocoapods, + Version: "4.2.0", + Name: "AppCenter", + Subpath: "Analytics", }, }, wantPkg: &ftypes.Package{ @@ -690,7 +675,7 @@ func TestPackage(t *testing.T) { }, { name: "wrong epoch", - pkgURL: &purl.PackageURL{ + pkgURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -714,13 +699,13 @@ func TestPackage(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := tt.pkgURL.Package() + got := purl.ToPackage(tt.pkgURL) assert.Equal(t, tt.wantPkg, got) }) } } -func TestPackageURL_LangType(t *testing.T) { +func TestLangType(t *testing.T) { tests := []struct { name string purl packageurl.PackageURL @@ -758,8 +743,8 @@ func TestPackageURL_LangType(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - p := &purl.PackageURL{PackageURL: tt.purl} - assert.Equalf(t, tt.want, p.LangType(), "LangType()") + p := &ftypes.PackageURL{PackageURL: tt.purl} + assert.Equalf(t, tt.want, purl.LangType(p), "LangType()") }) } } diff --git a/pkg/report/github/github.go b/pkg/report/github/github.go index 9476c5020709..8384f27b0e74 100644 --- a/pkg/report/github/github.go +++ b/pkg/report/github/github.go @@ -161,7 +161,7 @@ func getPkgRelationshipType(pkg ftypes.Package) string { } func buildPurl(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (string, error) { - packageUrl, err := purl.NewPackageURL(t, metadata, pkg) + packageUrl, err := purl.New(t, metadata, pkg) if err != nil { return "", xerrors.Errorf("purl error: %w", err) } diff --git a/pkg/result/filter_test.go b/pkg/result/filter_test.go index afe32726aa43..7392a4779861 100644 --- a/pkg/result/filter_test.go +++ b/pkg/result/filter_test.go @@ -2,6 +2,7 @@ package result_test import ( "context" + "github.com/package-url/packageurl-go" "testing" "time" @@ -150,9 +151,18 @@ func TestFilter(t *testing.T) { types.Result{ Vulnerabilities: []types.DetectedVulnerability{ { - VulnerabilityID: "CVE-2019-0001", - PkgName: "foo", - PkgRef: "pkg:golang/github.com/aquasecurity/foo@1.2.3", + VulnerabilityID: "CVE-2019-0001", + PkgName: "foo", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "foo", + Version: "1.2.3", + }, + }, + }, InstalledVersion: "1.2.3", FixedVersion: "1.2.4", Vulnerability: dbTypes.Vulnerability{ @@ -160,11 +170,20 @@ func TestFilter(t *testing.T) { }, }, { - VulnerabilityID: "CVE-2019-0001", - PkgName: "bar", - PkgRef: "pkg:golang/github.com/aquasecurity/bar@1.2.3", - InstalledVersion: "1.2.3", - FixedVersion: "1.2.4", + VulnerabilityID: "CVE-2019-0001", + PkgName: "bar", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "bar", + Version: "4.5.6", + }, + }, + }, + InstalledVersion: "4.5.6", + FixedVersion: "4.5.7", Vulnerability: dbTypes.Vulnerability{ Severity: dbTypes.SeverityCritical.String(), }, @@ -187,11 +206,20 @@ func TestFilter(t *testing.T) { types.Result{ Vulnerabilities: []types.DetectedVulnerability{ { - VulnerabilityID: "CVE-2019-0001", - PkgName: "bar", - PkgRef: "pkg:golang/github.com/aquasecurity/bar@1.2.3", - InstalledVersion: "1.2.3", - FixedVersion: "1.2.4", + VulnerabilityID: "CVE-2019-0001", + PkgName: "bar", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "bar", + Version: "4.5.6", + }, + }, + }, + InstalledVersion: "4.5.6", + FixedVersion: "4.5.7", Vulnerability: dbTypes.Vulnerability{ Severity: dbTypes.SeverityCritical.String(), }, @@ -713,7 +741,8 @@ func TestFilter(t *testing.T) { Severity: dbTypes.SeverityHigh.String(), Status: types.StatusPassed, }, - { // this misconf is ignored + { + // this misconf is ignored ID: "AVD-TEST-0003", AVDID: "AVD-TEST-0003", Title: "test-0003", diff --git a/pkg/rpc/convert.go b/pkg/rpc/convert.go index d3bc29425a4b..d828533c596e 100644 --- a/pkg/rpc/convert.go +++ b/pkg/rpc/convert.go @@ -11,6 +11,7 @@ import ( "github.com/aquasecurity/trivy/pkg/digest" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/rpc/cache" "github.com/aquasecurity/trivy/rpc/common" @@ -57,6 +58,7 @@ func ConvertToRPCPkgs(pkgs []ftypes.Package) []*common.Package { Release: pkg.Release, Epoch: int32(pkg.Epoch), Arch: pkg.Arch, + Identifier: ConvertToRPCPkgIdentifier(pkg.Identifier), Dev: pkg.Dev, SrcName: pkg.SrcName, SrcVersion: pkg.SrcVersion, @@ -73,6 +75,20 @@ func ConvertToRPCPkgs(pkgs []ftypes.Package) []*common.Package { return rpcPkgs } +func ConvertToRPCPkgIdentifier(pkg ftypes.PkgIdentifier) *common.PkgIdentifier { + if pkg.Empty() { + return nil + } + + var p string + if pkg.PURL != nil { + p = pkg.PURL.BOMRef() // Use BOMRef() instead of String() so that we won't lose file_path + } + return &common.PkgIdentifier{ + Purl: p, + } +} + func ConvertToRPCCustomResources(resources []ftypes.CustomResource) []*common.CustomResource { var rpcResources []*common.CustomResource for _, r := range resources { @@ -183,6 +199,7 @@ func ConvertFromRPCPkgs(rpcPkgs []*common.Package) []ftypes.Package { Release: pkg.Release, Epoch: int(pkg.Epoch), Arch: pkg.Arch, + Identifier: ConvertFromRPCPkgIdentifier(pkg.Identifier), Dev: pkg.Dev, SrcName: pkg.SrcName, SrcVersion: pkg.SrcVersion, @@ -199,6 +216,19 @@ func ConvertFromRPCPkgs(rpcPkgs []*common.Package) []ftypes.Package { return pkgs } +func ConvertFromRPCPkgIdentifier(pkg *common.PkgIdentifier) ftypes.PkgIdentifier { + if pkg == nil || pkg.Purl == "" { + return ftypes.PkgIdentifier{} + } + pu, err := purl.FromString(pkg.Purl) + if err != nil { + log.Logger.Error("Failed to parse PURL (%s): %s", pkg.Purl, err) + } + return ftypes.PkgIdentifier{ + PURL: pu, + } +} + // ConvertToRPCVulns returns common.Vulnerability func ConvertToRPCVulns(vulns []types.DetectedVulnerability) []*common.Vulnerability { var rpcVulns []*common.Vulnerability @@ -246,6 +276,7 @@ func ConvertToRPCVulns(vulns []types.DetectedVulnerability) []*common.Vulnerabil PkgPath: vuln.PkgPath, InstalledVersion: vuln.InstalledVersion, FixedVersion: vuln.FixedVersion, + PkgIdentifier: ConvertToRPCPkgIdentifier(vuln.PkgIdentifier), Status: int32(vuln.Status), Title: vuln.Title, Description: vuln.Description, @@ -521,6 +552,7 @@ func ConvertFromRPCVulns(rpcVulns []*common.Vulnerability) []types.DetectedVulne PkgPath: vuln.PkgPath, InstalledVersion: vuln.InstalledVersion, FixedVersion: vuln.FixedVersion, + PkgIdentifier: ConvertFromRPCPkgIdentifier(vuln.PkgIdentifier), Status: dbTypes.Status(vuln.Status), Vulnerability: dbTypes.Vulnerability{ Title: vuln.Title, diff --git a/pkg/sbom/cyclonedx/core/cyclonedx.go b/pkg/sbom/cyclonedx/core/cyclonedx.go index dad245b5239c..5d61f2993f72 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx.go @@ -14,8 +14,8 @@ import ( "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/digest" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" - "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -38,7 +38,7 @@ type Component struct { Name string Group string Version string - PackageURL *purl.PackageURL + PackageURL *ftypes.PackageURL Licenses []string Hashes []digest.Digest Supplier string @@ -231,7 +231,7 @@ func (c *CycloneDX) Vulnerabilities(uniq map[string]*cdx.Vulnerability) *[]cdx.V return &vulns } -func (c *CycloneDX) PackageURL(p *purl.PackageURL) string { +func (c *CycloneDX) PackageURL(p *ftypes.PackageURL) string { if p == nil { return "" } diff --git a/pkg/sbom/cyclonedx/core/cyclonedx_test.go b/pkg/sbom/cyclonedx/core/cyclonedx_test.go index c147b74247df..2685a56ef733 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx_test.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx_test.go @@ -10,7 +10,7 @@ import ( "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/digest" - "github.com/aquasecurity/trivy/pkg/purl" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -42,7 +42,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Type: cdx.ComponentTypeContainer, Name: "k8s.gcr.io/kube-apiserver", Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f", - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "oci", Name: "kube-apiserver", @@ -137,7 +137,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Value: "golang", }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "kubelet", @@ -156,7 +156,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Value: "golang", }, }, - PackageURL: &purl.PackageURL{ + PackageURL: &ftypes.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "containerd", diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index c6934571c0a0..586b82d3ee39 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -236,7 +236,7 @@ func (e *Marshaler) rootComponent(r types.Report) (*core.Component, error) { Value: r.Metadata.ImageID, }) - p, err := purl.NewPackageURL(purl.TypeOCI, r.Metadata, ftypes.Package{}) + p, err := purl.New(purl.TypeOCI, r.Metadata, ftypes.Package{}) if err != nil { return nil, xerrors.Errorf("failed to new package url for oci: %w", err) } @@ -315,17 +315,12 @@ func (e *Marshaler) resultComponent(r types.Result, osFound *ftypes.OS) *core.Co } func pkgComponent(pkg Package) (*core.Component, error) { - pu, err := purl.NewPackageURL(pkg.Type, pkg.Metadata, pkg.Package) - if err != nil { - return nil, xerrors.Errorf("failed to new package purl: %w", err) - } - name := pkg.Name version := pkg.Version var group string // there are cases when we can't build purl // e.g. local Go packages - if pu != nil { + if pu := pkg.Identifier.PURL; pu != nil { version = pu.Version // use `group` field for GroupID and `name` for ArtifactID for jar files if pkg.Type == ftypes.Jar { @@ -382,7 +377,7 @@ func pkgComponent(pkg Package) (*core.Component, error) { Name: name, Group: group, Version: version, - PackageURL: pu, + PackageURL: pkg.Identifier.PURL, Supplier: pkg.Maintainer, Licenses: pkg.Licenses, Hashes: lo.Ternary(pkg.Digest == "", nil, []digest.Digest{pkg.Digest}), diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 59f77a24ad63..234f2b9d0ae5 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -1,6 +1,7 @@ package cyclonedx_test import ( + "github.com/package-url/packageurl-go" "testing" "time" @@ -54,12 +55,32 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.CentOS, Packages: []ftypes.Package{ { - ID: "binutils@2.30-93.el8", - Name: "binutils", - Version: "2.30", - Release: "93.el8", - Epoch: 0, - Arch: "aarch64", + ID: "binutils@2.30-93.el8", + Name: "binutils", + Version: "2.30", + Release: "93.el8", + Epoch: 0, + Arch: "aarch64", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "binutils", + Version: "2.30-93.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + }, + }, + }, + }, SrcName: "binutils", SrcVersion: "2.30", SrcRelease: "93.el8", @@ -119,15 +140,33 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.Bundler, Packages: []ftypes.Package{ { - ID: "actionpack@7.0.0", - Name: "actionpack", - Version: "7.0.0", + ID: "actionpack@7.0.0", + Name: "actionpack", + Version: "7.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", + }, + }, + }, Indirect: false, }, { - ID: "actioncontroller@7.0.0", - Name: "actioncontroller", - Version: "7.0.0", + ID: "actioncontroller@7.0.0", + Name: "actioncontroller", + Version: "7.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncontroller", + Version: "7.0.0", + }, + }, + }, Indirect: false, DependsOn: []string{ "actionpack@7.0.0", @@ -144,6 +183,15 @@ func TestMarshaler_Marshal(t *testing.T) { ID: "actionpack@7.0.0", Name: "actionpack", Version: "7.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", + }, + }, + }, }, }, }, @@ -156,6 +204,15 @@ func TestMarshaler_Marshal(t *testing.T) { ID: "Newtonsoft.Json@9.0.1", Name: "Newtonsoft.Json", Version: "9.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNuget, + Name: "Newtonsoft.Json", + Version: "9.0.1", + }, + }, + }, }, }, }, @@ -167,6 +224,16 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "golang.org/x/crypto", Version: "v0.0.0-20210421170649-83a5a9bb288b", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "crypto", + Version: "v0.0.0-20210421170649-83a5a9bb288b", + }, + }, + }, }, // dependency has been replaced with local directory { @@ -592,12 +659,36 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.CentOS, Packages: []ftypes.Package{ { - ID: "acl@2.2.53-1.el8", - Name: "acl", - Version: "2.2.53", - Release: "1.el8", - Epoch: 1, - Arch: "aarch64", + ID: "acl@2.2.53-1.el8", + Name: "acl", + Version: "2.2.53", + Release: "1.el8", + Epoch: 1, + Arch: "aarch64", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + { + Key: "epoch", + Value: "1", + }, + }, + }, + }, + }, SrcName: "acl", SrcVersion: "2.2.53", SrcRelease: "1.el8", @@ -610,12 +701,32 @@ func TestMarshaler_Marshal(t *testing.T) { Digest: "md5:483792b8b5f9eb8be7dc4407733118d0", }, { - ID: "glibc@2.28-151.el8", - Name: "glibc", - Version: "2.28", - Release: "151.el8", - Epoch: 0, - Arch: "aarch64", + ID: "glibc@2.28-151.el8", + Name: "glibc", + Version: "2.28", + Release: "151.el8", + Epoch: 0, + Arch: "aarch64", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "glibc", + Version: "2.28-151.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + }, + }, + }, + }, SrcName: "glibc", SrcVersion: "2.28", SrcRelease: "151.el8", @@ -635,6 +746,16 @@ func TestMarshaler_Marshal(t *testing.T) { ID: "actionpack@7.0.0", Name: "actionpack", Version: "7.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", + }, + FilePath: "tools/project-john/specifications/actionpack.gemspec", + }, + }, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, @@ -644,6 +765,16 @@ func TestMarshaler_Marshal(t *testing.T) { ID: "actionpack@7.0.1", Name: "actionpack", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + FilePath: "tools/project-doe/specifications/actionpack.gemspec", + }, + }, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, @@ -652,10 +783,19 @@ func TestMarshaler_Marshal(t *testing.T) { }, Vulnerabilities: []types.DetectedVulnerability{ { - VulnerabilityID: "CVE-2022-23633", - PkgID: "actionpack@7.0.0", - PkgName: "actionpack", - PkgPath: "tools/project-john/specifications/actionpack.gemspec", + VulnerabilityID: "CVE-2022-23633", + PkgID: "actionpack@7.0.0", + PkgName: "actionpack", + PkgPath: "tools/project-john/specifications/actionpack.gemspec", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", + }, + }, + }, InstalledVersion: "7.0.0", FixedVersion: "~> 5.2.6, >= 5.2.6.2, ~> 6.0.4, >= 6.0.4.6, ~> 6.1.4, >= 6.1.4.6, >= 7.0.2.2", SeveritySource: vulnerability.RubySec, @@ -695,10 +835,19 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, { - VulnerabilityID: "CVE-2022-23633", - PkgID: "actionpack@7.0.1", - PkgName: "actionpack", - PkgPath: "tools/project-doe/specifications/actionpack.gemspec", + VulnerabilityID: "CVE-2022-23633", + PkgID: "actionpack@7.0.1", + PkgName: "actionpack", + PkgPath: "tools/project-doe/specifications/actionpack.gemspec", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + }, + }, InstalledVersion: "7.0.1", FixedVersion: "~> 5.2.6, >= 5.2.6.2, ~> 6.0.4, >= 6.0.4.6, ~> 6.1.4, >= 6.1.4.6, >= 7.0.2.2", SeveritySource: vulnerability.RubySec, @@ -1070,6 +1219,15 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actioncable", Version: "6.1.4.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncable", + Version: "6.1.4.1", + }, + }, + }, }, }, }, @@ -1079,8 +1237,19 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.Jar, Packages: []ftypes.Package{ { - Name: "org.springframework:spring-web", - Version: "5.3.22", + Name: "org.springframework:spring-web", + Version: "5.3.22", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-web", + Version: "5.3.22", + }, + FilePath: "spring-web-5.3.22.jar", + }, + }, FilePath: "spring-web-5.3.22.jar", }, }, @@ -1202,21 +1371,53 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.Jar, Packages: []ftypes.Package{ { - Name: "org.apache.nifi:nifi-dbcp-base", - Version: "1.20.0", + Name: "org.apache.nifi:nifi-dbcp-base", + Version: "1.20.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-dbcp-base", + Version: "1.20.0", + }, + FilePath: "nifi-dbcp-base-1.20.0.jar", + }, + }, FilePath: "nifi-dbcp-base-1.20.0.jar", }, { - Name: "org.apache.nifi:nifi-hikari-dbcp-service", - Version: "1.20.0", + Name: "org.apache.nifi:nifi-hikari-dbcp-service", + Version: "1.20.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-hikari-dbcp-service", + Version: "1.20.0", + }, + FilePath: "nifi-hikari-dbcp-service-1.20.0.jar", + }, + }, FilePath: "nifi-hikari-dbcp-service-1.20.0.jar", }, }, Vulnerabilities: []types.DetectedVulnerability{ { - VulnerabilityID: "CVE-2023-34468", - PkgName: "org.apache.nifi:nifi-dbcp-base", - PkgPath: "nifi-dbcp-base-1.20.0.jar", + VulnerabilityID: "CVE-2023-34468", + PkgName: "org.apache.nifi:nifi-dbcp-base", + PkgPath: "nifi-dbcp-base-1.20.0.jar", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-dbcp-base", + Version: "1.20.0", + }, + }, + }, InstalledVersion: "1.20.0", FixedVersion: "1.22.0", SeveritySource: vulnerability.GHSA, @@ -1256,9 +1457,19 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, { - VulnerabilityID: "CVE-2023-34468", - PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", - PkgPath: "nifi-hikari-dbcp-service-1.20.0.jar", + VulnerabilityID: "CVE-2023-34468", + PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", + PkgPath: "nifi-hikari-dbcp-service-1.20.0.jar", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-hikari-dbcp-service", + Version: "1.20.0", + }, + }, + }, InstalledVersion: "1.20.0", FixedVersion: "1.22.0", SeveritySource: vulnerability.GHSA, @@ -1464,9 +1675,19 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.NodePkg, Packages: []ftypes.Package{ { - ID: "ruby-typeprof@0.20.1", - Name: "ruby-typeprof", - Version: "0.20.1", + ID: "ruby-typeprof@0.20.1", + Name: "ruby-typeprof", + Version: "0.20.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "ruby-typeprof", + Version: "0.20.1", + }, + FilePath: "usr/local/lib/ruby/gems/3.1.0/gems/typeprof-0.21.1/vscode/package.json", + }, + }, Licenses: []string{"MIT"}, Layer: ftypes.Layer{ DiffID: "sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e", diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index 97c24cf2797a..be08c280ed13 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -202,7 +202,7 @@ func parsePkgs(components []cdx.Component, seen map[string]struct{}) ([]ftypes.P } // Skip unsupported package types - if pkgURL.Class() == types.ClassUnknown { + if purl.Class(pkgURL) == types.ClassUnknown { continue } pkgs = append(pkgs, *pkg) @@ -290,11 +290,11 @@ func aggregatePkgs(libs []cdx.Component) ([]ftypes.PackageInfo, []ftypes.Applica return nil, nil, xerrors.Errorf("failed to parse the component: %w", err) } - switch pkgURL.Class() { + switch purl.Class(pkgURL) { case types.ClassOSPkg: osPkgMap[pkgURL.Type] = append(osPkgMap[pkgURL.Type], *pkg) case types.ClassLangPkg: - langType := pkgURL.LangType() + langType := purl.LangType(pkgURL) langPkgMap[langType] = append(langPkgMap[langType], *pkg) } } @@ -337,7 +337,7 @@ func toApplication(component cdx.Component) *ftypes.Application { } } -func toPackage(component cdx.Component) (*purl.PackageURL, *ftypes.Package, error) { +func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, error) { if component.PackageURL == "" { log.Logger.Warnf("Skip the component (BOM-Ref: %s) as the PURL is empty", component.BOMRef) return nil, nil, ErrPURLEmpty @@ -347,10 +347,10 @@ func toPackage(component cdx.Component) (*purl.PackageURL, *ftypes.Package, erro return nil, nil, xerrors.Errorf("failed to parse purl: %w", err) } - pkg := p.Package() + pkg := purl.ToPackage(p) // Trivy's marshall loses case-sensitivity in PURL used in SBOM for packages (Go, Npm, PyPI), // so we have to use an original package name - pkg.Name = getPackageName(p.Type, pkg.Name, component) + pkg.Name = packageName(p.Type, pkg.Name, component) pkg.Ref = component.BOMRef for _, license := range lo.FromPtr(component.Licenses) { @@ -383,25 +383,34 @@ func toPackage(component cdx.Component) (*purl.PackageURL, *ftypes.Package, erro } } - if p.Class() == types.ClassOSPkg { - // Fill source package information for components in third-party SBOMs . - if pkg.SrcName == "" { - pkg.SrcName = pkg.Name - } - if pkg.SrcVersion == "" { - pkg.SrcVersion = pkg.Version - } - if pkg.SrcRelease == "" { - pkg.SrcRelease = pkg.Release - } - if pkg.SrcEpoch == 0 { - pkg.SrcEpoch = pkg.Epoch - } + if pkg.FilePath != "" { + p.FilePath = pkg.FilePath + } + pkg.Identifier = ftypes.PkgIdentifier{PURL: p} + + if purl.Class(p) == types.ClassOSPkg { + fillSrcPkg(pkg) } return p, pkg, nil } +func fillSrcPkg(pkg *ftypes.Package) { + // Fill source package information for components in third-party SBOMs . + if pkg.SrcName == "" { + pkg.SrcName = pkg.Name + } + if pkg.SrcVersion == "" { + pkg.SrcVersion = pkg.Version + } + if pkg.SrcRelease == "" { + pkg.SrcRelease = pkg.Release + } + if pkg.SrcEpoch == 0 { + pkg.SrcEpoch = pkg.Epoch + } +} + func toTrivyCdxComponent(component cdx.Component) ftypes.Component { return ftypes.Component{ BOMRef: component.BOMRef, @@ -413,7 +422,7 @@ func toTrivyCdxComponent(component cdx.Component) ftypes.Component { } } -func getPackageName(typ, pkgNameFromPurl string, component cdx.Component) string { +func packageName(typ, pkgNameFromPurl string, component cdx.Component) string { if typ == packageurl.TypeMaven { // Jar uses `Group` field for `GroupID` if component.Group != "" { diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index 26c5e5d7ff49..0af6121b4ea1 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -2,6 +2,8 @@ package cyclonedx_test import ( "encoding/json" + "github.com/aquasecurity/trivy/pkg/purl" + "github.com/package-url/packageurl-go" "os" "testing" @@ -37,7 +39,23 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", + }, + }, + }, + }, + }, + Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: ftypes.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -53,7 +71,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -62,7 +90,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -76,7 +114,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", + }, + }, + }, + Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -88,7 +136,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { FilePath: "app/gradle/target/gradle.lockfile", Libraries: ftypes.Packages{ { - Name: "com.example:example", + Name: "com.example:example", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.example", + Name: "example", + Version: "0.0.1", + }, + }, + }, Ref: "pkg:maven/com.example/example@0.0.1", Version: "0.0.1", Layer: ftypes.Layer{ @@ -101,7 +159,18 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Type: ftypes.Jar, Libraries: ftypes.Packages{ { - Name: "org.codehaus.mojo:child-project", + Name: "org.codehaus.mojo:child-project", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", + }, + FilePath: "app/maven/target/child-project-1.0.jar", + }, + }, Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Version: "1.0", Layer: ftypes.Layer{ @@ -116,8 +185,18 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { FilePath: "", Libraries: ftypes.Packages{ { - Name: "bootstrap", - Version: "5.0.2", + Name: "bootstrap", + Version: "5.0.2", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", + }, + FilePath: "app/app/package.json", + }, + }, Ref: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", Licenses: []string{"MIT"}, Layer: ftypes.Layer{ @@ -150,7 +229,16 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "docker", Version: "24.0.4", - Ref: "pkg:golang/docker@24.0.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Name: "docker", + Version: "24.0.4", + }, + }, + }, + Ref: "pkg:golang/docker@24.0.4", }, }, }, @@ -164,32 +252,86 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "k8s.io/apiserver", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fapiserver@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/apiserver", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fapiserver@1.27.4", }, { Name: "k8s.io/controller-manager", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fcontroller-manager@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/controller-manager", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fcontroller-manager@1.27.4", }, { Name: "k8s.io/kube-proxy", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fkube-proxy@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kube-proxy", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fkube-proxy@1.27.4", }, { Name: "k8s.io/kube-scheduler", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fkube-scheduler@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kube-scheduler", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fkube-scheduler@1.27.4", }, { Name: "k8s.io/kubelet", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fkubelet@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kubelet", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fkubelet@1.27.4", }, { Name: "k8s.io/kubernetes", Version: "1.27.4", - Ref: "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kubernetes", + Version: "1.27.4", + }, + }, + }, + Ref: "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", }, }, }, @@ -219,6 +361,22 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { "GPL-2.0", "GFDL-1.3", }, + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "ubuntu", + Name: "libc6", + Version: "2.35-0ubuntu3.1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "ubuntu-22.04", + }, + }, + }, + }, + }, Ref: "pkg:deb/ubuntu/libc6@2.35-0ubuntu3.1?distro=ubuntu-22.04", Layer: ftypes.Layer{ Digest: "sha256:74ac377868f863e123f24c409f79709f7563fa464557c36a09cf6f85c8b92b7f", @@ -234,7 +392,27 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcVersion: "4.4.27", SrcRelease: "1", SrcEpoch: 1, - Ref: "pkg:deb/ubuntu/libcrypt1@4.4.27-1?epoch=1&distro=ubuntu-22.04", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "ubuntu", + Name: "libcrypt1", + Version: "4.4.27-1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "ubuntu-22.04", + }, + { + Key: "epoch", + Value: "1", + }, + }, + }, + }, + }, + Ref: "pkg:deb/ubuntu/libcrypt1@4.4.27-1?epoch=1&distro=ubuntu-22.04", Layer: ftypes.Layer{ Digest: "sha256:74ac377868f863e123f24c409f79709f7563fa464557c36a09cf6f85c8b92b7f", DiffID: "sha256:b93c1bd012ab8fda60f5b4f5906bf244586e0e3292d84571d3abb56472248466", @@ -262,7 +440,23 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", + }, + }, + }, + }, + }, + Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, }, }, @@ -275,13 +469,33 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", }, { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -300,7 +514,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", }, }, }, @@ -319,13 +543,33 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", }, { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -344,18 +588,48 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/core", Version: "1.13.1", - Ref: "pkg:composer/pear/core@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "core", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/core@1.13.1", }, { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", }, { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -371,8 +645,19 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Type: "jar", Libraries: ftypes.Packages{ { - Name: "org.springframework:spring-web", - Version: "5.3.22", + Name: "org.springframework:spring-web", + Version: "5.3.22", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-web", + Version: "5.3.22", + }, + FilePath: "spring-web-5.3.22.jar", + }, + }, Ref: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", FilePath: "spring-web-5.3.22.jar", }, diff --git a/pkg/sbom/spdx/marshal.go b/pkg/sbom/spdx/marshal.go index 69544d850548..642e7d7629ab 100644 --- a/pkg/sbom/spdx/marshal.go +++ b/pkg/sbom/spdx/marshal.go @@ -243,7 +243,7 @@ func (m *Marshaler) rootPackage(r types.Report, pkgDownloadLocation string) (*sp attributionTexts := []string{attributionText(PropertySchemaVersion, strconv.Itoa(r.SchemaVersion))} // When the target is a container image, add PURL to the external references of the root package. - if p, err := purl.NewPackageURL(purl.TypeOCI, r.Metadata, ftypes.Package{}); err != nil { + if p, err := purl.New(purl.TypeOCI, r.Metadata, ftypes.Package{}); err != nil { return nil, xerrors.Errorf("failed to new package url for oci: %w", err) } else if p != nil { externalReferences = append(externalReferences, purlExternalReference(p.ToString())) @@ -333,14 +333,9 @@ func (m *Marshaler) pkgToSpdxPackage(t ftypes.TargetType, pkgDownloadLocation st pkgSrcInfo = fmt.Sprintf("%s: %s %s", SourcePackagePrefix, pkg.SrcName, utils.FormatSrcVersion(pkg)) } - packageURL, err := purl.NewPackageURL(t, metadata, pkg) - if err != nil { - return spdx.Package{}, xerrors.Errorf("failed to parse purl (%s): %w", pkg.Name, err) - } - var pkgExtRefs []*spdx.PackageExternalReference - if packageURL != nil { - pkgExtRefs = []*spdx.PackageExternalReference{purlExternalReference(packageURL.String())} + if pkg.Identifier.PURL != nil { + pkgExtRefs = []*spdx.PackageExternalReference{purlExternalReference(pkg.Identifier.PURL.String())} } var attrTexts []string diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index b173958a0164..eb73274bbc30 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -1,6 +1,7 @@ package spdx_test import ( + "github.com/package-url/packageurl-go" "hash/fnv" "testing" "time" @@ -54,11 +55,31 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.CentOS, Packages: []ftypes.Package{ { - Name: "binutils", - Version: "2.30", - Release: "93.el8", - Epoch: 0, - Arch: "aarch64", + Name: "binutils", + Version: "2.30", + Release: "93.el8", + Epoch: 0, + Arch: "aarch64", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "binutils", + Version: "2.30-93.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + }, + }, + }, + }, SrcName: "binutils", SrcVersion: "2.30", SrcRelease: "93.el8", @@ -78,10 +99,28 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actionpack", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + }, + }, }, { Name: "actioncontroller", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncontroller", + Version: "7.0.1", + }, + }, + }, }, }, }, @@ -93,6 +132,15 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actionpack", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + }, + }, }, }, }, @@ -296,11 +344,35 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.CentOS, Packages: []ftypes.Package{ { - Name: "acl", - Version: "2.2.53", - Release: "1.el8", - Epoch: 1, - Arch: "aarch64", + Name: "acl", + Version: "2.2.53", + Release: "1.el8", + Epoch: 1, + Arch: "aarch64", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + { + Key: "epoch", + Value: "1", + }, + }, + }, + }, + }, SrcName: "acl", SrcVersion: "2.2.53", SrcRelease: "1.el8", @@ -319,6 +391,15 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actionpack", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + }, + }, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, @@ -328,6 +409,15 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actionpack", Version: "7.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + }, + }, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, @@ -542,6 +632,15 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "actioncable", Version: "6.1.4.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncable", + Version: "6.1.4.1", + }, + }, + }, }, }, }, @@ -633,8 +732,17 @@ func TestMarshaler_Marshal(t *testing.T) { Type: ftypes.NodePkg, Packages: []ftypes.Package{ { - Name: "ruby-typeprof", - Version: "0.20.1", + Name: "ruby-typeprof", + Version: "0.20.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "ruby-typeprof", + Version: "0.20.1", + }, + }, + }, Licenses: []string{"MIT"}, Layer: ftypes.Layer{ DiffID: "sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e", @@ -866,6 +974,16 @@ func TestMarshaler_Marshal(t *testing.T) { { Name: "golang.org/x/crypto", Version: "v0.0.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "crypto", + Version: "v0.0.1", + }, + }, + }, }, }, }, diff --git a/pkg/sbom/spdx/unmarshal.go b/pkg/sbom/spdx/unmarshal.go index e603e646be9b..9ff8586c45d9 100644 --- a/pkg/sbom/spdx/unmarshal.go +++ b/pkg/sbom/spdx/unmarshal.go @@ -177,12 +177,12 @@ func (s *SPDX) parsePackages(pkgs map[common.ElementID]*spdx.Package) error { } else if err != nil { return xerrors.Errorf("failed to parse package: %w", err) } - switch pkgURL.Class() { + switch purl.Class(pkgURL) { case types.ClassOSPkg: osPkgs = append(osPkgs, *pkg) case types.ClassLangPkg: // Language-specific packages - pkgType := pkgURL.LangType() + pkgType := purl.LangType(pkgURL) app, ok := apps[pkgType] if !ok { app.Type = pkgType @@ -246,7 +246,7 @@ func parseOS(pkg spdx.Package) ftypes.OS { } } -func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes.Package, *purl.PackageURL, error) { +func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes.Package, *ftypes.PackageURL, error) { pkg, pkgURL, err := parseExternalReferences(spdxPkg.PackageExternalReferences) if err != nil { return nil, nil, xerrors.Errorf("external references error: %w", err) @@ -278,7 +278,7 @@ func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes return pkg, pkgURL, nil } -func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Package, *purl.PackageURL, error) { +func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Package, *ftypes.PackageURL, error) { for _, ref := range refs { // Extract the package information from PURL if ref.RefType != RefTypePurl || ref.Category != CategoryPackageManager { @@ -289,8 +289,11 @@ func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Pac if err != nil { return nil, nil, xerrors.Errorf("failed to parse purl from string: %w", err) } - pkg := packageURL.Package() + pkg := purl.ToPackage(packageURL) pkg.Ref = ref.Locator + pkg.Identifier = ftypes.PkgIdentifier{ + PURL: packageURL, + } return pkg, packageURL, nil } return nil, nil, errUnknownPackageFormat diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index 5b72fb9e0d05..d7ebdad3922d 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -2,6 +2,7 @@ package spdx_test import ( "encoding/json" + "github.com/package-url/packageurl-go" "os" "sort" "testing" @@ -38,7 +39,23 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", + }, + }, + }, + }, + }, + Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: ftypes.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -54,7 +71,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -63,7 +90,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -77,7 +114,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", + }, + }, + }, + Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -88,7 +135,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Type: "jar", Libraries: ftypes.Packages{ { - Name: "org.codehaus.mojo:child-project", + Name: "org.codehaus.mojo:child-project", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", + }, + }, + }, Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0", Version: "1.0", Layer: ftypes.Layer{ @@ -101,8 +158,17 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Type: "node-pkg", Libraries: ftypes.Packages{ { - Name: "bootstrap", - Version: "5.0.2", + Name: "bootstrap", + Version: "5.0.2", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", + }, + }, + }, Ref: "pkg:npm/bootstrap@5.0.2", Licenses: []string{"MIT"}, Layer: ftypes.Layer{ @@ -127,27 +193,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "yargs-parser", Version: "21.1.1", Licenses: []string{"ISC"}, - Ref: "pkg:npm/yargs-parser@21.1.1", - FilePath: "node_modules/yargs-parser/package.json", - }, - }, - }, - }, - }, - }, - { - name: "happy path for bom with hasFiles field", - inputFile: "testdata/happy/with-hasfiles-bom.json", - want: types.SBOM{ - Applications: []ftypes.Application{ - { - Type: "node-pkg", - Libraries: ftypes.Packages{ - { - ID: "yargs-parser@21.1.1", - Name: "yargs-parser", - Version: "21.1.1", - Licenses: []string{"ISC"}, + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "yargs-parser", + Version: "21.1.1", + }, + }, + }, Ref: "pkg:npm/yargs-parser@21.1.1", FilePath: "node_modules/yargs-parser/package.json", }, @@ -169,6 +223,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "yargs-parser", Version: "21.1.1", Licenses: []string{"ISC"}, + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "yargs-parser", + Version: "21.1.1", + }, + }, + }, Ref: "pkg:npm/yargs-parser@21.1.1", FilePath: "node_modules/yargs-parser/package.json", }, @@ -189,13 +252,33 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", + }, + }, + }, + Ref: "pkg:composer/pear/log@1.13.1", }, { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", + }, + }, + }, + Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -214,13 +297,33 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { FilePath: "modules/apm/elastic-apm-agent-1.36.0.jar", Name: "co.elastic.apm:apm-agent", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", + }, + }, + }, + Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", }, { FilePath: "modules/apm/elastic-apm-agent-1.36.0.jar", Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", + }, + }, + }, + Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", }, }, }, diff --git a/pkg/types/vulnerability.go b/pkg/types/vulnerability.go index 488a7d635184..4727d5009083 100644 --- a/pkg/types/vulnerability.go +++ b/pkg/types/vulnerability.go @@ -7,19 +7,21 @@ import ( // DetectedVulnerability holds the information of detected vulnerabilities type DetectedVulnerability struct { - VulnerabilityID string `json:",omitempty"` - VendorIDs []string `json:",omitempty"` - PkgID string `json:",omitempty"` // It is used to construct dependency graph. - PkgName string `json:",omitempty"` - PkgPath string `json:",omitempty"` // This field is populated in the case of language-specific packages such as egg/wheel and gemspec - InstalledVersion string `json:",omitempty"` - FixedVersion string `json:",omitempty"` - Status types.Status `json:",omitempty"` - Layer ftypes.Layer `json:",omitempty"` - SeveritySource types.SourceID `json:",omitempty"` - PrimaryURL string `json:",omitempty"` + VulnerabilityID string `json:",omitempty"` + VendorIDs []string `json:",omitempty"` + PkgID string `json:",omitempty"` // It is used to construct dependency graph. + PkgName string `json:",omitempty"` + PkgPath string `json:",omitempty"` // This field is populated in the case of language-specific packages such as egg/wheel and gemspec + PkgIdentifier ftypes.PkgIdentifier `json:",omitempty"` + InstalledVersion string `json:",omitempty"` + FixedVersion string `json:",omitempty"` + Status types.Status `json:",omitempty"` + Layer ftypes.Layer `json:",omitempty"` + SeveritySource types.SourceID `json:",omitempty"` + PrimaryURL string `json:",omitempty"` - // PkgRef is populated only when scanning SBOM and contains the reference ID used in the SBOM. + // TO BE DEPRECATED - use PkgIdentifier instead + // Only used when scanning SBOM and contains the reference ID used in it. // It could be PURL, UUID, etc. // e.g. // - pkg:npm/acme/component@1.0.0 diff --git a/pkg/vex/testdata/cyclonedx.json b/pkg/vex/testdata/cyclonedx.json index 61b97de17ada..a85d430dbc69 100644 --- a/pkg/vex/testdata/cyclonedx.json +++ b/pkg/vex/testdata/cyclonedx.json @@ -15,7 +15,7 @@ }, "affects": [ { - "ref": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#jackson-databind-2.8.0" + "ref": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.8.0" } ] } diff --git a/pkg/vex/testdata/openvex-multiple.json b/pkg/vex/testdata/openvex-multiple.json index acb027dc343e..11c9ac5d192e 100644 --- a/pkg/vex/testdata/openvex-multiple.json +++ b/pkg/vex/testdata/openvex-multiple.json @@ -11,7 +11,9 @@ "name": "CVE-2021-44228" }, "products": [ - {"@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0"} + { + "@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0" + } ], "status": "affected" }, @@ -20,7 +22,9 @@ "name": "CVE-2021-44228" }, "products": [ - {"@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0"} + { + "@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0" + } ], "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path" diff --git a/pkg/vex/testdata/openvex.json b/pkg/vex/testdata/openvex.json index e1dd960bfb1f..4acaf3aff95e 100644 --- a/pkg/vex/testdata/openvex.json +++ b/pkg/vex/testdata/openvex.json @@ -10,7 +10,9 @@ "name": "CVE-2021-44228" }, "products": [ - {"@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0"} + { + "@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0" + } ], "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path" diff --git a/pkg/vex/vex.go b/pkg/vex/vex.go index 05786d90dc14..fb64984bda6e 100644 --- a/pkg/vex/vex.go +++ b/pkg/vex/vex.go @@ -50,7 +50,13 @@ func newOpenVEX(vex openvex.VEX) VEX { func (v *OpenVEX) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { - stmts := v.vex.Matches(vuln.VulnerabilityID, vuln.PkgRef, nil) + var stmts []openvex.Statement + if vuln.PkgIdentifier.PURL != nil { + matchedStmts := v.vex.Matches(vuln.VulnerabilityID, vuln.PkgIdentifier.PURL.String(), nil) + if len(matchedStmts) > 0 { + stmts = append(stmts, matchedStmts...) + } + } if len(stmts) == 0 { return true } @@ -122,8 +128,7 @@ func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) b zap.Int("version", link.Version())) continue } - if vuln.PkgRef == link.Reference() && - (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { + if v.matchRef(vuln, link.Reference()) && (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), zap.String("status", string(stmt.Status)), zap.String("justification", stmt.Justification)) return false @@ -132,6 +137,16 @@ func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) b return true } +func (v *CycloneDX) matchRef(vuln types.DetectedVulnerability, ref string) bool { + switch { + case vuln.PkgRef == ref: // BOM-Ref + return true + case vuln.PkgIdentifier.PURL != nil && vuln.PkgIdentifier.PURL.String() == ref: // PURL + return true + } + return false +} + func cdxStatus(s cdx.ImpactAnalysisState) Status { switch s { case cdx.IASResolved, cdx.IASResolvedWithPedigree: diff --git a/pkg/vex/vex_test.go b/pkg/vex/vex_test.go index 45f8f7a5cf37..16abcf2a7ffa 100644 --- a/pkg/vex/vex_test.go +++ b/pkg/vex/vex_test.go @@ -1,6 +1,7 @@ package vex_test import ( + "github.com/package-url/packageurl-go" "os" "testing" @@ -43,7 +44,16 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2021-44228", PkgName: "spring-boot", InstalledVersion: "2.6.0", - PkgRef: "pkg:maven/org.springframework.boot/spring-boot@2.6.0?type=pom", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", + }, + }, + }, }, }, }, @@ -60,13 +70,31 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2021-44228", PkgName: "spring-boot", InstalledVersion: "2.6.0", - PkgRef: "pkg:maven/org.springframework.boot/spring-boot@2.6.0?type=pom", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", + }, + }, + }, }, { VulnerabilityID: "CVE-2021-0001", PkgName: "spring-boot", InstalledVersion: "2.6.0", - PkgRef: "pkg:maven/org.springframework.boot/spring-boot@2.6.0?type=pom", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", + }, + }, + }, }, }, }, @@ -75,7 +103,16 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2021-0001", PkgName: "spring-boot", InstalledVersion: "2.6.0", - PkgRef: "pkg:maven/org.springframework.boot/spring-boot@2.6.0?type=pom", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", + }, + }, + }, }, }, }, @@ -96,13 +133,31 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2018-7489", PkgName: "jackson-databind", InstalledVersion: "2.8.0", - PkgRef: "jackson-databind-2.8.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", + }, + }, + }, }, { VulnerabilityID: "CVE-2018-7490", PkgName: "jackson-databind", InstalledVersion: "2.8.0", - PkgRef: "jackson-databind-2.8.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", + }, + }, + }, }, }, }, @@ -111,7 +166,16 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2018-7490", PkgName: "jackson-databind", InstalledVersion: "2.8.0", - PkgRef: "jackson-databind-2.8.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", + }, + }, + }, }, }, }, @@ -132,7 +196,16 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2018-7489", PkgName: "jackson-databind", InstalledVersion: "2.8.0", - PkgRef: "jackson-databind-2.8.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", + }, + }, + }, }, }, }, @@ -141,7 +214,16 @@ func TestVEX_Filter(t *testing.T) { VulnerabilityID: "CVE-2018-7489", PkgName: "jackson-databind", InstalledVersion: "2.8.0", - PkgRef: "jackson-databind-2.8.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", + }, + }, + }, }, }, }, diff --git a/rpc/common/service.pb.go b/rpc/common/service.pb.go index 7183f59f6a24..fcae12028a0f 100644 --- a/rpc/common/service.pb.go +++ b/rpc/common/service.pb.go @@ -138,7 +138,7 @@ func (x LicenseCategory_Enum) Number() protoreflect.EnumNumber { // Deprecated: Use LicenseCategory_Enum.Descriptor instead. func (LicenseCategory_Enum) EnumDescriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{22, 0} + return file_rpc_common_service_proto_rawDescGZIP(), []int{23, 0} } type LicenseType_Enum int32 @@ -190,7 +190,7 @@ func (x LicenseType_Enum) Number() protoreflect.EnumNumber { // Deprecated: Use LicenseType_Enum.Descriptor instead. func (LicenseType_Enum) EnumDescriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{23, 0} + return file_rpc_common_service_proto_rawDescGZIP(), []int{24, 0} } type OS struct { @@ -444,12 +444,13 @@ type Package struct { // binary package // e.g. bind-utils - Id string `protobuf:"bytes,13,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - Release string `protobuf:"bytes,3,opt,name=release,proto3" json:"release,omitempty"` - Epoch int32 `protobuf:"varint,4,opt,name=epoch,proto3" json:"epoch,omitempty"` - Arch string `protobuf:"bytes,5,opt,name=arch,proto3" json:"arch,omitempty"` + Id string `protobuf:"bytes,13,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Release string `protobuf:"bytes,3,opt,name=release,proto3" json:"release,omitempty"` + Epoch int32 `protobuf:"varint,4,opt,name=epoch,proto3" json:"epoch,omitempty"` + Identifier *PkgIdentifier `protobuf:"bytes,19,opt,name=identifier,proto3" json:"identifier,omitempty"` + Arch string `protobuf:"bytes,5,opt,name=arch,proto3" json:"arch,omitempty"` // src package containing some binary packages // e.g. bind SrcName string `protobuf:"bytes,6,opt,name=src_name,json=srcName,proto3" json:"src_name,omitempty"` @@ -532,6 +533,13 @@ func (x *Package) GetEpoch() int32 { return 0 } +func (x *Package) GetIdentifier() *PkgIdentifier { + if x != nil { + return x.Identifier + } + return nil +} + func (x *Package) GetArch() string { if x != nil { return x.Arch @@ -616,6 +624,61 @@ func (x *Package) GetIndirect() bool { return false } +type PkgIdentifier struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Purl string `protobuf:"bytes,1,opt,name=purl,proto3" json:"purl,omitempty"` + Cpe string `protobuf:"bytes,2,opt,name=cpe,proto3" json:"cpe,omitempty"` +} + +func (x *PkgIdentifier) Reset() { + *x = PkgIdentifier{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_common_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PkgIdentifier) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PkgIdentifier) ProtoMessage() {} + +func (x *PkgIdentifier) ProtoReflect() protoreflect.Message { + mi := &file_rpc_common_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PkgIdentifier.ProtoReflect.Descriptor instead. +func (*PkgIdentifier) Descriptor() ([]byte, []int) { + return file_rpc_common_service_proto_rawDescGZIP(), []int{5} +} + +func (x *PkgIdentifier) GetPurl() string { + if x != nil { + return x.Purl + } + return "" +} + +func (x *PkgIdentifier) GetCpe() string { + if x != nil { + return x.Cpe + } + return "" +} + type Misconfiguration struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -632,7 +695,7 @@ type Misconfiguration struct { func (x *Misconfiguration) Reset() { *x = Misconfiguration{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[5] + mi := &file_rpc_common_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -645,7 +708,7 @@ func (x *Misconfiguration) String() string { func (*Misconfiguration) ProtoMessage() {} func (x *Misconfiguration) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[5] + mi := &file_rpc_common_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -658,7 +721,7 @@ func (x *Misconfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use Misconfiguration.ProtoReflect.Descriptor instead. func (*Misconfiguration) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{5} + return file_rpc_common_service_proto_rawDescGZIP(), []int{6} } func (x *Misconfiguration) GetFileType() string { @@ -717,7 +780,7 @@ type MisconfResult struct { func (x *MisconfResult) Reset() { *x = MisconfResult{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[6] + mi := &file_rpc_common_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -730,7 +793,7 @@ func (x *MisconfResult) String() string { func (*MisconfResult) ProtoMessage() {} func (x *MisconfResult) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[6] + mi := &file_rpc_common_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -743,7 +806,7 @@ func (x *MisconfResult) ProtoReflect() protoreflect.Message { // Deprecated: Use MisconfResult.ProtoReflect.Descriptor instead. func (*MisconfResult) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{6} + return file_rpc_common_service_proto_rawDescGZIP(), []int{7} } func (x *MisconfResult) GetNamespace() string { @@ -792,7 +855,7 @@ type PolicyMetadata struct { func (x *PolicyMetadata) Reset() { *x = PolicyMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[7] + mi := &file_rpc_common_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -805,7 +868,7 @@ func (x *PolicyMetadata) String() string { func (*PolicyMetadata) ProtoMessage() {} func (x *PolicyMetadata) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[7] + mi := &file_rpc_common_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -818,7 +881,7 @@ func (x *PolicyMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyMetadata.ProtoReflect.Descriptor instead. func (*PolicyMetadata) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{7} + return file_rpc_common_service_proto_rawDescGZIP(), []int{8} } func (x *PolicyMetadata) GetId() string { @@ -902,7 +965,7 @@ type DetectedMisconfiguration struct { func (x *DetectedMisconfiguration) Reset() { *x = DetectedMisconfiguration{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[8] + mi := &file_rpc_common_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -915,7 +978,7 @@ func (x *DetectedMisconfiguration) String() string { func (*DetectedMisconfiguration) ProtoMessage() {} func (x *DetectedMisconfiguration) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[8] + mi := &file_rpc_common_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -928,7 +991,7 @@ func (x *DetectedMisconfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectedMisconfiguration.ProtoReflect.Descriptor instead. func (*DetectedMisconfiguration) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{8} + return file_rpc_common_service_proto_rawDescGZIP(), []int{9} } func (x *DetectedMisconfiguration) GetType() string { @@ -1049,6 +1112,7 @@ type Vulnerability struct { Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` Severity Severity `protobuf:"varint,7,opt,name=severity,proto3,enum=trivy.common.Severity" json:"severity,omitempty"` References []string `protobuf:"bytes,8,rep,name=references,proto3" json:"references,omitempty"` + PkgIdentifier *PkgIdentifier `protobuf:"bytes,25,opt,name=pkg_identifier,json=pkgIdentifier,proto3" json:"pkg_identifier,omitempty"` Layer *Layer `protobuf:"bytes,10,opt,name=layer,proto3" json:"layer,omitempty"` SeveritySource string `protobuf:"bytes,11,opt,name=severity_source,json=severitySource,proto3" json:"severity_source,omitempty"` Cvss map[string]*CVSS `protobuf:"bytes,12,rep,name=cvss,proto3" json:"cvss,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -1069,7 +1133,7 @@ type Vulnerability struct { func (x *Vulnerability) Reset() { *x = Vulnerability{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[9] + mi := &file_rpc_common_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1082,7 +1146,7 @@ func (x *Vulnerability) String() string { func (*Vulnerability) ProtoMessage() {} func (x *Vulnerability) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[9] + mi := &file_rpc_common_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1095,7 +1159,7 @@ func (x *Vulnerability) ProtoReflect() protoreflect.Message { // Deprecated: Use Vulnerability.ProtoReflect.Descriptor instead. func (*Vulnerability) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{9} + return file_rpc_common_service_proto_rawDescGZIP(), []int{10} } func (x *Vulnerability) GetVulnerabilityId() string { @@ -1154,6 +1218,13 @@ func (x *Vulnerability) GetReferences() []string { return nil } +func (x *Vulnerability) GetPkgIdentifier() *PkgIdentifier { + if x != nil { + return x.PkgIdentifier + } + return nil +} + func (x *Vulnerability) GetLayer() *Layer { if x != nil { return x.Layer @@ -1272,7 +1343,7 @@ type DataSource struct { func (x *DataSource) Reset() { *x = DataSource{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[10] + mi := &file_rpc_common_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1285,7 +1356,7 @@ func (x *DataSource) String() string { func (*DataSource) ProtoMessage() {} func (x *DataSource) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[10] + mi := &file_rpc_common_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1298,7 +1369,7 @@ func (x *DataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSource.ProtoReflect.Descriptor instead. func (*DataSource) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{10} + return file_rpc_common_service_proto_rawDescGZIP(), []int{11} } func (x *DataSource) GetId() string { @@ -1335,7 +1406,7 @@ type Layer struct { func (x *Layer) Reset() { *x = Layer{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[11] + mi := &file_rpc_common_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1348,7 +1419,7 @@ func (x *Layer) String() string { func (*Layer) ProtoMessage() {} func (x *Layer) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[11] + mi := &file_rpc_common_service_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1361,7 +1432,7 @@ func (x *Layer) ProtoReflect() protoreflect.Message { // Deprecated: Use Layer.ProtoReflect.Descriptor instead. func (*Layer) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{11} + return file_rpc_common_service_proto_rawDescGZIP(), []int{12} } func (x *Layer) GetDigest() string { @@ -1401,7 +1472,7 @@ type CauseMetadata struct { func (x *CauseMetadata) Reset() { *x = CauseMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[12] + mi := &file_rpc_common_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1414,7 +1485,7 @@ func (x *CauseMetadata) String() string { func (*CauseMetadata) ProtoMessage() {} func (x *CauseMetadata) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[12] + mi := &file_rpc_common_service_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1427,7 +1498,7 @@ func (x *CauseMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use CauseMetadata.ProtoReflect.Descriptor instead. func (*CauseMetadata) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{12} + return file_rpc_common_service_proto_rawDescGZIP(), []int{13} } func (x *CauseMetadata) GetResource() string { @@ -1486,7 +1557,7 @@ type CVSS struct { func (x *CVSS) Reset() { *x = CVSS{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[13] + mi := &file_rpc_common_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1499,7 +1570,7 @@ func (x *CVSS) String() string { func (*CVSS) ProtoMessage() {} func (x *CVSS) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[13] + mi := &file_rpc_common_service_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1512,7 +1583,7 @@ func (x *CVSS) ProtoReflect() protoreflect.Message { // Deprecated: Use CVSS.ProtoReflect.Descriptor instead. func (*CVSS) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{13} + return file_rpc_common_service_proto_rawDescGZIP(), []int{14} } func (x *CVSS) GetV2Vector() string { @@ -1557,7 +1628,7 @@ type CustomResource struct { func (x *CustomResource) Reset() { *x = CustomResource{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[14] + mi := &file_rpc_common_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1570,7 +1641,7 @@ func (x *CustomResource) String() string { func (*CustomResource) ProtoMessage() {} func (x *CustomResource) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[14] + mi := &file_rpc_common_service_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1583,7 +1654,7 @@ func (x *CustomResource) ProtoReflect() protoreflect.Message { // Deprecated: Use CustomResource.ProtoReflect.Descriptor instead. func (*CustomResource) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{14} + return file_rpc_common_service_proto_rawDescGZIP(), []int{15} } func (x *CustomResource) GetType() string { @@ -1632,7 +1703,7 @@ type Line struct { func (x *Line) Reset() { *x = Line{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[15] + mi := &file_rpc_common_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1645,7 +1716,7 @@ func (x *Line) String() string { func (*Line) ProtoMessage() {} func (x *Line) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[15] + mi := &file_rpc_common_service_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1658,7 +1729,7 @@ func (x *Line) ProtoReflect() protoreflect.Message { // Deprecated: Use Line.ProtoReflect.Descriptor instead. func (*Line) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{15} + return file_rpc_common_service_proto_rawDescGZIP(), []int{16} } func (x *Line) GetNumber() int32 { @@ -1728,7 +1799,7 @@ type Code struct { func (x *Code) Reset() { *x = Code{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[16] + mi := &file_rpc_common_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1741,7 +1812,7 @@ func (x *Code) String() string { func (*Code) ProtoMessage() {} func (x *Code) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[16] + mi := &file_rpc_common_service_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1754,7 +1825,7 @@ func (x *Code) ProtoReflect() protoreflect.Message { // Deprecated: Use Code.ProtoReflect.Descriptor instead. func (*Code) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{16} + return file_rpc_common_service_proto_rawDescGZIP(), []int{17} } func (x *Code) GetLines() []*Line { @@ -1783,7 +1854,7 @@ type SecretFinding struct { func (x *SecretFinding) Reset() { *x = SecretFinding{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[17] + mi := &file_rpc_common_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1796,7 +1867,7 @@ func (x *SecretFinding) String() string { func (*SecretFinding) ProtoMessage() {} func (x *SecretFinding) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[17] + mi := &file_rpc_common_service_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1809,7 +1880,7 @@ func (x *SecretFinding) ProtoReflect() protoreflect.Message { // Deprecated: Use SecretFinding.ProtoReflect.Descriptor instead. func (*SecretFinding) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{17} + return file_rpc_common_service_proto_rawDescGZIP(), []int{18} } func (x *SecretFinding) GetRuleId() string { @@ -1887,7 +1958,7 @@ type Secret struct { func (x *Secret) Reset() { *x = Secret{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[18] + mi := &file_rpc_common_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1900,7 +1971,7 @@ func (x *Secret) String() string { func (*Secret) ProtoMessage() {} func (x *Secret) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[18] + mi := &file_rpc_common_service_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1913,7 +1984,7 @@ func (x *Secret) ProtoReflect() protoreflect.Message { // Deprecated: Use Secret.ProtoReflect.Descriptor instead. func (*Secret) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{18} + return file_rpc_common_service_proto_rawDescGZIP(), []int{19} } func (x *Secret) GetFilepath() string { @@ -1947,7 +2018,7 @@ type DetectedLicense struct { func (x *DetectedLicense) Reset() { *x = DetectedLicense{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[19] + mi := &file_rpc_common_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1960,7 +2031,7 @@ func (x *DetectedLicense) String() string { func (*DetectedLicense) ProtoMessage() {} func (x *DetectedLicense) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[19] + mi := &file_rpc_common_service_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1973,7 +2044,7 @@ func (x *DetectedLicense) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectedLicense.ProtoReflect.Descriptor instead. func (*DetectedLicense) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{19} + return file_rpc_common_service_proto_rawDescGZIP(), []int{20} } func (x *DetectedLicense) GetSeverity() Severity { @@ -2040,7 +2111,7 @@ type LicenseFile struct { func (x *LicenseFile) Reset() { *x = LicenseFile{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[20] + mi := &file_rpc_common_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2053,7 +2124,7 @@ func (x *LicenseFile) String() string { func (*LicenseFile) ProtoMessage() {} func (x *LicenseFile) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[20] + mi := &file_rpc_common_service_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2066,7 +2137,7 @@ func (x *LicenseFile) ProtoReflect() protoreflect.Message { // Deprecated: Use LicenseFile.ProtoReflect.Descriptor instead. func (*LicenseFile) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{20} + return file_rpc_common_service_proto_rawDescGZIP(), []int{21} } func (x *LicenseFile) GetLicenseType() LicenseType_Enum { @@ -2118,7 +2189,7 @@ type LicenseFinding struct { func (x *LicenseFinding) Reset() { *x = LicenseFinding{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[21] + mi := &file_rpc_common_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2131,7 +2202,7 @@ func (x *LicenseFinding) String() string { func (*LicenseFinding) ProtoMessage() {} func (x *LicenseFinding) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[21] + mi := &file_rpc_common_service_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2144,7 +2215,7 @@ func (x *LicenseFinding) ProtoReflect() protoreflect.Message { // Deprecated: Use LicenseFinding.ProtoReflect.Descriptor instead. func (*LicenseFinding) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{21} + return file_rpc_common_service_proto_rawDescGZIP(), []int{22} } func (x *LicenseFinding) GetCategory() LicenseCategory_Enum { @@ -2187,7 +2258,7 @@ type LicenseCategory struct { func (x *LicenseCategory) Reset() { *x = LicenseCategory{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[22] + mi := &file_rpc_common_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2200,7 +2271,7 @@ func (x *LicenseCategory) String() string { func (*LicenseCategory) ProtoMessage() {} func (x *LicenseCategory) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[22] + mi := &file_rpc_common_service_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2213,7 +2284,7 @@ func (x *LicenseCategory) ProtoReflect() protoreflect.Message { // Deprecated: Use LicenseCategory.ProtoReflect.Descriptor instead. func (*LicenseCategory) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{22} + return file_rpc_common_service_proto_rawDescGZIP(), []int{23} } type LicenseType struct { @@ -2225,7 +2296,7 @@ type LicenseType struct { func (x *LicenseType) Reset() { *x = LicenseType{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_common_service_proto_msgTypes[23] + mi := &file_rpc_common_service_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2238,7 +2309,7 @@ func (x *LicenseType) String() string { func (*LicenseType) ProtoMessage() {} func (x *LicenseType) ProtoReflect() protoreflect.Message { - mi := &file_rpc_common_service_proto_msgTypes[23] + mi := &file_rpc_common_service_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2251,7 +2322,7 @@ func (x *LicenseType) ProtoReflect() protoreflect.Message { // Deprecated: Use LicenseType.ProtoReflect.Descriptor instead. func (*LicenseType) Descriptor() ([]byte, []int) { - return file_rpc_common_service_proto_rawDescGZIP(), []int{23} + return file_rpc_common_service_proto_rawDescGZIP(), []int{24} } var File_rpc_common_service_proto protoreflect.FileDescriptor @@ -2286,7 +2357,7 @@ var file_rpc_common_service_proto_rawDesc = []byte{ 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x33, 0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x22, 0xce, 0x03, + 0x67, 0x65, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x22, 0x8b, 0x04, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, @@ -2294,332 +2365,343 @@ var file_rpc_common_service_proto_rawDesc = []byte{ 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x73, - 0x72, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x72, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x72, 0x63, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x72, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x72, - 0x63, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x72, 0x63, 0x5f, - 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x72, 0x63, - 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, - 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x70, - 0x65, 0x6e, 0x64, 0x73, 0x5f, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, - 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0x4f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x64, 0x65, 0x76, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x64, - 0x65, 0x76, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0xb6, - 0x02, 0x0a, 0x10, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x39, 0x0a, - 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x73, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, - 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, - 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, - 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x65, 0x78, - 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, - 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0a, 0x65, 0x78, 0x63, - 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x4d, 0x69, 0x73, 0x63, - 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, - 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0e, 0x63, 0x61, 0x75, 0x73, - 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x63, - 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, - 0x10, 0x07, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x52, 0x02, 0x69, 0x64, 0x52, 0x05, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x22, 0xf0, 0x01, - 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x15, 0x0a, 0x06, 0x61, 0x64, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x61, 0x64, 0x76, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, - 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, - 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x08, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x22, 0xf7, 0x03, 0x0a, 0x18, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x73, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, - 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, - 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3b, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, + 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6b, 0x67, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x72, 0x63, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x72, 0x63, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x72, 0x63, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x72, 0x63, 0x5f, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x72, 0x63, 0x45, 0x70, 0x6f, + 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0f, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x29, + 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0e, 0x63, 0x61, 0x75, - 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, - 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x15, 0x0a, - 0x06, 0x61, 0x76, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, - 0x76, 0x64, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0f, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xbb, 0x09, 0x0a, 0x0d, 0x56, - 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x29, 0x0a, 0x10, - 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x78, 0x65, 0x64, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, - 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, - 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, - 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x08, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, - 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x63, 0x76, 0x73, 0x73, 0x18, 0x0c, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, - 0x43, 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x63, 0x76, 0x73, 0x73, 0x12, - 0x17, 0x0a, 0x07, 0x63, 0x77, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x06, 0x63, 0x77, 0x65, 0x49, 0x64, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x12, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x5f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x11, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x63, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x40, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x76, 0x75, 0x6c, 0x6e, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, 0x75, 0x6c, 0x6e, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, - 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x0f, - 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, - 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x15, 0x0a, 0x06, 0x70, 0x6b, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x70, 0x6b, 0x67, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x1a, 0x4b, 0x0a, 0x09, 0x43, 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x56, - 0x53, 0x53, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, - 0x13, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x42, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, - 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x57, 0x0a, 0x05, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0xc3, 0x01, 0x0a, 0x0d, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, - 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, - 0x69, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x76, 0x0a, 0x04, 0x43, - 0x56, 0x53, 0x53, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x32, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x32, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x33, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x33, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x76, 0x32, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x07, 0x76, 0x32, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x33, 0x5f, 0x73, - 0x63, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x76, 0x33, 0x53, 0x63, - 0x6f, 0x72, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, - 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, - 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf3, - 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, - 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x43, - 0x61, 0x75, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, - 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, - 0x68, 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x63, 0x61, - 0x75, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x61, - 0x75, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x43, - 0x61, 0x75, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x05, - 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, - 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, - 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x9f, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, - 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, - 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x5d, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, - 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, - 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, + 0x73, 0x5f, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x73, 0x4f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x65, 0x76, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x64, 0x65, 0x76, 0x12, + 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x35, 0x0a, 0x0d, 0x50, + 0x6b, 0x67, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x75, 0x72, 0x6c, + 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, + 0x70, 0x65, 0x22, 0xb6, 0x02, 0x0a, 0x10, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x39, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, + 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x0d, + 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0e, + 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x4a, 0x04, 0x08, 0x03, 0x10, 0x07, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x52, 0x02, 0x69, 0x64, + 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x79, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x64, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x76, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x22, 0xf7, 0x03, 0x0a, 0x18, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, + 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x42, 0x0a, + 0x0e, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x76, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x61, 0x76, 0x64, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xff, + 0x09, 0x0a, 0x0d, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x29, 0x0a, 0x10, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, + 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x70, + 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, + 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x78, 0x65, + 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x70, 0x6b, 0x67, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, + 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6b, 0x67, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0d, 0x70, 0x6b, 0x67, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x04, + 0x63, 0x76, 0x73, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x72, 0x69, + 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x43, 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x63, 0x76, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x77, 0x65, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x63, 0x77, 0x65, 0x49, 0x64, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, + 0x6c, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c, 0x61, + 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, + 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, + 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x64, 0x76, 0x69, + 0x73, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x5f, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x56, 0x75, 0x6c, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x65, + 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x73, + 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, + 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, + 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, + 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x19, + 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x6b, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x70, 0x6b, 0x67, + 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x6b, 0x67, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x4b, 0x0a, 0x09, 0x43, 0x76, 0x73, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x13, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, + 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, - 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, - 0x3e, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, - 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, - 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, - 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, - 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, - 0xed, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, - 0x41, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, + 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x42, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x72, 0x6c, 0x22, 0x57, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, + 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0xc3, 0x01, + 0x0a, 0x0d, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x22, 0x76, 0x0a, 0x04, 0x43, 0x56, 0x53, 0x53, 0x12, 0x1b, 0x0a, 0x09, 0x76, + 0x32, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x76, 0x32, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x33, 0x5f, 0x76, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x33, 0x56, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x32, 0x5f, 0x73, 0x63, 0x6f, 0x72, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x76, 0x32, 0x53, 0x63, 0x6f, 0x72, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x76, 0x33, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x07, 0x76, 0x33, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x0e, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x66, 0x69, - 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, + 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, + 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf3, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, + 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x61, 0x75, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x04, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x9f, + 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x12, 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, + 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, + 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, + 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, + 0x22, 0x5d, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, + 0x85, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, + 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, + 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, + 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xed, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, + 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, + 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0b, 0x6c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, + 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, + 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x05, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, + 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, + 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x67, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, - 0x98, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, - 0x6f, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x95, 0x01, 0x0a, 0x0f, 0x4c, - 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x81, - 0x01, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x42, - 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x53, 0x54, 0x52, - 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x43, 0x49, 0x50, - 0x52, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, - 0x45, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, - 0x45, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x45, 0x4e, 0x43, 0x55, 0x4d, 0x42, 0x45, - 0x52, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x07, 0x22, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3f, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x50, - 0x4b, 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, 0x02, - 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, - 0x10, 0x03, 0x2a, 0x44, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, - 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, - 0x4f, 0x57, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x02, - 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, - 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x71, 0x75, 0x61, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, + 0x6e, 0x6b, 0x22, 0x95, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x81, 0x01, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, + 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x42, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x01, 0x12, + 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, + 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x43, 0x49, 0x50, 0x52, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, + 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x50, + 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, 0x45, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x55, + 0x4e, 0x45, 0x4e, 0x43, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x07, 0x22, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, + 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3f, 0x0a, 0x04, 0x45, 0x6e, 0x75, + 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x50, 0x4b, 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, + 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x43, 0x45, + 0x4e, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x2a, 0x44, 0x0a, 0x08, 0x53, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, + 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, + 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x71, 0x75, 0x61, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, + 0x79, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2635,7 +2717,7 @@ func file_rpc_common_service_proto_rawDescGZIP() []byte { } var file_rpc_common_service_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_rpc_common_service_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_rpc_common_service_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_rpc_common_service_proto_goTypes = []interface{}{ (Severity)(0), // 0: trivy.common.Severity (LicenseCategory_Enum)(0), // 1: trivy.common.LicenseCategory.Enum @@ -2645,72 +2727,75 @@ var file_rpc_common_service_proto_goTypes = []interface{}{ (*PackageInfo)(nil), // 5: trivy.common.PackageInfo (*Application)(nil), // 6: trivy.common.Application (*Package)(nil), // 7: trivy.common.Package - (*Misconfiguration)(nil), // 8: trivy.common.Misconfiguration - (*MisconfResult)(nil), // 9: trivy.common.MisconfResult - (*PolicyMetadata)(nil), // 10: trivy.common.PolicyMetadata - (*DetectedMisconfiguration)(nil), // 11: trivy.common.DetectedMisconfiguration - (*Vulnerability)(nil), // 12: trivy.common.Vulnerability - (*DataSource)(nil), // 13: trivy.common.DataSource - (*Layer)(nil), // 14: trivy.common.Layer - (*CauseMetadata)(nil), // 15: trivy.common.CauseMetadata - (*CVSS)(nil), // 16: trivy.common.CVSS - (*CustomResource)(nil), // 17: trivy.common.CustomResource - (*Line)(nil), // 18: trivy.common.Line - (*Code)(nil), // 19: trivy.common.Code - (*SecretFinding)(nil), // 20: trivy.common.SecretFinding - (*Secret)(nil), // 21: trivy.common.Secret - (*DetectedLicense)(nil), // 22: trivy.common.DetectedLicense - (*LicenseFile)(nil), // 23: trivy.common.LicenseFile - (*LicenseFinding)(nil), // 24: trivy.common.LicenseFinding - (*LicenseCategory)(nil), // 25: trivy.common.LicenseCategory - (*LicenseType)(nil), // 26: trivy.common.LicenseType - nil, // 27: trivy.common.Vulnerability.CvssEntry - nil, // 28: trivy.common.Vulnerability.VendorSeverityEntry - (*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp - (*structpb.Value)(nil), // 30: google.protobuf.Value + (*PkgIdentifier)(nil), // 8: trivy.common.PkgIdentifier + (*Misconfiguration)(nil), // 9: trivy.common.Misconfiguration + (*MisconfResult)(nil), // 10: trivy.common.MisconfResult + (*PolicyMetadata)(nil), // 11: trivy.common.PolicyMetadata + (*DetectedMisconfiguration)(nil), // 12: trivy.common.DetectedMisconfiguration + (*Vulnerability)(nil), // 13: trivy.common.Vulnerability + (*DataSource)(nil), // 14: trivy.common.DataSource + (*Layer)(nil), // 15: trivy.common.Layer + (*CauseMetadata)(nil), // 16: trivy.common.CauseMetadata + (*CVSS)(nil), // 17: trivy.common.CVSS + (*CustomResource)(nil), // 18: trivy.common.CustomResource + (*Line)(nil), // 19: trivy.common.Line + (*Code)(nil), // 20: trivy.common.Code + (*SecretFinding)(nil), // 21: trivy.common.SecretFinding + (*Secret)(nil), // 22: trivy.common.Secret + (*DetectedLicense)(nil), // 23: trivy.common.DetectedLicense + (*LicenseFile)(nil), // 24: trivy.common.LicenseFile + (*LicenseFinding)(nil), // 25: trivy.common.LicenseFinding + (*LicenseCategory)(nil), // 26: trivy.common.LicenseCategory + (*LicenseType)(nil), // 27: trivy.common.LicenseType + nil, // 28: trivy.common.Vulnerability.CvssEntry + nil, // 29: trivy.common.Vulnerability.VendorSeverityEntry + (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp + (*structpb.Value)(nil), // 31: google.protobuf.Value } var file_rpc_common_service_proto_depIdxs = []int32{ 7, // 0: trivy.common.PackageInfo.packages:type_name -> trivy.common.Package 7, // 1: trivy.common.Application.libraries:type_name -> trivy.common.Package - 14, // 2: trivy.common.Package.layer:type_name -> trivy.common.Layer - 9, // 3: trivy.common.Misconfiguration.successes:type_name -> trivy.common.MisconfResult - 9, // 4: trivy.common.Misconfiguration.warnings:type_name -> trivy.common.MisconfResult - 9, // 5: trivy.common.Misconfiguration.failures:type_name -> trivy.common.MisconfResult - 9, // 6: trivy.common.Misconfiguration.exceptions:type_name -> trivy.common.MisconfResult - 10, // 7: trivy.common.MisconfResult.policy_metadata:type_name -> trivy.common.PolicyMetadata - 15, // 8: trivy.common.MisconfResult.cause_metadata:type_name -> trivy.common.CauseMetadata - 0, // 9: trivy.common.DetectedMisconfiguration.severity:type_name -> trivy.common.Severity - 14, // 10: trivy.common.DetectedMisconfiguration.layer:type_name -> trivy.common.Layer - 15, // 11: trivy.common.DetectedMisconfiguration.cause_metadata:type_name -> trivy.common.CauseMetadata - 0, // 12: trivy.common.Vulnerability.severity:type_name -> trivy.common.Severity - 14, // 13: trivy.common.Vulnerability.layer:type_name -> trivy.common.Layer - 27, // 14: trivy.common.Vulnerability.cvss:type_name -> trivy.common.Vulnerability.CvssEntry - 29, // 15: trivy.common.Vulnerability.published_date:type_name -> google.protobuf.Timestamp - 29, // 16: trivy.common.Vulnerability.last_modified_date:type_name -> google.protobuf.Timestamp - 30, // 17: trivy.common.Vulnerability.custom_advisory_data:type_name -> google.protobuf.Value - 30, // 18: trivy.common.Vulnerability.custom_vuln_data:type_name -> google.protobuf.Value - 13, // 19: trivy.common.Vulnerability.data_source:type_name -> trivy.common.DataSource - 28, // 20: trivy.common.Vulnerability.vendor_severity:type_name -> trivy.common.Vulnerability.VendorSeverityEntry - 19, // 21: trivy.common.CauseMetadata.code:type_name -> trivy.common.Code - 14, // 22: trivy.common.CustomResource.layer:type_name -> trivy.common.Layer - 30, // 23: trivy.common.CustomResource.data:type_name -> google.protobuf.Value - 18, // 24: trivy.common.Code.lines:type_name -> trivy.common.Line - 19, // 25: trivy.common.SecretFinding.code:type_name -> trivy.common.Code - 14, // 26: trivy.common.SecretFinding.layer:type_name -> trivy.common.Layer - 20, // 27: trivy.common.Secret.findings:type_name -> trivy.common.SecretFinding - 0, // 28: trivy.common.DetectedLicense.severity:type_name -> trivy.common.Severity - 1, // 29: trivy.common.DetectedLicense.category:type_name -> trivy.common.LicenseCategory.Enum - 2, // 30: trivy.common.LicenseFile.license_type:type_name -> trivy.common.LicenseType.Enum - 24, // 31: trivy.common.LicenseFile.fingings:type_name -> trivy.common.LicenseFinding - 14, // 32: trivy.common.LicenseFile.layer:type_name -> trivy.common.Layer - 1, // 33: trivy.common.LicenseFinding.category:type_name -> trivy.common.LicenseCategory.Enum - 16, // 34: trivy.common.Vulnerability.CvssEntry.value:type_name -> trivy.common.CVSS - 0, // 35: trivy.common.Vulnerability.VendorSeverityEntry.value:type_name -> trivy.common.Severity - 36, // [36:36] is the sub-list for method output_type - 36, // [36:36] is the sub-list for method input_type - 36, // [36:36] is the sub-list for extension type_name - 36, // [36:36] is the sub-list for extension extendee - 0, // [0:36] is the sub-list for field type_name + 8, // 2: trivy.common.Package.identifier:type_name -> trivy.common.PkgIdentifier + 15, // 3: trivy.common.Package.layer:type_name -> trivy.common.Layer + 10, // 4: trivy.common.Misconfiguration.successes:type_name -> trivy.common.MisconfResult + 10, // 5: trivy.common.Misconfiguration.warnings:type_name -> trivy.common.MisconfResult + 10, // 6: trivy.common.Misconfiguration.failures:type_name -> trivy.common.MisconfResult + 10, // 7: trivy.common.Misconfiguration.exceptions:type_name -> trivy.common.MisconfResult + 11, // 8: trivy.common.MisconfResult.policy_metadata:type_name -> trivy.common.PolicyMetadata + 16, // 9: trivy.common.MisconfResult.cause_metadata:type_name -> trivy.common.CauseMetadata + 0, // 10: trivy.common.DetectedMisconfiguration.severity:type_name -> trivy.common.Severity + 15, // 11: trivy.common.DetectedMisconfiguration.layer:type_name -> trivy.common.Layer + 16, // 12: trivy.common.DetectedMisconfiguration.cause_metadata:type_name -> trivy.common.CauseMetadata + 0, // 13: trivy.common.Vulnerability.severity:type_name -> trivy.common.Severity + 8, // 14: trivy.common.Vulnerability.pkg_identifier:type_name -> trivy.common.PkgIdentifier + 15, // 15: trivy.common.Vulnerability.layer:type_name -> trivy.common.Layer + 28, // 16: trivy.common.Vulnerability.cvss:type_name -> trivy.common.Vulnerability.CvssEntry + 30, // 17: trivy.common.Vulnerability.published_date:type_name -> google.protobuf.Timestamp + 30, // 18: trivy.common.Vulnerability.last_modified_date:type_name -> google.protobuf.Timestamp + 31, // 19: trivy.common.Vulnerability.custom_advisory_data:type_name -> google.protobuf.Value + 31, // 20: trivy.common.Vulnerability.custom_vuln_data:type_name -> google.protobuf.Value + 14, // 21: trivy.common.Vulnerability.data_source:type_name -> trivy.common.DataSource + 29, // 22: trivy.common.Vulnerability.vendor_severity:type_name -> trivy.common.Vulnerability.VendorSeverityEntry + 20, // 23: trivy.common.CauseMetadata.code:type_name -> trivy.common.Code + 15, // 24: trivy.common.CustomResource.layer:type_name -> trivy.common.Layer + 31, // 25: trivy.common.CustomResource.data:type_name -> google.protobuf.Value + 19, // 26: trivy.common.Code.lines:type_name -> trivy.common.Line + 20, // 27: trivy.common.SecretFinding.code:type_name -> trivy.common.Code + 15, // 28: trivy.common.SecretFinding.layer:type_name -> trivy.common.Layer + 21, // 29: trivy.common.Secret.findings:type_name -> trivy.common.SecretFinding + 0, // 30: trivy.common.DetectedLicense.severity:type_name -> trivy.common.Severity + 1, // 31: trivy.common.DetectedLicense.category:type_name -> trivy.common.LicenseCategory.Enum + 2, // 32: trivy.common.LicenseFile.license_type:type_name -> trivy.common.LicenseType.Enum + 25, // 33: trivy.common.LicenseFile.fingings:type_name -> trivy.common.LicenseFinding + 15, // 34: trivy.common.LicenseFile.layer:type_name -> trivy.common.Layer + 1, // 35: trivy.common.LicenseFinding.category:type_name -> trivy.common.LicenseCategory.Enum + 17, // 36: trivy.common.Vulnerability.CvssEntry.value:type_name -> trivy.common.CVSS + 0, // 37: trivy.common.Vulnerability.VendorSeverityEntry.value:type_name -> trivy.common.Severity + 38, // [38:38] is the sub-list for method output_type + 38, // [38:38] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_rpc_common_service_proto_init() } @@ -2780,7 +2865,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Misconfiguration); i { + switch v := v.(*PkgIdentifier); i { case 0: return &v.state case 1: @@ -2792,7 +2877,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MisconfResult); i { + switch v := v.(*Misconfiguration); i { case 0: return &v.state case 1: @@ -2804,7 +2889,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyMetadata); i { + switch v := v.(*MisconfResult); i { case 0: return &v.state case 1: @@ -2816,7 +2901,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DetectedMisconfiguration); i { + switch v := v.(*PolicyMetadata); i { case 0: return &v.state case 1: @@ -2828,7 +2913,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Vulnerability); i { + switch v := v.(*DetectedMisconfiguration); i { case 0: return &v.state case 1: @@ -2840,7 +2925,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataSource); i { + switch v := v.(*Vulnerability); i { case 0: return &v.state case 1: @@ -2852,7 +2937,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Layer); i { + switch v := v.(*DataSource); i { case 0: return &v.state case 1: @@ -2864,7 +2949,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CauseMetadata); i { + switch v := v.(*Layer); i { case 0: return &v.state case 1: @@ -2876,7 +2961,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CVSS); i { + switch v := v.(*CauseMetadata); i { case 0: return &v.state case 1: @@ -2888,7 +2973,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CustomResource); i { + switch v := v.(*CVSS); i { case 0: return &v.state case 1: @@ -2900,7 +2985,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Line); i { + switch v := v.(*CustomResource); i { case 0: return &v.state case 1: @@ -2912,7 +2997,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Code); i { + switch v := v.(*Line); i { case 0: return &v.state case 1: @@ -2924,7 +3009,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecretFinding); i { + switch v := v.(*Code); i { case 0: return &v.state case 1: @@ -2936,7 +3021,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Secret); i { + switch v := v.(*SecretFinding); i { case 0: return &v.state case 1: @@ -2948,7 +3033,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DetectedLicense); i { + switch v := v.(*Secret); i { case 0: return &v.state case 1: @@ -2960,7 +3045,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LicenseFile); i { + switch v := v.(*DetectedLicense); i { case 0: return &v.state case 1: @@ -2972,7 +3057,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LicenseFinding); i { + switch v := v.(*LicenseFile); i { case 0: return &v.state case 1: @@ -2984,7 +3069,7 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LicenseCategory); i { + switch v := v.(*LicenseFinding); i { case 0: return &v.state case 1: @@ -2996,6 +3081,18 @@ func file_rpc_common_service_proto_init() { } } file_rpc_common_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LicenseCategory); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_common_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LicenseType); i { case 0: return &v.state @@ -3014,7 +3111,7 @@ func file_rpc_common_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rpc_common_service_proto_rawDesc, NumEnums: 3, - NumMessages: 26, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/common/service.proto b/rpc/common/service.proto index ee8aaea697d3..375b17684809 100644 --- a/rpc/common/service.proto +++ b/rpc/common/service.proto @@ -33,12 +33,13 @@ message Application { message Package { // binary package // e.g. bind-utils - string id = 13; - string name = 1; - string version = 2; - string release = 3; - int32 epoch = 4; - string arch = 5; + string id = 13; + string name = 1; + string version = 2; + string release = 3; + int32 epoch = 4; + PkgIdentifier identifier = 19; + string arch = 5; // src package containing some binary packages // e.g. bind string src_name = 6; @@ -54,6 +55,11 @@ message Package { bool indirect = 18; } +message PkgIdentifier { + string purl = 1; + string cpe = 2; +} + message Misconfiguration { string file_type = 1; string file_path = 2; @@ -110,6 +116,7 @@ message Vulnerability { string description = 6; Severity severity = 7; repeated string references = 8; + PkgIdentifier pkg_identifier = 25; Layer layer = 10; string severity_source = 11; map cvss = 12; @@ -252,4 +259,4 @@ message LicenseType { HEADER = 2; LICENSE_FILE = 3; } -} \ No newline at end of file +} From c17b6603db71d1e808c89ac6fce8e881722a0b1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 05:26:15 +0000 Subject: [PATCH 053/108] chore(deps): bump github.com/go-git/go-git/v5 from 5.10.1 to 5.11.0 (#5830) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index cac96e6e7337..550f357eeb93 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/color v1.15.0 - github.com/go-git/go-git/v5 v5.10.1 + github.com/go-git/go-git/v5 v5.11.0 github.com/go-openapi/runtime v0.26.0 github.com/go-openapi/strfmt v0.21.7 github.com/go-redis/redis/v8 v8.11.5 @@ -370,7 +370,7 @@ require ( go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.18.0 // indirect + golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.11.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/go.sum b/go.sum index 726b561bd8b8..a9840929c6d0 100644 --- a/go.sum +++ b/go.sum @@ -829,8 +829,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= -github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -1951,8 +1951,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From b3d516eafec6a9d4846fc7a9e5f55dd8931ad434 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:28:13 +0600 Subject: [PATCH 054/108] fix(cyclonedx): fix unmarshal for licenses (#5828) --- .../fixtures/sbom/centos-7-cyclonedx.json | 8 +++-- .../fluentd-multiple-lockfiles-cyclonedx.json | 4 ++- pkg/sbom/cyclonedx/testdata/happy/bom.json | 8 +++-- .../testdata/happy/infinite-loop-bom.json | 12 +++++-- .../testdata/happy/third-party-bom-no-os.json | 4 ++- .../testdata/happy/third-party-bom.json | 9 +++++- pkg/sbom/cyclonedx/unmarshal.go | 32 ++++++++++++++++--- pkg/sbom/cyclonedx/unmarshal_test.go | 3 +- 8 files changed, 65 insertions(+), 15 deletions(-) diff --git a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json index 27eeb322f228..801dea718089 100644 --- a/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json +++ b/integration/testdata/fixtures/sbom/centos-7-cyclonedx.json @@ -40,7 +40,9 @@ "version": "4.2.46-31.el7", "licenses": [ { - "expression": "GPLv3+" + "license": { + "name": "GPLv3+" + } } ], "purl": "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", @@ -78,7 +80,9 @@ "version": "1.0.2k-16.el7", "licenses": [ { - "expression": "OpenSSL" + "license": { + "name": "OpenSSL+" + } } ], "purl": "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", diff --git a/integration/testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json b/integration/testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json index ce7a21e7d25d..f5db904207d1 100644 --- a/integration/testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json +++ b/integration/testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json @@ -126,7 +126,9 @@ "version": "6.0.2.1", "licenses": [ { - "expression": "MIT" + "license": { + "name": "MIT" + } } ], "purl": "pkg:gem/activesupport@6.0.2.1", diff --git a/pkg/sbom/cyclonedx/testdata/happy/bom.json b/pkg/sbom/cyclonedx/testdata/happy/bom.json index 5b47e49d9f39..924daef7f405 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/bom.json @@ -48,7 +48,9 @@ "version": "1.2.3-r0", "licenses": [ { - "expression": "MIT" + "license": { + "name": "MIT" + } } ], "purl": "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", @@ -125,7 +127,9 @@ "version": "5.0.2", "licenses": [ { - "expression": "MIT" + "license": { + "name": "MIT" + } } ], "purl": "pkg:npm/bootstrap@5.0.2", diff --git a/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json b/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json index fc50f7dd441c..b3d039379709 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json @@ -49,13 +49,19 @@ "version": "2.35-0ubuntu3.1", "licenses": [ { - "expression": "LGPL-2.1" + "license": { + "name": "LGPL-2.1" + } }, { - "expression": "GPL-2.0" + "license": { + "name": "GPL-2.0" + } }, { - "expression": "GFDL-1.3" + "license": { + "name": "GFDL-1.3" + } } ], "purl": "pkg:deb/ubuntu/libc6@2.35-0ubuntu3.1?distro=ubuntu-22.04", diff --git a/pkg/sbom/cyclonedx/testdata/happy/third-party-bom-no-os.json b/pkg/sbom/cyclonedx/testdata/happy/third-party-bom-no-os.json index e683fe179355..436b7dcbf892 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/third-party-bom-no-os.json +++ b/pkg/sbom/cyclonedx/testdata/happy/third-party-bom-no-os.json @@ -19,7 +19,9 @@ "version": "1.2.3-r0", "licenses": [ { - "expression": "MIT" + "license": { + "name": "MIT" + } } ], "purl": "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0" diff --git a/pkg/sbom/cyclonedx/testdata/happy/third-party-bom.json b/pkg/sbom/cyclonedx/testdata/happy/third-party-bom.json index a7dd0b6bdb10..d8b5068f5cc0 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/third-party-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/third-party-bom.json @@ -35,7 +35,14 @@ "type": "library", "name": "pear/log", "version": "1.13.1", - "purl": "pkg:composer/pear/log@1.13.1" + "purl": "pkg:composer/pear/log@1.13.1", + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ] }, { "bom-ref": "pkg:composer/pear/pear_exception@v1.0.0", diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index be08c280ed13..73c5046c9947 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -352,10 +352,7 @@ func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, er // so we have to use an original package name pkg.Name = packageName(p.Type, pkg.Name, component) pkg.Ref = component.BOMRef - - for _, license := range lo.FromPtr(component.Licenses) { - pkg.Licenses = append(pkg.Licenses, license.Expression) - } + pkg.Licenses = parsePackageLicenses(component.Licenses) for key, value := range core.UnmarshalProperties(component.Properties) { switch key { @@ -434,3 +431,30 @@ func packageName(typ, pkgNameFromPurl string, component cdx.Component) string { } return component.Name } + +// parsePackageLicenses checks all supported license fields and returns a list of licenses. +// https://cyclonedx.org/docs/1.5/json/#components_items_licenses +func parsePackageLicenses(l *cdx.Licenses) []string { + var licenses []string + for _, license := range lo.FromPtr(l) { + if license.License != nil { + // Trivy uses `Name` field to marshal licenses + if license.License.Name != "" { + licenses = append(licenses, license.License.Name) + continue + } + + if license.License.ID != "" { + licenses = append(licenses, license.License.ID) + continue + } + } + + if license.Expression != "" { + licenses = append(licenses, license.Expression) + continue + } + + } + return licenses +} diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index 0af6121b4ea1..9c9666d319dd 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -479,7 +479,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:composer/pear/log@1.13.1", + Ref: "pkg:composer/pear/log@1.13.1", + Licenses: []string{"MIT"}, }, { From 1607eee77c1d0cb09d5eda1730b5cd5ac7b627aa Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Fri, 29 Dec 2023 10:52:36 +0400 Subject: [PATCH 055/108] refactor: move PkgRef under PkgIdentifier (#5831) Signed-off-by: knqyf263 --- integration/sbom_test.go | 55 +- integration/testdata/conda-spdx.json.golden | 12 +- .../fluentd-multiple-lockfiles.json.golden | 12 +- .../testdata/minikube-kbom.json.golden | 4 +- pkg/detector/library/detect.go | 1 - pkg/detector/ospkg/alma/alma.go | 1 - pkg/detector/ospkg/alpine/alpine.go | 1 - pkg/detector/ospkg/amazon/amazon.go | 1 - pkg/detector/ospkg/chainguard/chainguard.go | 1 - pkg/detector/ospkg/debian/debian.go | 1 - pkg/detector/ospkg/mariner/mariner.go | 1 - pkg/detector/ospkg/oracle/oracle.go | 1 - pkg/detector/ospkg/photon/photon.go | 1 - pkg/detector/ospkg/redhat/redhat.go | 1 - pkg/detector/ospkg/rocky/rocky.go | 1 - pkg/detector/ospkg/suse/suse.go | 1 - pkg/detector/ospkg/ubuntu/ubuntu.go | 1 - pkg/detector/ospkg/wolfi/wolfi.go | 1 - pkg/fanal/analyzer/sbom/sbom_test.go | 13 +- pkg/fanal/applier/docker_test.go | 2 - pkg/fanal/artifact/image/remote_sbom_test.go | 18 +- pkg/fanal/artifact/sbom/sbom_test.go | 36 +- pkg/fanal/cache/mock_artifact_cache.go | 2 +- .../handler/unpackaged/unpackaged_test.go | 2 +- pkg/fanal/types/artifact.go | 24 +- pkg/module/serialize/types_easyjson.go | 36 +- pkg/rpc/convert.go | 22 +- pkg/sbom/cyclonedx/unmarshal.go | 6 +- pkg/sbom/cyclonedx/unmarshal_test.go | 52 +- pkg/sbom/spdx/unmarshal.go | 1 - pkg/sbom/spdx/unmarshal_test.go | 12 - pkg/types/vulnerability.go | 8 - pkg/vex/vex.go | 12 +- rpc/common/service.pb.go | 625 +++++++++--------- rpc/common/service.proto | 22 +- 35 files changed, 462 insertions(+), 528 deletions(-) diff --git a/integration/sbom_test.go b/integration/sbom_test.go index 5b657335d316..dc18cb43bceb 100644 --- a/integration/sbom_test.go +++ b/integration/sbom_test.go @@ -42,13 +42,19 @@ func TestSBOM(t *testing.T) { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ { - PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, }, { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -89,13 +95,19 @@ func TestSBOM(t *testing.T) { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ { - PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", + }, }, { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", + }, }, }, }, @@ -116,17 +128,6 @@ func TestSBOM(t *testing.T) { Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)", - Vulnerabilities: []types.DetectedVulnerability{ - { - PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", - }, - { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", - }, - { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", - }, - }, }, }, }, @@ -145,17 +146,6 @@ func TestSBOM(t *testing.T) { Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)", - Vulnerabilities: []types.DetectedVulnerability{ - { - PkgRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", - }, - { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", - }, - { - PkgRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", - }, - }, }, }, }, @@ -223,12 +213,11 @@ func compareSBOMReports(t *testing.T, wantFile, gotFile string, overrideWant typ for i, result := range overrideWant.Results { want.Results[i].Target = result.Target for j, vuln := range result.Vulnerabilities { - want.Results[i].Vulnerabilities[j].PkgRef = vuln.PkgRef - if vuln.PkgIdentifier.Empty() { - continue + if vuln.PkgIdentifier.PURL != nil { + want.Results[i].Vulnerabilities[j].PkgIdentifier.PURL = vuln.PkgIdentifier.PURL } - want.Results[i].Vulnerabilities[j].PkgIdentifier = ftypes.PkgIdentifier{ - PURL: vuln.PkgIdentifier.PURL, + if vuln.PkgIdentifier.BOMRef != "" { + want.Results[i].Vulnerabilities[j].PkgIdentifier.BOMRef = vuln.PkgIdentifier.BOMRef } } } diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index 4803da139d8c..a201662a7736 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -22,7 +22,7 @@ }, { "name": "openssl", - "SPDXID": "SPDXRef-Package-a4bad823866cc210", + "SPDXID": "SPDXRef-Package-38e5db7a21fc70a8", "versionInfo": "1.1.1q", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -43,7 +43,7 @@ }, { "name": "pip", - "SPDXID": "SPDXRef-Package-e8a0eb2c9979a021", + "SPDXID": "SPDXRef-Package-f9844c873ead5dbe", "versionInfo": "22.2.2", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -110,21 +110,21 @@ }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-a4bad823866cc210", + "relatedSpdxElement": "SPDXRef-Package-38e5db7a21fc70a8", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-a4bad823866cc210", + "spdxElementId": "SPDXRef-Package-38e5db7a21fc70a8", "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-e8a0eb2c9979a021", + "relatedSpdxElement": "SPDXRef-Package-f9844c873ead5dbe", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-e8a0eb2c9979a021", + "spdxElementId": "SPDXRef-Package-f9844c873ead5dbe", "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", "relationshipType": "CONTAINS" } diff --git a/integration/testdata/fluentd-multiple-lockfiles.json.golden b/integration/testdata/fluentd-multiple-lockfiles.json.golden index 784f9f1a0339..23a1ae2a8af3 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.json.golden @@ -29,14 +29,14 @@ "VulnerabilityID": "CVE-2019-18276", "PkgName": "bash", "PkgIdentifier": { - "PURL": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2" + "PURL": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2", + "BOMRef": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2" }, "InstalledVersion": "5.0-4", "Status": "affected", "Layer": {}, "SeveritySource": "debian", "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-18276", - "PkgRef": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2", "DataSource": { "ID": "debian", "Name": "Debian Security Tracker", @@ -92,7 +92,8 @@ ], "PkgName": "libidn2-0", "PkgIdentifier": { - "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2" + "PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2", + "BOMRef": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2" }, "InstalledVersion": "2.0.5-1", "FixedVersion": "2.0.5-1+deb10u1", @@ -100,7 +101,6 @@ "Layer": {}, "SeveritySource": "nvd", "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-18224", - "PkgRef": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2", "DataSource": { "ID": "debian", "Name": "Debian Security Tracker", @@ -161,7 +161,8 @@ "PkgName": "activesupport", "PkgPath": "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", "PkgIdentifier": { - "PURL": "pkg:gem/activesupport@6.0.2.1" + "PURL": "pkg:gem/activesupport@6.0.2.1", + "BOMRef": "pkg:gem/activesupport@6.0.2.1?file_path=var%2Flib%2Fgems%2F2.5.0%2Fspecifications%2Factivesupport-6.0.2.1.gemspec" }, "InstalledVersion": "6.0.2.1", "FixedVersion": "6.0.3.1, 5.2.4.3", @@ -169,7 +170,6 @@ "Layer": {}, "SeveritySource": "ghsa", "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2020-8165", - "PkgRef": "pkg:gem/activesupport@6.0.2.1?file_path=var%2Flib%2Fgems%2F2.5.0%2Fspecifications%2Factivesupport-6.0.2.1.gemspec", "DataSource": { "ID": "ghsa", "Name": "GitHub Security Advisory RubyGems", diff --git a/integration/testdata/minikube-kbom.json.golden b/integration/testdata/minikube-kbom.json.golden index 5a4ee8ed2949..080e061142e8 100644 --- a/integration/testdata/minikube-kbom.json.golden +++ b/integration/testdata/minikube-kbom.json.golden @@ -34,7 +34,8 @@ "VulnerabilityID": "CVE-2023-2431", "PkgName": "k8s.io/kubelet", "PkgIdentifier": { - "PURL": "pkg:k8s/k8s.io%2Fkubelet@1.27.0" + "PURL": "pkg:k8s/k8s.io%2Fkubelet@1.27.0", + "BOMRef": "pkg:k8s/k8s.io%2Fkubelet@1.27.0" }, "InstalledVersion": "1.27.0", "FixedVersion": "1.24.14, 1.25.9, 1.26.4, 1.27.1", @@ -42,7 +43,6 @@ "Layer": {}, "SeveritySource": "k8s", "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2023-2431", - "PkgRef": "pkg:k8s/k8s.io%2Fkubelet@1.27.0", "DataSource": { "ID": "k8s", "Name": "Official Kubernetes CVE Feed", diff --git a/pkg/detector/library/detect.go b/pkg/detector/library/detect.go index 14674be8d1a8..3a7af4a06f54 100644 --- a/pkg/detector/library/detect.go +++ b/pkg/detector/library/detect.go @@ -33,7 +33,6 @@ func detect(driver Driver, libs []ftypes.Package) ([]types.DetectedVulnerability for i := range vulns { vulns[i].Layer = lib.Layer vulns[i].PkgPath = lib.FilePath - vulns[i].PkgRef = lib.Ref vulns[i].PkgIdentifier = lib.Identifier } vulnerabilities = append(vulnerabilities, vulns...) diff --git a/pkg/detector/ospkg/alma/alma.go b/pkg/detector/ospkg/alma/alma.go index a3c3a546f8f4..a9450046f27a 100644 --- a/pkg/detector/ospkg/alma/alma.go +++ b/pkg/detector/ospkg/alma/alma.go @@ -90,7 +90,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, FixedVersion: fixedVersion.String(), - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/alpine/alpine.go b/pkg/detector/ospkg/alpine/alpine.go index aa50ef35ba1e..f1d284fea15e 100644 --- a/pkg/detector/ospkg/alpine/alpine.go +++ b/pkg/detector/ospkg/alpine/alpine.go @@ -130,7 +130,6 @@ func (s *Scanner) Detect(osVer string, repo *ftypes.Repository, pkgs []ftypes.Pa InstalledVersion: utils.FormatVersion(pkg), FixedVersion: adv.FixedVersion, Layer: pkg.Layer, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/amazon/amazon.go b/pkg/detector/ospkg/amazon/amazon.go index 4be7ab8080ae..8bb310b131c7 100644 --- a/pkg/detector/ospkg/amazon/amazon.go +++ b/pkg/detector/ospkg/amazon/amazon.go @@ -103,7 +103,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, FixedVersion: adv.FixedVersion, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/chainguard/chainguard.go b/pkg/detector/ospkg/chainguard/chainguard.go index a818de11cbfe..f2ef2c307034 100644 --- a/pkg/detector/ospkg/chainguard/chainguard.go +++ b/pkg/detector/ospkg/chainguard/chainguard.go @@ -81,7 +81,6 @@ func (s *Scanner) Detect(_ string, _ *ftypes.Repository, pkgs []ftypes.Package) InstalledVersion: installed, FixedVersion: adv.FixedVersion, Layer: pkg.Layer, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/debian/debian.go b/pkg/detector/ospkg/debian/debian.go index 90a91af42b27..b0a1d426f4d4 100644 --- a/pkg/detector/ospkg/debian/debian.go +++ b/pkg/detector/ospkg/debian/debian.go @@ -103,7 +103,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), FixedVersion: adv.FixedVersion, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Status: adv.Status, Layer: pkg.Layer, diff --git a/pkg/detector/ospkg/mariner/mariner.go b/pkg/detector/ospkg/mariner/mariner.go index 0b780b9f2d71..46cafa22fce6 100644 --- a/pkg/detector/ospkg/mariner/mariner.go +++ b/pkg/detector/ospkg/mariner/mariner.go @@ -49,7 +49,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa VulnerabilityID: adv.VulnerabilityID, PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/oracle/oracle.go b/pkg/detector/ospkg/oracle/oracle.go index 0f07d9873526..e8a34c95b07a 100644 --- a/pkg/detector/ospkg/oracle/oracle.go +++ b/pkg/detector/ospkg/oracle/oracle.go @@ -86,7 +86,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgID: pkg.ID, PkgName: pkg.Name, InstalledVersion: installed, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/photon/photon.go b/pkg/detector/ospkg/photon/photon.go index ac7eb501f102..558e5511fc2f 100644 --- a/pkg/detector/ospkg/photon/photon.go +++ b/pkg/detector/ospkg/photon/photon.go @@ -81,7 +81,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgID: pkg.ID, PkgName: pkg.Name, InstalledVersion: installed, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/redhat/redhat.go b/pkg/detector/ospkg/redhat/redhat.go index 9420e9cdbb1c..54bedcbf98c3 100644 --- a/pkg/detector/ospkg/redhat/redhat.go +++ b/pkg/detector/ospkg/redhat/redhat.go @@ -157,7 +157,6 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln PkgID: pkg.ID, PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Status: adv.Status, Layer: pkg.Layer, diff --git a/pkg/detector/ospkg/rocky/rocky.go b/pkg/detector/ospkg/rocky/rocky.go index 9a57cf7974cf..5de786675b34 100644 --- a/pkg/detector/ospkg/rocky/rocky.go +++ b/pkg/detector/ospkg/rocky/rocky.go @@ -90,7 +90,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: installed, FixedVersion: fixedVersion.String(), - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, DataSource: adv.DataSource, diff --git a/pkg/detector/ospkg/suse/suse.go b/pkg/detector/ospkg/suse/suse.go index 267c8940ef0b..9b685a50c448 100644 --- a/pkg/detector/ospkg/suse/suse.go +++ b/pkg/detector/ospkg/suse/suse.go @@ -133,7 +133,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgID: pkg.ID, PkgName: pkg.Name, InstalledVersion: installed, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/ubuntu/ubuntu.go b/pkg/detector/ospkg/ubuntu/ubuntu.go index d2f76a2e67d0..eb143fcd9952 100644 --- a/pkg/detector/ospkg/ubuntu/ubuntu.go +++ b/pkg/detector/ospkg/ubuntu/ubuntu.go @@ -123,7 +123,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa PkgName: pkg.Name, InstalledVersion: utils.FormatVersion(pkg), FixedVersion: adv.FixedVersion, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Layer: pkg.Layer, Custom: adv.Custom, diff --git a/pkg/detector/ospkg/wolfi/wolfi.go b/pkg/detector/ospkg/wolfi/wolfi.go index c7d4ca1a1c4f..c4d8d71d972c 100644 --- a/pkg/detector/ospkg/wolfi/wolfi.go +++ b/pkg/detector/ospkg/wolfi/wolfi.go @@ -81,7 +81,6 @@ func (s *Scanner) Detect(_ string, _ *ftypes.Repository, pkgs []ftypes.Package) InstalledVersion: installed, FixedVersion: adv.FixedVersion, Layer: pkg.Layer, - PkgRef: pkg.Ref, PkgIdentifier: pkg.Identifier, Custom: adv.Custom, DataSource: adv.DataSource, diff --git a/pkg/fanal/analyzer/sbom/sbom_test.go b/pkg/fanal/analyzer/sbom/sbom_test.go index e475e1b363bb..4e37834d04d8 100644 --- a/pkg/fanal/analyzer/sbom/sbom_test.go +++ b/pkg/fanal/analyzer/sbom/sbom_test.go @@ -33,7 +33,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "co.elastic.apm:apm-agent", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -49,7 +48,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -65,7 +63,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "co.elastic.apm:apm-agent-common", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent-common@1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -81,7 +78,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "co.elastic.apm:apm-agent-core", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent-core@1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -103,7 +99,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "elasticsearch", Version: "8.9.1", - Ref: "pkg:bitnami/elasticsearch@8.9.1?arch=arm64", Arch: "arm64", Licenses: []string{"Elastic-2.0"}, Identifier: types.PkgIdentifier{ @@ -141,7 +136,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", Name: "co.elastic.apm:apm-agent", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ PackageURL: packageurl.PackageURL{ @@ -152,13 +146,13 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { }, FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", }, + BOMRef: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", }, }, { FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", - Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ PackageURL: packageurl.PackageURL{ @@ -169,6 +163,7 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { }, FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", }, + BOMRef: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", }, }, }, @@ -190,7 +185,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "gdal", Version: "3.7.1", - Ref: "pkg:bitnami/gdal@3.7.1", Licenses: []string{"MIT"}, Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -205,7 +199,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "geos", Version: "3.8.3", - Ref: "pkg:bitnami/geos@3.8.3", Licenses: []string{"LGPL-2.1-only"}, Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -220,7 +213,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "postgresql", Version: "15.3.0", - Ref: "pkg:bitnami/postgresql@15.3.0", Licenses: []string{"PostgreSQL"}, Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ @@ -235,7 +227,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { { Name: "proj", Version: "6.3.2", - Ref: "pkg:bitnami/proj@6.3.2", Licenses: []string{"MIT"}, Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ diff --git a/pkg/fanal/applier/docker_test.go b/pkg/fanal/applier/docker_test.go index fc04b7654070..a8076f3bb4e5 100644 --- a/pkg/fanal/applier/docker_test.go +++ b/pkg/fanal/applier/docker_test.go @@ -280,7 +280,6 @@ func TestApplyLayers(t *testing.T) { Arch: "all", SrcName: "adduser", SrcVersion: "3.118+deb11u1", - Ref: "pkg:deb/debian/adduser@3.118%2Bdeb11u1?arch=all&distro=debian-11.8", Layer: types.Layer{ Digest: "sha256:e67fdae3559346105027c63e7fb032bba57e62b1fe9f2da23e6fdfb56384e00b", DiffID: "sha256:633f5bf471f7595b236a21e62dc60beef321db45916363a02ad5af02d794d497", @@ -319,7 +318,6 @@ func TestApplyLayers(t *testing.T) { Arch: "all", SrcName: "adduser", SrcVersion: "3.118+deb11u1", - Ref: "pkg:deb/debian/adduser@3.118%2Bdeb11u1?arch=all&distro=debian-11.8", Layer: types.Layer{ Digest: "sha256:e67fdae3559346105027c63e7fb032bba57e62b1fe9f2da23e6fdfb56384e00b", DiffID: "sha256:633f5bf471f7595b236a21e62dc60beef321db45916363a02ad5af02d794d497", diff --git a/pkg/fanal/artifact/image/remote_sbom_test.go b/pkg/fanal/artifact/image/remote_sbom_test.go index b924a6efa6a3..6b21e2200233 100644 --- a/pkg/fanal/artifact/image/remote_sbom_test.go +++ b/pkg/fanal/artifact/image/remote_sbom_test.go @@ -70,7 +70,7 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { putBlobExpectations: []cache.ArtifactCachePutBlobExpectation{ { Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", + BlobID: "sha256:5c9fad635c53ddafd1b5248fcd989b6c0f311c91a2fe2a206c7d67a715335fa1", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -98,11 +98,11 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { }, }, }, + BOMRef: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.2", }, SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.2", Layer: types.Layer{ DiffID: "sha256:994393dc58e7931862558d06e46aa2bb17487044f670f310dffe1d24e4d1eec7", }, @@ -121,9 +121,9 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { want: types.ArtifactReference{ Name: "test/image:10", Type: types.ArtifactCycloneDX, - ID: "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", + ID: "sha256:5c9fad635c53ddafd1b5248fcd989b6c0f311c91a2fe2a206c7d67a715335fa1", BlobIDs: []string{ - "sha256:754c66ef82bae2e07dc6e7a7bc42f078e1f48cbbc5b9124d18f1c18a48e1ad31", + "sha256:5c9fad635c53ddafd1b5248fcd989b6c0f311c91a2fe2a206c7d67a715335fa1", }, }, }, @@ -224,7 +224,7 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { putBlobExpectations: []cache.ArtifactCachePutBlobExpectation{ { Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", + BlobID: "sha256:fb9379cfc2aeff911515f04ca04300a8c0609c8a2a19b4a3b05a984802fa44eb", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, Applications: []types.Application{ @@ -243,8 +243,8 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:golang/github.com/opencontainers/go-digest@v1.0.0", }, - Ref: "pkg:golang/github.com/opencontainers/go-digest@v1.0.0", }, { Name: "golang.org/x/sync", @@ -258,8 +258,8 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { Version: "v0.1.0", }, }, + BOMRef: "pkg:golang/golang.org/x/sync@v0.1.0", }, - Ref: "pkg:golang/golang.org/x/sync@v0.1.0", }, }, }, @@ -271,9 +271,9 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { want: types.ArtifactReference{ Name: registry + "/test/image:10", Type: types.ArtifactCycloneDX, - ID: "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", + ID: "sha256:fb9379cfc2aeff911515f04ca04300a8c0609c8a2a19b4a3b05a984802fa44eb", BlobIDs: []string{ - "sha256:c4e3bd56d4b5f9634c918d0953f7667928c2410e23bdacb299bfe5802217809a", + "sha256:fb9379cfc2aeff911515f04ca04300a8c0609c8a2a19b4a3b05a984802fa44eb", }, }, }, diff --git a/pkg/fanal/artifact/sbom/sbom_test.go b/pkg/fanal/artifact/sbom/sbom_test.go index 036574b63d13..e58437141ea8 100644 --- a/pkg/fanal/artifact/sbom/sbom_test.go +++ b/pkg/fanal/artifact/sbom/sbom_test.go @@ -30,7 +30,7 @@ func TestArtifact_Inspect(t *testing.T) { filePath: filepath.Join("testdata", "bom.json"), putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + BlobID: "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -46,7 +46,6 @@ func TestArtifact_Inspect(t *testing.T) { SrcName: "musl", SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: types.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -65,6 +64,7 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, + BOMRef: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, }, }, @@ -78,7 +78,6 @@ func TestArtifact_Inspect(t *testing.T) { { Name: "pear/log", Version: "1.13.1", - Ref: "pkg:composer/pear/log@1.13.1", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -91,13 +90,13 @@ func TestArtifact_Inspect(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, }, { Name: "pear/pear_exception", Version: "v1.0.0", - Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -110,6 +109,7 @@ func TestArtifact_Inspect(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -121,7 +121,6 @@ func TestArtifact_Inspect(t *testing.T) { { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -134,6 +133,7 @@ func TestArtifact_Inspect(t *testing.T) { Version: "v0.1.1-0.20220203205134-d70459300c8a", }, }, + BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, }, }, @@ -144,7 +144,6 @@ func TestArtifact_Inspect(t *testing.T) { Libraries: types.Packages{ { Name: "org.codehaus.mojo:child-project", - Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Version: "1.0", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -160,6 +159,7 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/maven/target/child-project-1.0.jar", }, + BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, }, }, @@ -171,7 +171,6 @@ func TestArtifact_Inspect(t *testing.T) { { Name: "bootstrap", Version: "5.0.2", - Ref: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", Licenses: []string{"MIT"}, Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -186,6 +185,7 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/app/package.json", }, + BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, }, }, @@ -198,9 +198,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: filepath.Join("testdata", "bom.json"), Type: types.ArtifactCycloneDX, - ID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + ID: "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", BlobIDs: []string{ - "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", }, }, }, @@ -209,7 +209,7 @@ func TestArtifact_Inspect(t *testing.T) { filePath: filepath.Join("testdata", "sbom.cdx.intoto.jsonl"), putBlobExpectation: cache.ArtifactCachePutBlobExpectation{ Args: cache.ArtifactCachePutBlobArgs{ - BlobID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + BlobID: "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", BlobInfo: types.BlobInfo{ SchemaVersion: types.BlobJSONSchemaVersion, OS: types.OS{ @@ -240,8 +240,8 @@ func TestArtifact_Inspect(t *testing.T) { }, }, }, + BOMRef: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: types.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -266,8 +266,8 @@ func TestArtifact_Inspect(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -285,8 +285,8 @@ func TestArtifact_Inspect(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -309,8 +309,8 @@ func TestArtifact_Inspect(t *testing.T) { Version: "v0.1.1-0.20220203205134-d70459300c8a", }, }, + BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -334,8 +334,8 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/maven/target/child-project-1.0.jar", }, + BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, - Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -359,8 +359,8 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/app/package.json", }, + BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, - Ref: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", Licenses: []string{"MIT"}, Layer: types.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -377,9 +377,9 @@ func TestArtifact_Inspect(t *testing.T) { want: types.ArtifactReference{ Name: filepath.Join("testdata", "sbom.cdx.intoto.jsonl"), Type: types.ArtifactCycloneDX, - ID: "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + ID: "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", BlobIDs: []string{ - "sha256:c1cc58e08422fd7606a8e9ee2b42bf722b7af8b703b895461c23b83956f33227", + "sha256:5d7b14f463a56006dd4060d04295afbda468350f2e5a786ae48d18fd02fb9a89", }, }, }, diff --git a/pkg/fanal/cache/mock_artifact_cache.go b/pkg/fanal/cache/mock_artifact_cache.go index c73786021a58..e0b1430337e4 100644 --- a/pkg/fanal/cache/mock_artifact_cache.go +++ b/pkg/fanal/cache/mock_artifact_cache.go @@ -193,7 +193,7 @@ type ArtifactCachePutBlobExpectation struct { Returns ArtifactCachePutBlobReturns } -func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpectation) *mock.Call{ +func (_m *MockArtifactCache) ApplyPutBlobExpectation(e ArtifactCachePutBlobExpectation) *mock.Call { var args []interface{} if e.Args.BlobIDAnything { args = append(args, mock.Anything) diff --git a/pkg/fanal/handler/unpackaged/unpackaged_test.go b/pkg/fanal/handler/unpackaged/unpackaged_test.go index 483e45b81b71..40c3cff54fdd 100644 --- a/pkg/fanal/handler/unpackaged/unpackaged_test.go +++ b/pkg/fanal/handler/unpackaged/unpackaged_test.go @@ -45,7 +45,6 @@ func Test_unpackagedHook_Handle(t *testing.T) { { Name: "github.com/spf13/cobra", Version: "1.5.0", - Ref: "pkg:golang/github.com/spf13/cobra@1.5.0", Identifier: types.PkgIdentifier{ PURL: &types.PackageURL{ PackageURL: packageurl.PackageURL{ @@ -55,6 +54,7 @@ func Test_unpackagedHook_Handle(t *testing.T) { Version: "1.5.0", }, }, + BOMRef: "pkg:golang/github.com/spf13/cobra@1.5.0", }, }, }, diff --git a/pkg/fanal/types/artifact.go b/pkg/fanal/types/artifact.go index a6d9e5372a95..b715cb7eeb77 100644 --- a/pkg/fanal/types/artifact.go +++ b/pkg/fanal/types/artifact.go @@ -81,14 +81,6 @@ type Package struct { BuildInfo *BuildInfo `json:",omitempty"` // only for Red Hat Indirect bool `json:",omitempty"` // this package is direct dependency of the project or not - // TO BE DEPRECATED - use Identifier instead - // Only used when scanning SBOM and contains the reference ID used in it. - // It could be PURL, UUID, etc. - // e.g. - // - pkg:npm/acme/component@1.0.0 - // - b2a46a4b-8367-4bae-9820-95557cfe03a8 - Ref string `json:",omitempty"` - // Dependencies of this package // Note: it may have interdependencies, which may lead to infinite loops. DependsOn []string `json:",omitempty"` @@ -110,12 +102,22 @@ type Package struct { // PkgIdentifier represents a software identifiers in one of more of the supported formats. type PkgIdentifier struct { - // PURL is a package URL - PURL *PackageURL `json:",omitempty"` + PURL *PackageURL `json:",omitempty"` + BOMRef string `json:",omitempty"` // For CycloneDX } func (id *PkgIdentifier) Empty() bool { - return id.PURL == nil + return id.PURL == nil && id.BOMRef == "" +} + +func (id *PkgIdentifier) Match(s string) bool { + switch { + case id.BOMRef == s: + return true + case id.PURL != nil && id.PURL.String() == s: + return true + } + return false } type Location struct { diff --git a/pkg/module/serialize/types_easyjson.go b/pkg/module/serialize/types_easyjson.go index fc28d5e0f758..3ccb7e194271 100644 --- a/pkg/module/serialize/types_easyjson.go +++ b/pkg/module/serialize/types_easyjson.go @@ -1632,8 +1632,6 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgTypes(in *jlexer.Lexer, out.SeveritySource = types2.SourceID(in.String()) case "PrimaryURL": out.PrimaryURL = string(in.String()) - case "PkgRef": - out.PkgRef = string(in.String()) case "DataSource": if in.IsNull() { in.Skip() @@ -1907,16 +1905,6 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgTypes(out *jwriter.Write } out.String(string(in.PrimaryURL)) } - if in.PkgRef != "" { - const prefix string = ",\"PkgRef\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.PkgRef)) - } if in.DataSource != nil { const prefix string = ",\"DataSource\":" if first { @@ -2258,6 +2246,8 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.L in.AddError((*out.PURL).UnmarshalJSON(data)) } } + case "BOMRef": + out.BOMRef = string(in.String()) default: in.SkipRecursive() } @@ -2278,6 +2268,16 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter out.RawString(prefix[1:]) out.Raw((*in.PURL).MarshalJSON()) } + if in.BOMRef != "" { + const prefix string = ",\"BOMRef\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.BOMRef)) + } out.RawByte('}') } func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Lexer, out *types1.Package) { @@ -2362,8 +2362,6 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le } case "Indirect": out.Indirect = bool(in.Bool()) - case "Ref": - out.Ref = string(in.String()) case "DependsOn": if in.IsNull() { in.Skip() @@ -2628,16 +2626,6 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } out.Bool(bool(in.Indirect)) } - if in.Ref != "" { - const prefix string = ",\"Ref\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Ref)) - } if len(in.DependsOn) != 0 { const prefix string = ",\"DependsOn\":" if first { diff --git a/pkg/rpc/convert.go b/pkg/rpc/convert.go index d828533c596e..a8a04d0dcbd6 100644 --- a/pkg/rpc/convert.go +++ b/pkg/rpc/convert.go @@ -85,7 +85,8 @@ func ConvertToRPCPkgIdentifier(pkg ftypes.PkgIdentifier) *common.PkgIdentifier { p = pkg.PURL.BOMRef() // Use BOMRef() instead of String() so that we won't lose file_path } return &common.PkgIdentifier{ - Purl: p, + Purl: p, + BomRef: pkg.BOMRef, } } @@ -217,16 +218,23 @@ func ConvertFromRPCPkgs(rpcPkgs []*common.Package) []ftypes.Package { } func ConvertFromRPCPkgIdentifier(pkg *common.PkgIdentifier) ftypes.PkgIdentifier { - if pkg == nil || pkg.Purl == "" { + if pkg == nil { return ftypes.PkgIdentifier{} } - pu, err := purl.FromString(pkg.Purl) - if err != nil { - log.Logger.Error("Failed to parse PURL (%s): %s", pkg.Purl, err) + + pkgID := ftypes.PkgIdentifier{ + BOMRef: pkg.BomRef, } - return ftypes.PkgIdentifier{ - PURL: pu, + + if pkg.Purl != "" { + pu, err := purl.FromString(pkg.Purl) + if err != nil { + log.Logger.Error("Failed to parse PURL (%s): %s", pkg.Purl, err) + } + pkgID.PURL = pu } + + return pkgID } // ConvertToRPCVulns returns common.Vulnerability diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index 73c5046c9947..77babfda26aa 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -351,7 +351,6 @@ func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, er // Trivy's marshall loses case-sensitivity in PURL used in SBOM for packages (Go, Npm, PyPI), // so we have to use an original package name pkg.Name = packageName(p.Type, pkg.Name, component) - pkg.Ref = component.BOMRef pkg.Licenses = parsePackageLicenses(component.Licenses) for key, value := range core.UnmarshalProperties(component.Properties) { @@ -383,7 +382,10 @@ func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, er if pkg.FilePath != "" { p.FilePath = pkg.FilePath } - pkg.Identifier = ftypes.PkgIdentifier{PURL: p} + pkg.Identifier = ftypes.PkgIdentifier{ + PURL: p, + BOMRef: component.BOMRef, + } if purl.Class(p) == types.ClassOSPkg { fillSrcPkg(pkg) diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index 9c9666d319dd..a61bbf8d0d30 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -54,8 +54,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + BOMRef: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: ftypes.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -80,8 +80,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -99,8 +99,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -123,8 +123,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "v0.1.1-0.20220203205134-d70459300c8a", }, }, + BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -146,8 +146,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "0.0.1", }, }, + BOMRef: "pkg:maven/com.example/example@0.0.1", }, - Ref: "pkg:maven/com.example/example@0.0.1", Version: "0.0.1", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -170,8 +170,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, FilePath: "app/maven/target/child-project-1.0.jar", }, + BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, - Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", Version: "1.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -196,8 +196,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, FilePath: "app/app/package.json", }, + BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, - Ref: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", Licenses: []string{"MIT"}, Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -237,8 +237,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "24.0.4", }, }, + BOMRef: "pkg:golang/docker@24.0.4", }, - Ref: "pkg:golang/docker@24.0.4", }, }, }, @@ -260,8 +260,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fapiserver@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fapiserver@1.27.4", }, { Name: "k8s.io/controller-manager", @@ -274,8 +274,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fcontroller-manager@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fcontroller-manager@1.27.4", }, { Name: "k8s.io/kube-proxy", @@ -288,8 +288,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fkube-proxy@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fkube-proxy@1.27.4", }, { Name: "k8s.io/kube-scheduler", @@ -302,8 +302,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fkube-scheduler@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fkube-scheduler@1.27.4", }, { Name: "k8s.io/kubelet", @@ -316,8 +316,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fkubelet@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fkubelet@1.27.4", }, { Name: "k8s.io/kubernetes", @@ -330,8 +330,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.27.4", }, }, + BOMRef: "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", }, - Ref: "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", }, }, }, @@ -376,8 +376,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + BOMRef: "pkg:deb/ubuntu/libc6@2.35-0ubuntu3.1?distro=ubuntu-22.04", }, - Ref: "pkg:deb/ubuntu/libc6@2.35-0ubuntu3.1?distro=ubuntu-22.04", Layer: ftypes.Layer{ Digest: "sha256:74ac377868f863e123f24c409f79709f7563fa464557c36a09cf6f85c8b92b7f", DiffID: "sha256:b93c1bd012ab8fda60f5b4f5906bf244586e0e3292d84571d3abb56472248466", @@ -411,8 +411,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + BOMRef: "pkg:deb/ubuntu/libcrypt1@4.4.27-1?epoch=1&distro=ubuntu-22.04", }, - Ref: "pkg:deb/ubuntu/libcrypt1@4.4.27-1?epoch=1&distro=ubuntu-22.04", Layer: ftypes.Layer{ Digest: "sha256:74ac377868f863e123f24c409f79709f7563fa464557c36a09cf6f85c8b92b7f", DiffID: "sha256:b93c1bd012ab8fda60f5b4f5906bf244586e0e3292d84571d3abb56472248466", @@ -455,8 +455,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + BOMRef: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", }, }, }, @@ -478,8 +478,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", Licenses: []string{"MIT"}, }, { @@ -495,8 +495,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -524,8 +524,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", }, }, }, @@ -553,8 +553,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", }, { @@ -569,8 +569,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -598,8 +598,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/core@1.13.1", }, - Ref: "pkg:composer/pear/core@1.13.1", }, { Name: "pear/log", @@ -613,8 +613,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "1.13.1", }, }, + BOMRef: "pkg:composer/pear/log@1.13.1", }, - Ref: "pkg:composer/pear/log@1.13.1", }, { @@ -629,8 +629,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "v1.0.0", }, }, + BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -658,8 +658,8 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, FilePath: "spring-web-5.3.22.jar", }, + BOMRef: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", }, - Ref: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", FilePath: "spring-web-5.3.22.jar", }, }, diff --git a/pkg/sbom/spdx/unmarshal.go b/pkg/sbom/spdx/unmarshal.go index 9ff8586c45d9..5ce4237ac20a 100644 --- a/pkg/sbom/spdx/unmarshal.go +++ b/pkg/sbom/spdx/unmarshal.go @@ -290,7 +290,6 @@ func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Pac return nil, nil, xerrors.Errorf("failed to parse purl from string: %w", err) } pkg := purl.ToPackage(packageURL) - pkg.Ref = ref.Locator pkg.Identifier = ftypes.PkgIdentifier{ PURL: packageURL, } diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index d7ebdad3922d..dfa09a0c86fa 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -55,7 +55,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:apk/alpine/musl@1.2.3-r0?distro=3.16.0", Layer: ftypes.Layer{ DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, @@ -81,7 +80,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:composer/pear/log@1.13.1", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -100,7 +98,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -124,7 +121,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, @@ -146,7 +142,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:maven/org.codehaus.mojo/child-project@1.0", Version: "1.0", Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -169,7 +164,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:npm/bootstrap@5.0.2", Licenses: []string{"MIT"}, Layer: ftypes.Layer{ DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", @@ -202,7 +196,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:npm/yargs-parser@21.1.1", FilePath: "node_modules/yargs-parser/package.json", }, }, @@ -232,7 +225,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:npm/yargs-parser@21.1.1", FilePath: "node_modules/yargs-parser/package.json", }, }, @@ -262,7 +254,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:composer/pear/log@1.13.1", }, { @@ -278,7 +269,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:composer/pear/pear_exception@v1.0.0", }, }, }, @@ -307,7 +297,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", }, { FilePath: "modules/apm/elastic-apm-agent-1.36.0.jar", @@ -323,7 +312,6 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, - Ref: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", }, }, }, diff --git a/pkg/types/vulnerability.go b/pkg/types/vulnerability.go index 4727d5009083..7e0d942cfd92 100644 --- a/pkg/types/vulnerability.go +++ b/pkg/types/vulnerability.go @@ -20,14 +20,6 @@ type DetectedVulnerability struct { SeveritySource types.SourceID `json:",omitempty"` PrimaryURL string `json:",omitempty"` - // TO BE DEPRECATED - use PkgIdentifier instead - // Only used when scanning SBOM and contains the reference ID used in it. - // It could be PURL, UUID, etc. - // e.g. - // - pkg:npm/acme/component@1.0.0 - // - b2a46a4b-8367-4bae-9820-95557cfe03a8 - PkgRef string `json:",omitempty"` - // DataSource holds where the advisory comes from DataSource *types.DataSource `json:",omitempty"` diff --git a/pkg/vex/vex.go b/pkg/vex/vex.go index fb64984bda6e..1042e0886515 100644 --- a/pkg/vex/vex.go +++ b/pkg/vex/vex.go @@ -128,7 +128,7 @@ func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) b zap.Int("version", link.Version())) continue } - if v.matchRef(vuln, link.Reference()) && (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { + if vuln.PkgIdentifier.Match(link.Reference()) && (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), zap.String("status", string(stmt.Status)), zap.String("justification", stmt.Justification)) return false @@ -137,16 +137,6 @@ func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) b return true } -func (v *CycloneDX) matchRef(vuln types.DetectedVulnerability, ref string) bool { - switch { - case vuln.PkgRef == ref: // BOM-Ref - return true - case vuln.PkgIdentifier.PURL != nil && vuln.PkgIdentifier.PURL.String() == ref: // PURL - return true - } - return false -} - func cdxStatus(s cdx.ImpactAnalysisState) Status { switch s { case cdx.IASResolved, cdx.IASResolvedWithPedigree: diff --git a/rpc/common/service.pb.go b/rpc/common/service.pb.go index fcae12028a0f..33e8f40c7c2f 100644 --- a/rpc/common/service.pb.go +++ b/rpc/common/service.pb.go @@ -629,8 +629,8 @@ type PkgIdentifier struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Purl string `protobuf:"bytes,1,opt,name=purl,proto3" json:"purl,omitempty"` - Cpe string `protobuf:"bytes,2,opt,name=cpe,proto3" json:"cpe,omitempty"` + Purl string `protobuf:"bytes,1,opt,name=purl,proto3" json:"purl,omitempty"` + BomRef string `protobuf:"bytes,2,opt,name=bom_ref,json=bomRef,proto3" json:"bom_ref,omitempty"` } func (x *PkgIdentifier) Reset() { @@ -672,9 +672,9 @@ func (x *PkgIdentifier) GetPurl() string { return "" } -func (x *PkgIdentifier) GetCpe() string { +func (x *PkgIdentifier) GetBomRef() string { if x != nil { - return x.Cpe + return x.BomRef } return "" } @@ -2246,8 +2246,8 @@ func (x *LicenseFinding) GetLink() string { return "" } -// Enumerations are wrapped with a message to improve the readability of enumerations -// in generated code and avoid name conflicts. +// Enumerations are wrapped with a message to improve the readability of +// enumerations in generated code and avoid name conflicts. // https://github.com/golang/protobuf/issues/513 type LicenseCategory struct { state protoimpl.MessageState @@ -2390,318 +2390,319 @@ var file_rpc_common_service_proto_rawDesc = []byte{ 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x65, 0x76, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x64, 0x65, 0x76, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x35, 0x0a, 0x0d, 0x50, + 0x08, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x3c, 0x0a, 0x0d, 0x50, 0x6b, 0x67, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x75, 0x72, 0x6c, - 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, - 0x70, 0x65, 0x22, 0xb6, 0x02, 0x0a, 0x10, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x39, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, - 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x12, 0x17, 0x0a, 0x07, 0x62, 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x62, 0x6f, 0x6d, 0x52, 0x65, 0x66, 0x22, 0xb6, 0x02, 0x0a, 0x10, 0x4d, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, + 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x39, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, + 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x08, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, - 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x77, 0x61, 0x72, - 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, - 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x0d, - 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0e, - 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x4a, 0x04, 0x08, 0x03, 0x10, 0x07, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x52, 0x02, 0x69, 0x64, - 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x64, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x76, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, - 0x69, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x22, 0xf7, 0x03, 0x0a, 0x18, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, - 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x42, 0x0a, - 0x0e, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x76, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x61, 0x76, 0x64, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xff, - 0x09, 0x0a, 0x0d, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x29, 0x0a, 0x10, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, - 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x70, - 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, - 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x78, 0x65, - 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x70, 0x6b, 0x67, 0x5f, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, - 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6b, 0x67, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0d, 0x70, 0x6b, 0x67, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, - 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x04, - 0x63, 0x76, 0x73, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x72, 0x69, - 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, - 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x43, 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x04, 0x63, 0x76, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x77, 0x65, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x63, 0x77, 0x65, 0x49, 0x64, 0x73, + 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x66, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x0f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0e, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, + 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x07, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x52, 0x02, 0x69, 0x64, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x52, 0x08, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x61, + 0x64, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x64, 0x76, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xf7, 0x03, 0x0a, 0x18, + 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, - 0x6c, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, - 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c, 0x61, - 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, - 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, - 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x64, 0x76, 0x69, - 0x73, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x5f, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x56, 0x75, 0x6c, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x65, - 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, - 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x64, 0x61, 0x74, - 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x73, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, - 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, - 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x19, - 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x70, 0x6b, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x70, 0x6b, 0x67, - 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x6b, 0x67, 0x49, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x4b, 0x0a, 0x09, 0x43, 0x76, 0x73, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x13, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, - 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, - 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x42, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x75, 0x72, 0x6c, 0x22, 0x57, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0xc3, 0x01, - 0x0a, 0x0d, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, - 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x22, 0x76, 0x0a, 0x04, 0x43, 0x56, 0x53, 0x53, 0x12, 0x1b, 0x0a, 0x09, 0x76, - 0x32, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x76, 0x32, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x33, 0x5f, 0x76, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x33, 0x56, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x32, 0x5f, 0x73, 0x63, 0x6f, 0x72, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x76, 0x32, 0x53, 0x63, 0x6f, 0x72, 0x65, - 0x12, 0x19, 0x0a, 0x08, 0x76, 0x33, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x07, 0x76, 0x33, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x0e, - 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, - 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf3, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, - 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x61, 0x75, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x61, 0x75, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x04, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x9f, - 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x12, 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, - 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, - 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, - 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, - 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, - 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, + 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, + 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0e, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, + 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x75, 0x73, + 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x76, 0x64, 0x5f, + 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x76, 0x64, 0x49, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xff, 0x09, 0x0a, 0x0d, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x76, 0x75, 0x6c, 0x6e, 0x65, + 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, + 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x66, 0x69, 0x78, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, + 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x70, + 0x6b, 0x67, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x19, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x50, 0x6b, 0x67, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x52, 0x0d, 0x70, 0x6b, 0x67, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, - 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, - 0x22, 0x5d, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, - 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, - 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, - 0x85, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, - 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, - 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xed, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, - 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, - 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, - 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0b, 0x6c, - 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, - 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, - 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x05, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, - 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, - 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, - 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, - 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, - 0x6e, 0x6b, 0x22, 0x95, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x81, 0x01, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, - 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x42, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x01, 0x12, - 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, - 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x43, 0x49, 0x50, 0x52, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, - 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x50, - 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, 0x45, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x55, - 0x4e, 0x45, 0x4e, 0x43, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0b, 0x0a, - 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x07, 0x22, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3f, 0x0a, 0x04, 0x45, 0x6e, 0x75, - 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x50, 0x4b, 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x43, 0x45, - 0x4e, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x2a, 0x44, 0x0a, 0x08, 0x53, 0x65, - 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, - 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, - 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, - 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, - 0x71, 0x75, 0x61, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, - 0x79, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x63, 0x76, 0x73, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x43, + 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x63, 0x76, 0x73, 0x73, 0x12, 0x17, + 0x0a, 0x07, 0x63, 0x77, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x63, 0x77, 0x65, 0x49, 0x64, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, + 0x61, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x41, 0x64, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x40, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x56, 0x75, 0x6c, 0x6e, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x73, + 0x12, 0x39, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x0a, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x76, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x15, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, + 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6b, 0x67, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x15, 0x0a, 0x06, 0x70, 0x6b, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x70, 0x6b, 0x67, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, + 0x4b, 0x0a, 0x09, 0x43, 0x76, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x56, 0x53, + 0x53, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x13, + 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x42, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x57, 0x0a, 0x05, 0x4c, + 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, + 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x42, 0x79, 0x22, 0xc3, 0x01, 0x0a, 0x0d, 0x43, 0x61, 0x75, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, + 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, + 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x76, 0x0a, 0x04, 0x43, 0x56, + 0x53, 0x53, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x32, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x32, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x1b, 0x0a, 0x09, 0x76, 0x33, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x76, 0x33, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x76, 0x32, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, + 0x76, 0x32, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x33, 0x5f, 0x73, 0x63, + 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x76, 0x33, 0x53, 0x63, 0x6f, + 0x72, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x12, 0x2a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf3, 0x01, + 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x63, + 0x61, 0x75, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x43, 0x61, + 0x75, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, + 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, + 0x61, 0x75, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x75, + 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x61, + 0x75, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6c, + 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, + 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x05, + 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x9f, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x5d, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, 0x0a, + 0x08, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, + 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x76, 0x65, + 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, + 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x2e, + 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x19, + 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, + 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xed, + 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x41, + 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x2e, + 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, + 0x0a, 0x08, 0x70, 0x6b, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x6b, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x66, 0x69, 0x6e, + 0x67, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, + 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x67, 0x69, + 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x98, + 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x12, 0x3e, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, + 0x72, 0x79, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x95, 0x01, 0x0a, 0x0f, 0x4c, 0x69, + 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x81, 0x01, + 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x42, 0x49, + 0x44, 0x44, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x53, 0x54, 0x52, 0x49, + 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x43, 0x49, 0x50, 0x52, + 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, + 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, 0x45, + 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x45, 0x4e, 0x43, 0x55, 0x4d, 0x42, 0x45, 0x52, + 0x45, 0x44, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x07, 0x22, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x3f, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x50, 0x4b, + 0x47, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, + 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, + 0x03, 0x2a, 0x44, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, + 0x57, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x10, 0x02, 0x12, + 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, + 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x71, 0x75, 0x61, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/rpc/common/service.proto b/rpc/common/service.proto index 375b17684809..f35d22051deb 100644 --- a/rpc/common/service.proto +++ b/rpc/common/service.proto @@ -33,13 +33,13 @@ message Application { message Package { // binary package // e.g. bind-utils - string id = 13; - string name = 1; - string version = 2; - string release = 3; - int32 epoch = 4; - PkgIdentifier identifier = 19; - string arch = 5; + string id = 13; + string name = 1; + string version = 2; + string release = 3; + int32 epoch = 4; + PkgIdentifier identifier = 19; + string arch = 5; // src package containing some binary packages // e.g. bind string src_name = 6; @@ -56,8 +56,8 @@ message Package { } message PkgIdentifier { - string purl = 1; - string cpe = 2; + string purl = 1; + string bom_ref = 2; } message Misconfiguration { @@ -236,8 +236,8 @@ message LicenseFinding { string link = 4; } -// Enumerations are wrapped with a message to improve the readability of enumerations -// in generated code and avoid name conflicts. +// Enumerations are wrapped with a message to improve the readability of +// enumerations in generated code and avoid name conflicts. // https://github.com/golang/protobuf/issues/513 message LicenseCategory { enum Enum { From da597c479cd69ef4c77137f6a27a812d78b7bb85 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Wed, 3 Jan 2024 13:43:45 +0400 Subject: [PATCH 056/108] refactor: propagate time through context values (#5858) Signed-off-by: knqyf263 --- integration/client_server_test.go | 4 -- integration/integration_test.go | 11 +++-- integration/repo_test.go | 17 ++++--- .../testdata/debian-stretch.json.golden | 3 +- .../testdata/distroless-base.json.golden | 3 +- .../testdata/distroless-python27.json.golden | 3 +- .../ubuntu-1804-ignore-unfixed.json.golden | 3 +- integration/testdata/ubuntu-1804.json.golden | 3 +- pkg/clock/clock.go | 30 ++++++++---- pkg/cloud/aws/commands/run_test.go | 31 +++++++++---- pkg/cloud/report/report.go | 8 ++-- pkg/cloud/report/service_test.go | 15 ++++-- pkg/commands/server/run.go | 2 +- pkg/compliance/report/report.go | 7 +-- pkg/compliance/report/table.go | 5 +- pkg/compliance/report/table_test.go | 18 ++++++-- pkg/detector/ospkg/alma/alma.go | 31 ++----------- pkg/detector/ospkg/alma/alma_test.go | 13 +++--- pkg/detector/ospkg/alpine/alpine.go | 31 ++----------- pkg/detector/ospkg/alpine/alpine_test.go | 13 +++--- pkg/detector/ospkg/amazon/amazon.go | 31 ++----------- pkg/detector/ospkg/amazon/amazon_test.go | 13 +++--- pkg/detector/ospkg/chainguard/chainguard.go | 30 ++---------- pkg/detector/ospkg/debian/debian.go | 31 ++----------- pkg/detector/ospkg/debian/debian_test.go | 13 +++--- pkg/detector/ospkg/detect.go | 7 +-- pkg/detector/ospkg/mariner/mariner.go | 4 +- pkg/detector/ospkg/oracle/oracle.go | 12 ++--- pkg/detector/ospkg/oracle/oracle_test.go | 46 +++++++++---------- pkg/detector/ospkg/photon/photon.go | 31 ++----------- pkg/detector/ospkg/photon/photon_test.go | 13 +++--- pkg/detector/ospkg/redhat/redhat.go | 33 +++---------- pkg/detector/ospkg/redhat/redhat_test.go | 13 +++--- pkg/detector/ospkg/rocky/rocky.go | 31 ++----------- pkg/detector/ospkg/rocky/rocky_test.go | 13 +++--- pkg/detector/ospkg/suse/suse.go | 37 +++------------ pkg/detector/ospkg/suse/suse_test.go | 13 +++--- .../ubuntu/testdata/fixtures/ubuntu.yaml | 7 +++ pkg/detector/ospkg/ubuntu/ubuntu.go | 33 +++---------- pkg/detector/ospkg/ubuntu/ubuntu_test.go | 24 ++++------ pkg/detector/ospkg/version/version.go | 8 ++-- pkg/detector/ospkg/wolfi/wolfi.go | 30 ++---------- pkg/k8s/commands/run.go | 4 +- pkg/k8s/report/cyclonedx.go | 5 +- pkg/k8s/report/table.go | 17 +++++-- pkg/k8s/writer.go | 11 ++--- pkg/k8s/writer_test.go | 6 ++- pkg/report/cyclonedx/cyclonedx.go | 5 +- pkg/report/github/github.go | 5 +- pkg/report/github/github_test.go | 3 +- pkg/report/json.go | 3 +- pkg/report/json_test.go | 3 +- pkg/report/predicate/vuln.go | 6 +-- pkg/report/predicate/vuln_test.go | 6 +-- pkg/report/sarif.go | 3 +- pkg/report/sarif_test.go | 2 +- pkg/report/spdx/spdx.go | 5 +- pkg/report/table/table.go | 3 +- pkg/report/table/table_test.go | 2 +- pkg/report/template.go | 3 +- pkg/report/template_test.go | 8 ++-- pkg/report/writer.go | 10 ++-- pkg/result/filter.go | 2 +- pkg/result/filter_test.go | 4 +- pkg/result/ignore.go | 15 +++--- pkg/rpc/server/listen.go | 9 ++-- pkg/rpc/server/listen_test.go | 8 ++-- pkg/sbom/cyclonedx/core/cyclonedx.go | 9 ++-- pkg/sbom/cyclonedx/core/cyclonedx_test.go | 5 +- pkg/sbom/cyclonedx/marshal.go | 5 +- pkg/sbom/cyclonedx/marshal_test.go | 5 +- pkg/sbom/spdx/marshal.go | 5 +- pkg/sbom/spdx/marshal_test.go | 5 +- pkg/scanner/local/scan.go | 6 +-- pkg/scanner/ospkg/scan.go | 10 ++-- pkg/scanner/scan.go | 2 +- pkg/scanner/scan_test.go | 6 +-- 77 files changed, 384 insertions(+), 546 deletions(-) diff --git a/integration/client_server_test.go b/integration/client_server_test.go index c4274eb77a80..352fd8253444 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -17,7 +17,6 @@ import ( "github.com/stretchr/testify/require" testcontainers "github.com/testcontainers/testcontainers-go" - "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/report" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -364,8 +363,6 @@ func TestClientServerWithFormat(t *testing.T) { } fakeTime := time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC) - clock.SetFakeTime(t, fakeTime) - report.CustomTemplateFuncMap = map[string]interface{}{ "now": func() time.Time { return fakeTime @@ -428,7 +425,6 @@ func TestClientServerWithCycloneDX(t *testing.T) { addr, cacheDir := setup(t, setupOptions{}) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d") osArgs, outputFile := setupClient(t, tt.args, addr, cacheDir, tt.golden) diff --git a/integration/integration_test.go b/integration/integration_test.go index 67dc9aeb49b5..05f9c094cd03 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -7,6 +7,7 @@ import ( "encoding/json" "flag" "fmt" + "github.com/aquasecurity/trivy/pkg/clock" "io" "net" "os" @@ -27,7 +28,6 @@ import ( "github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/metadata" - "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/commands" "github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/types" @@ -44,8 +44,6 @@ func initDB(t *testing.T) string { entries, err := os.ReadDir(fixtureDir) require.NoError(t, err) - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) - var fixtures []string for _, entry := range entries { if entry.IsDir() { @@ -193,13 +191,16 @@ func readSpdxJson(t *testing.T, filePath string) *spdx.Document { } func execute(osArgs []string) error { + // Set a fake time + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + // Setup CLI App app := commands.NewApp() app.SetOut(io.Discard) + app.SetArgs(osArgs) // Run Trivy - app.SetArgs(osArgs) - return app.Execute() + return app.ExecuteContext(ctx) } func compareReports(t *testing.T, wantFile, gotFile string, override func(*types.Report)) { diff --git a/integration/repo_test.go b/integration/repo_test.go index dbf9c9bcbdab..68321a57effe 100644 --- a/integration/repo_test.go +++ b/integration/repo_test.go @@ -4,16 +4,13 @@ package integration import ( "fmt" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "os" "path/filepath" "strings" "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/aquasecurity/trivy/pkg/clock" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/uuid" @@ -416,12 +413,15 @@ func TestRepository(t *testing.T) { osArgs := []string{ "-q", - "--cache-dir", cacheDir, + "--cache-dir", + cacheDir, command, "--skip-db-update", "--skip-policy-update", - "--format", string(format), - "--parallel", fmt.Sprint(tt.args.parallel), + "--format", + string(format), + "--parallel", + fmt.Sprint(tt.args.parallel), "--offline-scan", } @@ -499,7 +499,6 @@ func TestRepository(t *testing.T) { osArgs = append(osArgs, "--output", outputFile) osArgs = append(osArgs, tt.args.input) - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d") // Run "trivy repo" diff --git a/integration/testdata/debian-stretch.json.golden b/integration/testdata/debian-stretch.json.golden index 6fd20bda1ee8..ed15dd42381f 100644 --- a/integration/testdata/debian-stretch.json.golden +++ b/integration/testdata/debian-stretch.json.golden @@ -6,8 +6,7 @@ "Metadata": { "OS": { "Family": "debian", - "Name": "9.9", - "EOSL": true + "Name": "9.9" }, "ImageID": "sha256:f26939cc87ef44a6fc554eedd0a976ab30b5bc2769d65d2e986b6c5f1fd4053d", "DiffIDs": [ diff --git a/integration/testdata/distroless-base.json.golden b/integration/testdata/distroless-base.json.golden index 82de2d5368b9..0bd390a36f54 100644 --- a/integration/testdata/distroless-base.json.golden +++ b/integration/testdata/distroless-base.json.golden @@ -6,8 +6,7 @@ "Metadata": { "OS": { "Family": "debian", - "Name": "9.9", - "EOSL": true + "Name": "9.9" }, "ImageID": "sha256:7f04a8d247173b1f2546d22913af637bbab4e7411e00ae6207da8d94c445750d", "DiffIDs": [ diff --git a/integration/testdata/distroless-python27.json.golden b/integration/testdata/distroless-python27.json.golden index f8d54b339867..8c0657976b97 100644 --- a/integration/testdata/distroless-python27.json.golden +++ b/integration/testdata/distroless-python27.json.golden @@ -6,8 +6,7 @@ "Metadata": { "OS": { "Family": "debian", - "Name": "9.9", - "EOSL": true + "Name": "9.9" }, "ImageID": "sha256:6fcac2cc8a710f21577b5bbd534e0bfc841c0cca569b57182ba19054696cddda", "DiffIDs": [ diff --git a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden index fbc7dafbdbb7..f2a38510385b 100644 --- a/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden +++ b/integration/testdata/ubuntu-1804-ignore-unfixed.json.golden @@ -6,8 +6,7 @@ "Metadata": { "OS": { "Family": "ubuntu", - "Name": "18.04", - "EOSL": true + "Name": "18.04" }, "ImageID": "sha256:a2a15febcdf362f6115e801d37b5e60d6faaeedcb9896155e5fe9d754025be12", "DiffIDs": [ diff --git a/integration/testdata/ubuntu-1804.json.golden b/integration/testdata/ubuntu-1804.json.golden index 93abad738729..5fc21dba6a6e 100644 --- a/integration/testdata/ubuntu-1804.json.golden +++ b/integration/testdata/ubuntu-1804.json.golden @@ -6,8 +6,7 @@ "Metadata": { "OS": { "Family": "ubuntu", - "Name": "18.04", - "EOSL": true + "Name": "18.04" }, "ImageID": "sha256:a2a15febcdf362f6115e801d37b5e60d6faaeedcb9896155e5fe9d754025be12", "DiffIDs": [ diff --git a/pkg/clock/clock.go b/pkg/clock/clock.go index e87f9ca8ede5..91f6a5212bd2 100644 --- a/pkg/clock/clock.go +++ b/pkg/clock/clock.go @@ -1,23 +1,33 @@ package clock import ( - "testing" + "context" "time" "k8s.io/utils/clock" clocktesting "k8s.io/utils/clock/testing" ) -var c clock.Clock = clock.RealClock{} +// clockKey is the context key for clock. It is unexported to prevent collisions with context keys defined in +// other packages. +type clockKey struct{} -// SetFakeTime sets a fake time for testing. -func SetFakeTime(t *testing.T, fakeTime time.Time) { - c = clocktesting.NewFakeClock(fakeTime) - t.Cleanup(func() { - c = clock.RealClock{} - }) +// With returns a new context with the given time. +func With(ctx context.Context, t time.Time) context.Context { + c := clocktesting.NewFakeClock(t) + return context.WithValue(ctx, clockKey{}, c) } -func Now() time.Time { - return c.Now() +// Now returns the current time. +func Now(ctx context.Context) time.Time { + return Clock(ctx).Now() +} + +// Clock returns the clock from the context. +func Clock(ctx context.Context) clock.Clock { + t, ok := ctx.Value(clockKey{}).(clock.Clock) + if !ok { + return clock.RealClock{} + } + return t } diff --git a/pkg/cloud/aws/commands/run_test.go b/pkg/cloud/aws/commands/run_test.go index 3c7a188f2d33..3d9d01f17292 100644 --- a/pkg/cloud/aws/commands/run_test.go +++ b/pkg/cloud/aws/commands/run_test.go @@ -1068,8 +1068,11 @@ Summary Report for compliance: my-custom-spec MisconfOptions: flag.MisconfOptions{IncludeNonFailures: true}, }, cacheContent: "testdata/s3andcloudtrailcache.json", - allServices: []string{"s3", "cloudtrail"}, - want: expectedS3AndCloudTrailResult, + allServices: []string{ + "s3", + "cloudtrail", + }, + want: expectedS3AndCloudTrailResult, }, { name: "skip certain services and include specific services", @@ -1087,7 +1090,10 @@ Summary Report for compliance: my-custom-spec MisconfOptions: flag.MisconfOptions{IncludeNonFailures: true}, }, cacheContent: "testdata/s3andcloudtrailcache.json", - allServices: []string{"s3", "cloudtrail"}, + allServices: []string{ + "s3", + "cloudtrail", + }, // we skip cloudtrail but still expect results from it as it is cached want: expectedS3AndCloudTrailResult, }, @@ -1096,16 +1102,23 @@ Summary Report for compliance: my-custom-spec options: flag.Options{ RegoOptions: flag.RegoOptions{SkipPolicyUpdate: true}, AWSOptions: flag.AWSOptions{ - Region: "us-east-1", - SkipServices: []string{"cloudtrail", "iam"}, - Account: "12345678", + Region: "us-east-1", + SkipServices: []string{ + "cloudtrail", + "iam", + }, + Account: "12345678", }, CloudOptions: flag.CloudOptions{ MaxCacheAge: time.Hour * 24 * 365 * 100, }, MisconfOptions: flag.MisconfOptions{IncludeNonFailures: true}, }, - allServices: []string{"s3", "cloudtrail", "iam"}, + allServices: []string{ + "s3", + "cloudtrail", + "iam", + }, cacheContent: "testdata/s3onlycache.json", want: expectedS3ScanResult, }, @@ -1129,7 +1142,7 @@ Summary Report for compliance: my-custom-spec }, } - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.allServices != nil { @@ -1179,7 +1192,7 @@ Summary Report for compliance: my-custom-spec require.NoError(t, os.WriteFile(cacheFile, cacheData, 0600)) } - err := Run(context.Background(), test.options) + err := Run(ctx, test.options) if test.expectErr { assert.Error(t, err) return diff --git a/pkg/cloud/report/report.go b/pkg/cloud/report/report.go index 8c4fa3861b8e..c60e00b45360 100644 --- a/pkg/cloud/report/report.go +++ b/pkg/cloud/report/report.go @@ -67,7 +67,7 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e defer cleanup() if opt.Compliance.Spec.ID != "" { - return writeCompliance(rep, opt, output) + return writeCompliance(ctx, rep, opt, output) } var filtered []types.Result @@ -93,7 +93,7 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e }) base := types.Report{ - CreatedAt: clock.Now(), + CreatedAt: clock.Now(ctx), ArtifactName: rep.AccountID, ArtifactType: ftypes.ArtifactAWSAccount, Results: filtered, @@ -139,7 +139,7 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e } } -func writeCompliance(rep *Report, opt flag.Options, output io.Writer) error { +func writeCompliance(ctx context.Context, rep *Report, opt flag.Options, output io.Writer) error { var crr []types.Results for _, r := range rep.Results { crr = append(crr, r.Results) @@ -150,7 +150,7 @@ func writeCompliance(rep *Report, opt flag.Options, output io.Writer) error { return xerrors.Errorf("compliance report build error: %w", err) } - return cr.Write(complianceReport, cr.Option{ + return cr.Write(ctx, complianceReport, cr.Option{ Format: opt.Format, Report: opt.ReportFormat, Output: output, diff --git a/pkg/cloud/report/service_test.go b/pkg/cloud/report/service_test.go index 507f3ff31466..55dd6cf5f77d 100644 --- a/pkg/cloud/report/service_test.go +++ b/pkg/cloud/report/service_test.go @@ -88,7 +88,10 @@ This scan report was loaded from cached results. If you'd like to run a fresh sc }, }, AWSOptions: flag.AWSOptions{ - Services: []string{"s3", "ec2"}, + Services: []string{ + "s3", + "ec2", + }, }, }, fromCache: false, @@ -117,7 +120,11 @@ Scan Overview for AWS Account }, }, AWSOptions: flag.AWSOptions{ - Services: []string{"ec2", "s3", "iam"}, + Services: []string{ + "ec2", + "s3", + "iam", + }, }, }, fromCache: false, @@ -310,7 +317,7 @@ Scan Overview for AWS Account }`, }, } - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { report := New( @@ -323,7 +330,7 @@ Scan Overview for AWS Account output := bytes.NewBuffer(nil) tt.options.SetOutputWriter(output) - require.NoError(t, Write(context.Background(), report, tt.options, tt.fromCache)) + require.NoError(t, Write(ctx, report, tt.options, tt.fromCache)) assert.Equal(t, "AWS", report.Provider) assert.Equal(t, tt.options.AWSOptions.Account, report.AccountID) diff --git a/pkg/commands/server/run.go b/pkg/commands/server/run.go index 7ddb6f7b3abb..03b8f144170a 100644 --- a/pkg/commands/server/run.go +++ b/pkg/commands/server/run.go @@ -59,5 +59,5 @@ func Run(ctx context.Context, opts flag.Options) (err error) { server := rpcServer.NewServer(opts.AppVersion, opts.Listen, opts.CacheDir, opts.Token, opts.TokenHeader, opts.DBRepository, opts.RegistryOpts()) - return server.ListenAndServe(cache, opts.SkipDBUpdate) + return server.ListenAndServe(ctx, cache, opts.SkipDBUpdate) } diff --git a/pkg/compliance/report/report.go b/pkg/compliance/report/report.go index 8bc8b90d76ee..61a4973b2b0a 100644 --- a/pkg/compliance/report/report.go +++ b/pkg/compliance/report/report.go @@ -1,6 +1,7 @@ package report import ( + "context" "io" "golang.org/x/xerrors" @@ -63,8 +64,8 @@ type Writer interface { Write(ComplianceReport) error } -// Write writes the results in the give format -func Write(report *ComplianceReport, option Option) error { +// Write writes the results in the given format +func Write(ctx context.Context, report *ComplianceReport, option Option) error { switch option.Format { case types.FormatJSON: jwriter := JSONWriter{ @@ -79,7 +80,7 @@ func Write(report *ComplianceReport, option Option) error { Report: option.Report, Severities: option.Severities, } - err := complianceWriter.Write(report) + err := complianceWriter.Write(ctx, report) if err != nil { return err } diff --git a/pkg/compliance/report/table.go b/pkg/compliance/report/table.go index 5de2428a6062..c54f031ef3d6 100644 --- a/pkg/compliance/report/table.go +++ b/pkg/compliance/report/table.go @@ -1,6 +1,7 @@ package report import ( + "context" "io" "sync" @@ -26,7 +27,7 @@ const ( IssuesColumn = "Issues" ) -func (tw TableWriter) Write(report *ComplianceReport) error { +func (tw TableWriter) Write(ctx context.Context, report *ComplianceReport) error { switch tw.Report { case allReport: t := pkgReport.Writer{ @@ -36,7 +37,7 @@ func (tw TableWriter) Write(report *ComplianceReport) error { } for _, cr := range report.Results { r := types.Report{Results: cr.Results} - err := t.Write(r) + err := t.Write(ctx, r) if err != nil { return err } diff --git a/pkg/compliance/report/table_test.go b/pkg/compliance/report/table_test.go index b99aa4b0a20d..ec880adb518d 100644 --- a/pkg/compliance/report/table_test.go +++ b/pkg/compliance/report/table_test.go @@ -2,6 +2,7 @@ package report_test import ( "bytes" + "context" "os" "path/filepath" "testing" @@ -36,7 +37,10 @@ func TestTableWriter_Write(t *testing.T) { Results: types.Results{ { Misconfigurations: []types.DetectedMisconfiguration{ - {AVDID: "AVD-KSV012", Status: types.StatusFailure}, + { + AVDID: "AVD-KSV012", + Status: types.StatusFailure, + }, }, }, }, @@ -48,7 +52,10 @@ func TestTableWriter_Write(t *testing.T) { Results: types.Results{ { Misconfigurations: []types.DetectedMisconfiguration{ - {AVDID: "AVD-KSV013", Status: types.StatusFailure}, + { + AVDID: "AVD-KSV013", + Status: types.StatusFailure, + }, }, }, }, @@ -62,8 +69,11 @@ func TestTableWriter_Write(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { buf := new(bytes.Buffer) - tr := report.TableWriter{Report: tt.reportType, Output: buf} - err := tr.Write(tt.input) + tr := report.TableWriter{ + Report: tt.reportType, + Output: buf, + } + err := tr.Write(context.Background(), tt.input) require.NoError(t, err) want, err := os.ReadFile(tt.want) diff --git a/pkg/detector/ospkg/alma/alma.go b/pkg/detector/ospkg/alma/alma.go index a9450046f27a..67465f04a1b0 100644 --- a/pkg/detector/ospkg/alma/alma.go +++ b/pkg/detector/ospkg/alma/alma.go @@ -1,12 +1,12 @@ package alma import ( + "context" "strings" "time" version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/alma" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -25,36 +25,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the AlmaLinux scanner type Scanner struct { vs *alma.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: alma.NewVulnSrc(), - options: o, + vs: alma.NewVulnSrc(), } } @@ -107,8 +86,8 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osver.Major(osVer)) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osver.Major(osVer)) } func addModularNamespace(name, label string) string { diff --git a/pkg/detector/ospkg/alma/alma_test.go b/pkg/detector/ospkg/alma/alma_test.go index 5934e9a29779..bd70079fd189 100644 --- a/pkg/detector/ospkg/alma/alma_test.go +++ b/pkg/detector/ospkg/alma/alma_test.go @@ -1,13 +1,11 @@ package alma_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -15,6 +13,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/alma" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -215,8 +215,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := alma.NewScanner(alma.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := alma.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/alpine/alpine.go b/pkg/detector/ospkg/alpine/alpine.go index f1d284fea15e..4602df844727 100644 --- a/pkg/detector/ospkg/alpine/alpine.go +++ b/pkg/detector/ospkg/alpine/alpine.go @@ -1,12 +1,12 @@ package alpine import ( + "context" "strings" "time" version "github.com/knqyf263/go-apk-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/alpine" @@ -50,36 +50,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Alpine scanner type Scanner struct { vs alpine.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: alpine.NewVulnSrc(), - options: o, + vs: alpine.NewVulnSrc(), } } @@ -173,8 +152,8 @@ func (s *Scanner) isVulnerable(installedVersion version.Version, adv dbTypes.Adv } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osver.Minor(osVer)) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osver.Minor(osVer)) } func (s *Scanner) repoRelease(repo *ftypes.Repository) string { diff --git a/pkg/detector/ospkg/alpine/alpine_test.go b/pkg/detector/ospkg/alpine/alpine_test.go index 35abfc1f6e98..f420cf5576ab 100644 --- a/pkg/detector/ospkg/alpine/alpine_test.go +++ b/pkg/detector/ospkg/alpine/alpine_test.go @@ -1,21 +1,21 @@ package alpine_test import ( + "context" "sort" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" + "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/detector/ospkg/alpine" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -326,8 +326,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := alpine.NewScanner(alpine.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := alpine.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/amazon/amazon.go b/pkg/detector/ospkg/amazon/amazon.go index 8bb310b131c7..0846e24c3dcb 100644 --- a/pkg/detector/ospkg/amazon/amazon.go +++ b/pkg/detector/ospkg/amazon/amazon.go @@ -1,12 +1,12 @@ package amazon import ( + "context" "strings" "time" version "github.com/knqyf263/go-deb-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/amazon" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -27,36 +27,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner to scan amazon vulnerabilities type Scanner struct { ac amazon.VulnSrc - options } // NewScanner is the factory method to return Amazon scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - ac: amazon.NewVulnSrc(), - options: *o, + ac: amazon.NewVulnSrc(), } } @@ -116,11 +95,11 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { osVer = strings.Fields(osVer)[0] if osVer != "2" && osVer != "2022" && osVer != "2023" { osVer = "1" } - return osver.Supported(s.clock, eolDates, osFamily, osVer) + return osver.Supported(ctx, eolDates, osFamily, osVer) } diff --git a/pkg/detector/ospkg/amazon/amazon_test.go b/pkg/detector/ospkg/amazon/amazon_test.go index 2839adc32e19..1fa65f0598fb 100644 --- a/pkg/detector/ospkg/amazon/amazon_test.go +++ b/pkg/detector/ospkg/amazon/amazon_test.go @@ -1,13 +1,11 @@ package amazon_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -15,6 +13,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/amazon" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -248,8 +248,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := amazon.NewScanner(amazon.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := amazon.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/chainguard/chainguard.go b/pkg/detector/ospkg/chainguard/chainguard.go index f2ef2c307034..bba9642c481c 100644 --- a/pkg/detector/ospkg/chainguard/chainguard.go +++ b/pkg/detector/ospkg/chainguard/chainguard.go @@ -1,9 +1,10 @@ package chainguard import ( + "context" + version "github.com/knqyf263/go-apk-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/chainguard" @@ -13,36 +14,15 @@ import ( "github.com/aquasecurity/trivy/pkg/types" ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Chainguard scanner type Scanner struct { vs chainguard.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: chainguard.NewVulnSrc(), - options: o, + vs: chainguard.NewVulnSrc(), } } @@ -103,7 +83,7 @@ func (s *Scanner) isVulnerable(installedVersion version.Version, adv dbTypes.Adv } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(_ ftypes.OSType, _ string) bool { +func (s *Scanner) IsSupportedVersion(_ context.Context, _ ftypes.OSType, _ string) bool { // Chainguard doesn't have versions, so there is no case where a given input yields a // result of an unsupported Chainguard version. diff --git a/pkg/detector/ospkg/debian/debian.go b/pkg/detector/ospkg/debian/debian.go index b0a1d426f4d4..c350f6d2c281 100644 --- a/pkg/detector/ospkg/debian/debian.go +++ b/pkg/detector/ospkg/debian/debian.go @@ -1,11 +1,11 @@ package debian import ( + "context" "time" version "github.com/knqyf263/go-deb-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/debian" @@ -41,36 +41,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Debian scanner type Scanner struct { vs debian.VulnSrc - *options } // NewScanner is the factory method to return Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: debian.NewVulnSrc(), - options: o, + vs: debian.NewVulnSrc(), } } @@ -140,6 +119,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osver.Major(osVer)) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osver.Major(osVer)) } diff --git a/pkg/detector/ospkg/debian/debian_test.go b/pkg/detector/ospkg/debian/debian_test.go index 9d5e847e2656..8c22a386a74d 100644 --- a/pkg/detector/ospkg/debian/debian_test.go +++ b/pkg/detector/ospkg/debian/debian_test.go @@ -1,14 +1,12 @@ package debian_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "sort" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -16,6 +14,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/debian" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -172,8 +172,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := debian.NewScanner(debian.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := debian.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/detect.go b/pkg/detector/ospkg/detect.go index 16c3102265c4..32ed2ff9c5ab 100644 --- a/pkg/detector/ospkg/detect.go +++ b/pkg/detector/ospkg/detect.go @@ -1,6 +1,7 @@ package ospkg import ( + "context" "time" "github.com/samber/lo" @@ -55,17 +56,17 @@ func RegisterDriver(name ftypes.OSType, driver Driver) { // Driver defines operations for OS package scan type Driver interface { Detect(string, *ftypes.Repository, []ftypes.Package) ([]types.DetectedVulnerability, error) - IsSupportedVersion(ftypes.OSType, string) bool + IsSupportedVersion(context.Context, ftypes.OSType, string) bool } // Detect detects the vulnerabilities -func Detect(_, osFamily ftypes.OSType, osName string, repo *ftypes.Repository, _ time.Time, pkgs []ftypes.Package) ([]types.DetectedVulnerability, bool, error) { +func Detect(ctx context.Context, _, osFamily ftypes.OSType, osName string, repo *ftypes.Repository, _ time.Time, pkgs []ftypes.Package) ([]types.DetectedVulnerability, bool, error) { driver, err := newDriver(osFamily) if err != nil { return nil, false, ErrUnsupportedOS } - eosl := !driver.IsSupportedVersion(osFamily, osName) + eosl := !driver.IsSupportedVersion(ctx, osFamily, osName) // Package `gpg-pubkey` doesn't use the correct version. // We don't need to find vulnerabilities for this package. diff --git a/pkg/detector/ospkg/mariner/mariner.go b/pkg/detector/ospkg/mariner/mariner.go index 46cafa22fce6..6e1054151518 100644 --- a/pkg/detector/ospkg/mariner/mariner.go +++ b/pkg/detector/ospkg/mariner/mariner.go @@ -1,6 +1,8 @@ package mariner import ( + "context" + version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" @@ -73,7 +75,7 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(_ ftypes.OSType, _ string) bool { +func (s *Scanner) IsSupportedVersion(_ context.Context, _ ftypes.OSType, _ string) bool { // EOL is not in public at the moment. return true } diff --git a/pkg/detector/ospkg/oracle/oracle.go b/pkg/detector/ospkg/oracle/oracle.go index e8a34c95b07a..186e0d2734dc 100644 --- a/pkg/detector/ospkg/oracle/oracle.go +++ b/pkg/detector/ospkg/oracle/oracle.go @@ -1,12 +1,12 @@ package oracle import ( + "context" "strings" "time" version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -33,15 +33,13 @@ var ( // Scanner implements oracle vulnerability scanner type Scanner struct { - vs *oracleoval.VulnSrc - clock clock.Clock + vs *oracleoval.VulnSrc } // NewScanner is the factory method to return oracle vulnerabilities func NewScanner() *Scanner { return &Scanner{ - vs: oracleoval.NewVulnSrc(), - clock: clock.RealClock{}, + vs: oracleoval.NewVulnSrc(), } } @@ -101,6 +99,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osver.Major(osVer)) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osver.Major(osVer)) } diff --git a/pkg/detector/ospkg/oracle/oracle_test.go b/pkg/detector/ospkg/oracle/oracle_test.go index e72bc1c1ed2d..40c8f26f2d9a 100644 --- a/pkg/detector/ospkg/oracle/oracle_test.go +++ b/pkg/detector/ospkg/oracle/oracle_test.go @@ -1,95 +1,91 @@ package oracle import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "k8s.io/utils/clock" - clocktesting "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" - oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/dbtest" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_IsSupportedVersion(t *testing.T) { - vectors := map[string]struct { - clock clock.Clock + tests := map[string]struct { + now time.Time osFamily ftypes.OSType osVersion string expected bool }{ "oracle3": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "3", expected: false, }, "oracle4": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "4", expected: false, }, "oracle5": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "5", expected: false, }, "oracle6": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "6", expected: true, }, "oracle7": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "7", expected: true, }, "oracle7.6": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "7.6", expected: true, }, "oracle8": { - clock: clocktesting.NewFakeClock(time.Date(2029, 7, 18, 23, 59, 58, 59, time.UTC)), + now: time.Date(2029, 7, 18, 23, 59, 58, 59, time.UTC), osFamily: "oracle", osVersion: "8", expected: true, }, "oracle8-same-time": { - clock: clocktesting.NewFakeClock(time.Date(2029, 7, 18, 23, 59, 59, 0, time.UTC)), + now: time.Date(2029, 7, 18, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "8", expected: false, }, "latest": { - clock: clocktesting.NewFakeClock(time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC)), + now: time.Date(2019, 5, 31, 23, 59, 59, 0, time.UTC), osFamily: "oracle", osVersion: "latest", expected: true, }, } - for testName, v := range vectors { - s := &Scanner{ - vs: oracleoval.NewVulnSrc(), - clock: v.clock, - } + for testName, tt := range tests { + s := NewScanner() t.Run(testName, func(t *testing.T) { - actual := s.IsSupportedVersion(v.osFamily, v.osVersion) - if actual != v.expected { - t.Errorf("[%s] got %v, want %v", testName, actual, v.expected) + ctx := clock.With(context.Background(), tt.now) + actual := s.IsSupportedVersion(ctx, tt.osFamily, tt.osVersion) + if actual != tt.expected { + t.Errorf("[%s] got %v, want %v", testName, actual, tt.expected) } }) } diff --git a/pkg/detector/ospkg/photon/photon.go b/pkg/detector/ospkg/photon/photon.go index 558e5511fc2f..b6c00f3c24f8 100644 --- a/pkg/detector/ospkg/photon/photon.go +++ b/pkg/detector/ospkg/photon/photon.go @@ -1,11 +1,11 @@ package photon import ( + "context" "time" version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/photon" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -26,36 +26,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Photon scanner type Scanner struct { vs photon.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: photon.NewVulnSrc(), - options: o, + vs: photon.NewVulnSrc(), } } @@ -96,6 +75,6 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osVer) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osVer) } diff --git a/pkg/detector/ospkg/photon/photon_test.go b/pkg/detector/ospkg/photon/photon_test.go index 84d1e947880d..b81b0fd30d6d 100644 --- a/pkg/detector/ospkg/photon/photon_test.go +++ b/pkg/detector/ospkg/photon/photon_test.go @@ -1,13 +1,11 @@ package photon_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -15,6 +13,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/photon" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -147,8 +147,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := photon.NewScanner(photon.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := photon.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/redhat/redhat.go b/pkg/detector/ospkg/redhat/redhat.go index 54bedcbf98c3..fe7581dbf481 100644 --- a/pkg/detector/ospkg/redhat/redhat.go +++ b/pkg/detector/ospkg/redhat/redhat.go @@ -1,6 +1,7 @@ package redhat import ( + "context" "fmt" "sort" "strings" @@ -10,7 +11,6 @@ import ( "golang.org/x/exp/maps" "golang.org/x/exp/slices" "golang.org/x/xerrors" - "k8s.io/utils/clock" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" ustrings "github.com/aquasecurity/trivy-db/pkg/utils/strings" @@ -64,36 +64,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the RedHat scanner type Scanner struct { vs redhat.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: redhat.NewVulnSrc(), - options: o, + vs: redhat.NewVulnSrc(), } } @@ -208,13 +187,13 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln } // IsSupportedVersion checks is OSFamily can be scanned with Redhat scanner -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { osVer = osver.Major(osVer) if osFamily == ftypes.CentOS { - return osver.Supported(s.clock, centosEOLDates, osFamily, osVer) + return osver.Supported(ctx, centosEOLDates, osFamily, osVer) } - return osver.Supported(s.clock, redhatEOLDates, osFamily, osVer) + return osver.Supported(ctx, redhatEOLDates, osFamily, osVer) } func isFromSupportedVendor(pkg ftypes.Package) bool { diff --git a/pkg/detector/ospkg/redhat/redhat_test.go b/pkg/detector/ospkg/redhat/redhat_test.go index 034e37a8e40c..3910b87f9cac 100644 --- a/pkg/detector/ospkg/redhat/redhat_test.go +++ b/pkg/detector/ospkg/redhat/redhat_test.go @@ -1,14 +1,12 @@ package redhat_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "os" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/dbtest" @@ -16,6 +14,8 @@ import ( ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMain(m *testing.M) { @@ -435,8 +435,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := redhat.NewScanner(redhat.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := redhat.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/rocky/rocky.go b/pkg/detector/ospkg/rocky/rocky.go index 5de786675b34..49aaa4d0a543 100644 --- a/pkg/detector/ospkg/rocky/rocky.go +++ b/pkg/detector/ospkg/rocky/rocky.go @@ -1,11 +1,11 @@ package rocky import ( + "context" "time" version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/rocky" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -24,36 +24,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Rocky Linux scanner type Scanner struct { vs *rocky.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: rocky.NewVulnSrc(), - options: o, + vs: rocky.NewVulnSrc(), } } @@ -107,8 +86,8 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osver.Major(osVer)) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osver.Major(osVer)) } func addModularNamespace(name, label string) string { diff --git a/pkg/detector/ospkg/rocky/rocky_test.go b/pkg/detector/ospkg/rocky/rocky_test.go index 4a4c68f047d6..dddba1df850a 100644 --- a/pkg/detector/ospkg/rocky/rocky_test.go +++ b/pkg/detector/ospkg/rocky/rocky_test.go @@ -1,13 +1,11 @@ package rocky_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -15,6 +13,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/rocky" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -175,8 +175,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := rocky.NewScanner(rocky.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := rocky.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/suse/suse.go b/pkg/detector/ospkg/suse/suse.go index 9b685a50c448..617161df87aa 100644 --- a/pkg/detector/ospkg/suse/suse.go +++ b/pkg/detector/ospkg/suse/suse.go @@ -1,11 +1,11 @@ package suse import ( + "context" "time" version "github.com/knqyf263/go-rpm-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" susecvrf "github.com/aquasecurity/trivy-db/pkg/vulnsrc/suse-cvrf" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -58,18 +58,6 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Type defines SUSE type type Type int @@ -83,29 +71,18 @@ const ( // Scanner implements the SUSE scanner type Scanner struct { vs susecvrf.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(t Type, opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } - +func NewScanner(t Type) *Scanner { switch t { case SUSEEnterpriseLinux: return &Scanner{ - vs: susecvrf.NewVulnSrc(susecvrf.SUSEEnterpriseLinux), - options: o, + vs: susecvrf.NewVulnSrc(susecvrf.SUSEEnterpriseLinux), } case OpenSUSE: return &Scanner{ - vs: susecvrf.NewVulnSrc(susecvrf.OpenSUSE), - options: o, + vs: susecvrf.NewVulnSrc(susecvrf.OpenSUSE), } } return nil @@ -148,9 +125,9 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks if OSFamily can be scanned using SUSE scanner -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { if osFamily == ftypes.SLES { - return osver.Supported(s.clock, slesEolDates, osFamily, osVer) + return osver.Supported(ctx, slesEolDates, osFamily, osVer) } - return osver.Supported(s.clock, opensuseEolDates, osFamily, osVer) + return osver.Supported(ctx, opensuseEolDates, osFamily, osVer) } diff --git a/pkg/detector/ospkg/suse/suse_test.go b/pkg/detector/ospkg/suse/suse_test.go index 85d0024335be..7766863e2ec4 100644 --- a/pkg/detector/ospkg/suse/suse_test.go +++ b/pkg/detector/ospkg/suse/suse_test.go @@ -1,13 +1,11 @@ package suse_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -15,6 +13,8 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/suse" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { @@ -153,8 +153,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := suse.NewScanner(tt.distribution, suse.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := suse.NewScanner(tt.distribution) + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/ubuntu/testdata/fixtures/ubuntu.yaml b/pkg/detector/ospkg/ubuntu/testdata/fixtures/ubuntu.yaml index 7da30a16b22a..bcb207cd8e26 100644 --- a/pkg/detector/ospkg/ubuntu/testdata/fixtures/ubuntu.yaml +++ b/pkg/detector/ospkg/ubuntu/testdata/fixtures/ubuntu.yaml @@ -1,3 +1,10 @@ +- bucket: ubuntu 19.04 + pairs: + - bucket: wpa + pairs: + - key: CVE-2019-9243 + value: + FixedVersion: "" - bucket: ubuntu 20.04 pairs: - bucket: wpa diff --git a/pkg/detector/ospkg/ubuntu/ubuntu.go b/pkg/detector/ospkg/ubuntu/ubuntu.go index eb143fcd9952..46948806a64d 100644 --- a/pkg/detector/ospkg/ubuntu/ubuntu.go +++ b/pkg/detector/ospkg/ubuntu/ubuntu.go @@ -1,12 +1,12 @@ package ubuntu import ( + "context" "strings" "time" version "github.com/knqyf263/go-deb-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ubuntu" osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version" @@ -63,36 +63,15 @@ var ( } ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Ubuntu scanner type Scanner struct { vs ubuntu.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: ubuntu.NewVulnSrc(), - options: o, + vs: ubuntu.NewVulnSrc(), } } @@ -149,8 +128,8 @@ func (s *Scanner) Detect(osVer string, _ *ftypes.Repository, pkgs []ftypes.Packa } // IsSupportedVersion checks is OSFamily can be scanned using Ubuntu scanner -func (s *Scanner) IsSupportedVersion(osFamily ftypes.OSType, osVer string) bool { - return osver.Supported(s.clock, eolDates, osFamily, osVer) +func (s *Scanner) IsSupportedVersion(ctx context.Context, osFamily ftypes.OSType, osVer string) bool { + return osver.Supported(ctx, eolDates, osFamily, osVer) } // versionFromEolDates checks if actual (not ESM) version is not outdated @@ -165,7 +144,7 @@ func (s *Scanner) versionFromEolDates(osVer string) string { // then we need to get vulnerabilities for `18.04` // if `18.04` is outdated - we need to use `18.04-ESM` (we will return error until we add `18.04-ESM` to eolDates) ver := strings.TrimRight(osVer, "-ESM") - if eol, ok := eolDates[ver]; ok && s.clock.Now().Before(eol) { + if eol, ok := eolDates[ver]; ok && time.Now().Before(eol) { // TODO: time.Now() should be replaced with clock.Now() return ver } return osVer diff --git a/pkg/detector/ospkg/ubuntu/ubuntu_test.go b/pkg/detector/ospkg/ubuntu/ubuntu_test.go index 96979fca7095..a2218e211b77 100644 --- a/pkg/detector/ospkg/ubuntu/ubuntu_test.go +++ b/pkg/detector/ospkg/ubuntu/ubuntu_test.go @@ -1,14 +1,12 @@ package ubuntu_test import ( + "context" + "github.com/aquasecurity/trivy/pkg/clock" "sort" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - fake "k8s.io/utils/clock/testing" - "github.com/aquasecurity/trivy-db/pkg/db" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" @@ -16,12 +14,13 @@ import ( "github.com/aquasecurity/trivy/pkg/detector/ospkg/ubuntu" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestScanner_Detect(t *testing.T) { type args struct { osVer string - now time.Time pkgs []ftypes.Package } tests := []struct { @@ -39,7 +38,6 @@ func TestScanner_Detect(t *testing.T) { }, args: args{ osVer: "20.04", - now: time.Date(2019, 3, 31, 23, 59, 59, 0, time.UTC), pkgs: []ftypes.Package{ { Name: "wpa", @@ -91,7 +89,6 @@ func TestScanner_Detect(t *testing.T) { }, args: args{ osVer: "20.04-ESM", - now: time.Date(2019, 3, 31, 23, 59, 59, 0, time.UTC), pkgs: []ftypes.Package{ { Name: "wpa", @@ -136,14 +133,13 @@ func TestScanner_Detect(t *testing.T) { }, }, { - name: "ubuntu 20.04-ESM. 20.04 is outdated", + name: "ubuntu 19.04-ESM, 19.04 is outdated", // Use 19.04-ESM for testing, although it doesn't exist fixtures: []string{ "testdata/fixtures/ubuntu.yaml", "testdata/fixtures/data-source.yaml", }, args: args{ - osVer: "20.04-ESM", - now: time.Date(2031, 3, 31, 23, 59, 59, 0, time.UTC), + osVer: "19.04-ESM", pkgs: []ftypes.Package{ { Name: "wpa", @@ -165,7 +161,6 @@ func TestScanner_Detect(t *testing.T) { }, args: args{ osVer: "21.04", - now: time.Date(2019, 3, 31, 23, 59, 59, 0, time.UTC), pkgs: []ftypes.Package{ { Name: "jq", @@ -183,7 +178,7 @@ func TestScanner_Detect(t *testing.T) { _ = dbtest.InitDB(t, tt.fixtures) defer db.Close() - s := ubuntu.NewScanner(ubuntu.WithClock(fake.NewFakeClock(tt.args.now))) + s := ubuntu.NewScanner() got, err := s.Detect(tt.args.osVer, nil, tt.args.pkgs) if tt.wantErr != "" { require.Error(t, err) @@ -258,8 +253,9 @@ func TestScanner_IsSupportedVersion(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - s := ubuntu.NewScanner(ubuntu.WithClock(fake.NewFakeClock(tt.now))) - got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) + ctx := clock.With(context.Background(), tt.now) + s := ubuntu.NewScanner() + got := s.IsSupportedVersion(ctx, tt.args.osFamily, tt.args.osVer) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/detector/ospkg/version/version.go b/pkg/detector/ospkg/version/version.go index 2e0fce38a2ce..dc47ffd88409 100644 --- a/pkg/detector/ospkg/version/version.go +++ b/pkg/detector/ospkg/version/version.go @@ -1,11 +1,11 @@ package version import ( + "context" "strings" "time" - "k8s.io/utils/clock" - + "github.com/aquasecurity/trivy/pkg/clock" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" ) @@ -28,11 +28,11 @@ func Minor(osVer string) string { return major + "." + minor } -func Supported(c clock.Clock, eolDates map[string]time.Time, osFamily ftypes.OSType, osVer string) bool { +func Supported(ctx context.Context, eolDates map[string]time.Time, osFamily ftypes.OSType, osVer string) bool { eol, ok := eolDates[osVer] if !ok { log.Logger.Warnf("This OS version is not on the EOL list: %s %s", osFamily, osVer) return true // can be the latest version } - return c.Now().Before(eol) + return clock.Now(ctx).Before(eol) } diff --git a/pkg/detector/ospkg/wolfi/wolfi.go b/pkg/detector/ospkg/wolfi/wolfi.go index c4d8d71d972c..9757fc6aa637 100644 --- a/pkg/detector/ospkg/wolfi/wolfi.go +++ b/pkg/detector/ospkg/wolfi/wolfi.go @@ -1,9 +1,10 @@ package wolfi import ( + "context" + version "github.com/knqyf263/go-apk-version" "golang.org/x/xerrors" - "k8s.io/utils/clock" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy-db/pkg/vulnsrc/wolfi" @@ -13,36 +14,15 @@ import ( "github.com/aquasecurity/trivy/pkg/types" ) -type options struct { - clock clock.Clock -} - -type option func(*options) - -func WithClock(c clock.Clock) option { - return func(opts *options) { - opts.clock = c - } -} - // Scanner implements the Wolfi scanner type Scanner struct { vs wolfi.VulnSrc - *options } // NewScanner is the factory method for Scanner -func NewScanner(opts ...option) *Scanner { - o := &options{ - clock: clock.RealClock{}, - } - - for _, opt := range opts { - opt(o) - } +func NewScanner() *Scanner { return &Scanner{ - vs: wolfi.NewVulnSrc(), - options: o, + vs: wolfi.NewVulnSrc(), } } @@ -103,7 +83,7 @@ func (s *Scanner) isVulnerable(installedVersion version.Version, adv dbTypes.Adv } // IsSupportedVersion checks if the version is supported. -func (s *Scanner) IsSupportedVersion(_ ftypes.OSType, _ string) bool { +func (s *Scanner) IsSupportedVersion(_ context.Context, _ ftypes.OSType, _ string) bool { // Wolfi doesn't have versions, so there is no case where a given input yields a // result of an unsupported Wolfi version. diff --git a/pkg/k8s/commands/run.go b/pkg/k8s/commands/run.go index ec3e61385c65..61ea4860db61 100644 --- a/pkg/k8s/commands/run.go +++ b/pkg/k8s/commands/run.go @@ -116,14 +116,14 @@ func (r *runner) run(ctx context.Context, artifacts []*k8sArtifacts.Artifact) er if err != nil { return xerrors.Errorf("compliance report build error: %w", err) } - return cr.Write(complianceReport, cr.Option{ + return cr.Write(ctx, complianceReport, cr.Option{ Format: r.flagOpts.Format, Report: r.flagOpts.ReportFormat, Output: output, }) } - if err := k8sRep.Write(rpt, report.Option{ + if err := k8sRep.Write(ctx, rpt, report.Option{ Format: r.flagOpts.Format, Report: r.flagOpts.ReportFormat, Output: output, diff --git a/pkg/k8s/report/cyclonedx.go b/pkg/k8s/report/cyclonedx.go index 0640aed036a6..6e10d34e7e89 100644 --- a/pkg/k8s/report/cyclonedx.go +++ b/pkg/k8s/report/cyclonedx.go @@ -1,6 +1,7 @@ package report import ( + "context" "io" cdx "github.com/CycloneDX/cyclonedx-go" @@ -25,7 +26,7 @@ func NewCycloneDXWriter(output io.Writer, format cdx.BOMFileFormat, appVersion s } } -func (w CycloneDXWriter) Write(component *core.Component) error { - bom := w.marshaler.Marshal(component) +func (w CycloneDXWriter) Write(ctx context.Context, component *core.Component) error { + bom := w.marshaler.Marshal(ctx, component) return w.encoder.Encode(bom) } diff --git a/pkg/k8s/report/table.go b/pkg/k8s/report/table.go index f2cf548ca1a9..640d116cbd84 100644 --- a/pkg/k8s/report/table.go +++ b/pkg/k8s/report/table.go @@ -1,6 +1,7 @@ package report import ( + "context" "io" "sync" @@ -28,7 +29,11 @@ const ( ) func WorkloadColumns() []string { - return []string{VulnerabilitiesColumn, MisconfigurationsColumn, SecretsColumn} + return []string{ + VulnerabilitiesColumn, + MisconfigurationsColumn, + SecretsColumn, + } } func RoleColumns() []string { @@ -39,13 +44,17 @@ func InfraColumns() []string { return []string{InfraAssessmentColumn} } -func (tw TableWriter) Write(report Report) error { +func (tw TableWriter) Write(ctx context.Context, report Report) error { switch tw.Report { case AllReport: - t := pkgReport.Writer{Output: tw.Output, Severities: tw.Severities, ShowMessageOnce: &sync.Once{}} + t := pkgReport.Writer{ + Output: tw.Output, + Severities: tw.Severities, + ShowMessageOnce: &sync.Once{}, + } for _, r := range report.Resources { if r.Report.Results.Failed() { - err := t.Write(r.Report) + err := t.Write(ctx, r.Report) if err != nil { return err } diff --git a/pkg/k8s/writer.go b/pkg/k8s/writer.go index 4decab422699..0e218b38f30f 100644 --- a/pkg/k8s/writer.go +++ b/pkg/k8s/writer.go @@ -1,6 +1,7 @@ package k8s import ( + "context" "fmt" cdx "github.com/CycloneDX/cyclonedx-go" @@ -10,12 +11,8 @@ import ( "github.com/aquasecurity/trivy/pkg/types" ) -type Writer interface { - Write(report.Report) error -} - // Write writes the results in the give format -func Write(k8sreport report.Report, option report.Option) error { +func Write(ctx context.Context, k8sreport report.Report, option report.Option) error { k8sreport.PrintErrors() switch option.Format { @@ -41,7 +38,7 @@ func Write(k8sreport report.Report, option report.Option) error { ColumnHeading: report.ColumnHeading(option.Scanners, option.Components, r.Columns), } - if err := writer.Write(r.Report); err != nil { + if err := writer.Write(ctx, r.Report); err != nil { return err } } @@ -49,7 +46,7 @@ func Write(k8sreport report.Report, option report.Option) error { return nil case types.FormatCycloneDX: w := report.NewCycloneDXWriter(option.Output, cdx.BOMFileFormatJSON, option.APIVersion) - return w.Write(k8sreport.RootComponent) + return w.Write(ctx, k8sreport.RootComponent) } return nil } diff --git a/pkg/k8s/writer_test.go b/pkg/k8s/writer_test.go index d747b8867154..f8ab555b26c6 100644 --- a/pkg/k8s/writer_test.go +++ b/pkg/k8s/writer_test.go @@ -2,6 +2,8 @@ package k8s import ( "bytes" + "context" + "github.com/stretchr/testify/require" "regexp" "strings" "testing" @@ -393,8 +395,8 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`, Components: tc.components, } - Write(tc.report, opt) - + err := Write(context.Background(), tc.report, opt) + require.NoError(t, err) assert.Equal(t, tc.expectedOutput, stripAnsi(output.String()), tc.name) }) } diff --git a/pkg/report/cyclonedx/cyclonedx.go b/pkg/report/cyclonedx/cyclonedx.go index a99d2f6511db..f624c02e83b2 100644 --- a/pkg/report/cyclonedx/cyclonedx.go +++ b/pkg/report/cyclonedx/cyclonedx.go @@ -1,6 +1,7 @@ package cyclonedx import ( + "context" "io" cdx "github.com/CycloneDX/cyclonedx-go" @@ -26,8 +27,8 @@ func NewWriter(output io.Writer, appVersion string) Writer { } // Write writes the results in CycloneDX format -func (w Writer) Write(report types.Report) error { - bom, err := w.marshaler.Marshal(report) +func (w Writer) Write(ctx context.Context, report types.Report) error { + bom, err := w.marshaler.Marshal(ctx, report) if err != nil { return xerrors.Errorf("CycloneDX marshal error: %w", err) } diff --git a/pkg/report/github/github.go b/pkg/report/github/github.go index 8384f27b0e74..512a3dc9c528 100644 --- a/pkg/report/github/github.go +++ b/pkg/report/github/github.go @@ -1,6 +1,7 @@ package github import ( + "context" "encoding/json" "fmt" "io" @@ -71,11 +72,11 @@ type Writer struct { Version string } -func (w Writer) Write(report types.Report) error { +func (w Writer) Write(ctx context.Context, report types.Report) error { snapshot := &DependencySnapshot{} // use now() method that can be overwritten while integration tests run - snapshot.Scanned = clock.Now().Format(time.RFC3339) + snapshot.Scanned = clock.Now(ctx).Format(time.RFC3339) snapshot.Detector = Detector{ Name: "trivy", Version: w.Version, diff --git a/pkg/report/github/github_test.go b/pkg/report/github/github_test.go index b7187c9723c8..ada2e8c84880 100644 --- a/pkg/report/github/github_test.go +++ b/pkg/report/github/github_test.go @@ -2,6 +2,7 @@ package github_test import ( "bytes" + "context" "encoding/json" "testing" @@ -174,7 +175,7 @@ func TestWriter_Write(t *testing.T) { inputResults := tt.report - err := w.Write(inputResults) + err := w.Write(context.Background(), inputResults) assert.NoError(t, err) var got github.DependencySnapshot diff --git a/pkg/report/json.go b/pkg/report/json.go index 15da8041add0..57ac92cfe8ca 100644 --- a/pkg/report/json.go +++ b/pkg/report/json.go @@ -1,6 +1,7 @@ package report import ( + "context" "encoding/json" "fmt" "io" @@ -16,7 +17,7 @@ type JSONWriter struct { } // Write writes the results in JSON format -func (jw JSONWriter) Write(report types.Report) error { +func (jw JSONWriter) Write(ctx context.Context, report types.Report) error { output, err := json.MarshalIndent(report, "", " ") if err != nil { return xerrors.Errorf("failed to marshal json: %w", err) diff --git a/pkg/report/json_test.go b/pkg/report/json_test.go index ea486c145327..493fd6d8f641 100644 --- a/pkg/report/json_test.go +++ b/pkg/report/json_test.go @@ -2,6 +2,7 @@ package report_test import ( "bytes" + "context" "encoding/json" "testing" @@ -85,7 +86,7 @@ func TestReportWriter_JSON(t *testing.T) { }, } - err := jw.Write(inputResults) + err := jw.Write(context.Background(), inputResults) assert.NoError(t, err) var got types.Report diff --git a/pkg/report/predicate/vuln.go b/pkg/report/predicate/vuln.go index c1f15edb59de..9c975a4be76a 100644 --- a/pkg/report/predicate/vuln.go +++ b/pkg/report/predicate/vuln.go @@ -1,6 +1,7 @@ package predicate import ( + "context" "encoding/json" "fmt" "io" @@ -59,8 +60,7 @@ func NewVulnWriter(output io.Writer, version string) VulnWriter { } } -func (w VulnWriter) Write(report types.Report) error { - +func (w VulnWriter) Write(ctx context.Context, report types.Report) error { predicate := CosignVulnPredicate{} purl := packageurl.NewPackageURL("github", "aquasecurity", "trivy", w.version, nil, "") @@ -70,7 +70,7 @@ func (w VulnWriter) Write(report types.Report) error { Result: report, } - now := clock.Now() + now := clock.Now(ctx) predicate.Metadata = Metadata{ ScanStartedOn: now, ScanFinishedOn: now, diff --git a/pkg/report/predicate/vuln_test.go b/pkg/report/predicate/vuln_test.go index a09716b849c0..8477a3971bd4 100644 --- a/pkg/report/predicate/vuln_test.go +++ b/pkg/report/predicate/vuln_test.go @@ -2,6 +2,7 @@ package predicate_test import ( "bytes" + "context" "encoding/json" "testing" "time" @@ -84,7 +85,6 @@ func TestWriter_Write(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - inputResults := types.Report{ SchemaVersion: 2, ArtifactName: "alpine:3.14", @@ -98,10 +98,10 @@ func TestWriter_Write(t *testing.T) { output := bytes.NewBuffer(nil) - clock.SetFakeTime(t, time.Date(2022, 7, 22, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2022, 7, 22, 12, 20, 30, 5, time.UTC)) writer := predicate.NewVulnWriter(output, "dev") - err := writer.Write(inputResults) + err := writer.Write(ctx, inputResults) require.NoError(t, err) var got predicate.CosignVulnPredicate diff --git a/pkg/report/sarif.go b/pkg/report/sarif.go index 621f6696b96f..800737a84258 100644 --- a/pkg/report/sarif.go +++ b/pkg/report/sarif.go @@ -1,6 +1,7 @@ package report import ( + "context" "fmt" "html" "io" @@ -121,7 +122,7 @@ func getRuleIndex(id string, indexes map[string]int) int { } } -func (sw *SarifWriter) Write(report types.Report) error { +func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { sarifReport, err := sarif.New(sarif.Version210) if err != nil { return xerrors.Errorf("error creating a new sarif template: %w", err) diff --git a/pkg/report/sarif_test.go b/pkg/report/sarif_test.go index 556491c1dcad..737662dcd536 100644 --- a/pkg/report/sarif_test.go +++ b/pkg/report/sarif_test.go @@ -549,7 +549,7 @@ func TestReportWriter_Sarif(t *testing.T) { w := report.SarifWriter{ Output: sarifWritten, } - err := w.Write(tt.input) + err := w.Write(nil, tt.input) assert.NoError(t, err) result := &sarif.Report{} diff --git a/pkg/report/spdx/spdx.go b/pkg/report/spdx/spdx.go index 848e26172dbe..7984db0e1517 100644 --- a/pkg/report/spdx/spdx.go +++ b/pkg/report/spdx/spdx.go @@ -1,6 +1,7 @@ package spdx import ( + "context" "encoding/json" "io" @@ -28,8 +29,8 @@ func NewWriter(output io.Writer, version string, spdxFormat types.Format) Writer } } -func (w Writer) Write(report types.Report) error { - spdxDoc, err := w.marshaler.Marshal(report) +func (w Writer) Write(ctx context.Context, report types.Report) error { + spdxDoc, err := w.marshaler.Marshal(ctx, report) if err != nil { return xerrors.Errorf("failed to marshal spdx: %w", err) } diff --git a/pkg/report/table/table.go b/pkg/report/table/table.go index 8be620f36589..652fda43a327 100644 --- a/pkg/report/table/table.go +++ b/pkg/report/table/table.go @@ -1,6 +1,7 @@ package table import ( + "context" "fmt" "io" "os" @@ -52,7 +53,7 @@ type Renderer interface { } // Write writes the result on standard output -func (tw Writer) Write(report types.Report) error { +func (tw Writer) Write(_ context.Context, report types.Report) error { for _, result := range report.Results { // Not display a table of custom resources if result.Class == types.ClassCustom { diff --git a/pkg/report/table/table_test.go b/pkg/report/table/table_test.go index cbce1fd18e22..90edcdabcb7b 100644 --- a/pkg/report/table/table_test.go +++ b/pkg/report/table/table_test.go @@ -354,7 +354,7 @@ package-lock.json dbTypes.SeverityMedium, }, } - err := writer.Write(types.Report{Results: tc.results}) + err := writer.Write(nil, types.Report{Results: tc.results}) assert.NoError(t, err) assert.Equal(t, tc.expectedOutput, tableWritten.String(), tc.name) }) diff --git a/pkg/report/template.go b/pkg/report/template.go index d320a420f722..7a28a65cfbb2 100644 --- a/pkg/report/template.go +++ b/pkg/report/template.go @@ -2,6 +2,7 @@ package report import ( "bytes" + "context" "encoding/xml" "html" "io" @@ -74,7 +75,7 @@ func NewTemplateWriter(output io.Writer, outputTemplate, appVersion string) (*Te } // Write writes result -func (tw TemplateWriter) Write(report types.Report) error { +func (tw TemplateWriter) Write(ctx context.Context, report types.Report) error { err := tw.Template.Execute(tw.Output, report.Results) if err != nil { return xerrors.Errorf("failed to write with template: %w", err) diff --git a/pkg/report/template_test.go b/pkg/report/template_test.go index 30db3595680e..4422e2c0e136 100644 --- a/pkg/report/template_test.go +++ b/pkg/report/template_test.go @@ -2,6 +2,7 @@ package report_test import ( "bytes" + "context" "os" "testing" "time" @@ -39,7 +40,8 @@ func TestReportWriter_Template(t *testing.T) { VulnerabilityID: "CVE-2019-0000", PkgName: "bar", Vulnerability: dbTypes.Vulnerability{ - Severity: dbTypes.SeverityHigh.String()}, + Severity: dbTypes.SeverityHigh.String(), + }, }, { VulnerabilityID: "CVE-2019-0001", @@ -164,7 +166,7 @@ func TestReportWriter_Template(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - clock.SetFakeTime(t, time.Date(2020, 8, 10, 7, 28, 17, 958601, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2020, 8, 10, 7, 28, 17, 958601, time.UTC)) os.Setenv("AWS_ACCOUNT_ID", "123456789012") got := bytes.Buffer{} @@ -180,7 +182,7 @@ func TestReportWriter_Template(t *testing.T) { w, err := report.NewTemplateWriter(&got, tc.template, "dev") require.NoError(t, err) - err = w.Write(inputReport) + err = w.Write(ctx, inputReport) assert.NoError(t, err) assert.Equal(t, tc.expected, got.String()) }) diff --git a/pkg/report/writer.go b/pkg/report/writer.go index c467f921d4d2..3a095bbbfc8e 100644 --- a/pkg/report/writer.go +++ b/pkg/report/writer.go @@ -39,7 +39,7 @@ func Write(ctx context.Context, report types.Report, option flag.Options) (err e // Compliance report if option.Compliance.Spec.ID != "" { - return complianceWrite(report, option, output) + return complianceWrite(ctx, report, option, output) } var writer Writer @@ -97,19 +97,19 @@ func Write(ctx context.Context, report types.Report, option flag.Options) (err e return xerrors.Errorf("unknown format: %v", option.Format) } - if err = writer.Write(report); err != nil { + if err = writer.Write(ctx, report); err != nil { return xerrors.Errorf("failed to write results: %w", err) } return nil } -func complianceWrite(report types.Report, opt flag.Options, output io.Writer) error { +func complianceWrite(ctx context.Context, report types.Report, opt flag.Options, output io.Writer) error { complianceReport, err := cr.BuildComplianceReport([]types.Results{report.Results}, opt.Compliance) if err != nil { return xerrors.Errorf("compliance report build error: %w", err) } - return cr.Write(complianceReport, cr.Option{ + return cr.Write(ctx, complianceReport, cr.Option{ Format: opt.Format, Report: opt.ReportFormat, Output: output, @@ -119,5 +119,5 @@ func complianceWrite(report types.Report, opt flag.Options, output io.Writer) er // Writer defines the result write operation type Writer interface { - Write(types.Report) error + Write(context.Context, types.Report) error } diff --git a/pkg/result/filter.go b/pkg/result/filter.go index 9dc738d318aa..524738043bb2 100644 --- a/pkg/result/filter.go +++ b/pkg/result/filter.go @@ -40,7 +40,7 @@ func Filter(ctx context.Context, report types.Report, opt FilterOption) error { return xerrors.Errorf("VEX error: %w", err) } - ignoreConf, err := getIgnoredFindings(opt.IgnoreFile) + ignoreConf, err := getIgnoredFindings(ctx, opt.IgnoreFile) if err != nil { return xerrors.Errorf("%s error: %w", opt.IgnoreFile, err) } diff --git a/pkg/result/filter_test.go b/pkg/result/filter_test.go index 7392a4779861..db9770d886d1 100644 --- a/pkg/result/filter_test.go +++ b/pkg/result/filter_test.go @@ -1072,9 +1072,9 @@ func TestFilter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fakeTime := time.Date(2020, 8, 10, 7, 28, 17, 958601, time.UTC) - clock.SetFakeTime(t, fakeTime) + ctx := clock.With(context.Background(), fakeTime) - err := result.Filter(context.Background(), tt.args.report, result.FilterOption{ + err := result.Filter(ctx, tt.args.report, result.FilterOption{ Severities: tt.args.severities, VEXPath: tt.args.vexPath, IgnoreStatuses: tt.args.ignoreStatuses, diff --git a/pkg/result/ignore.go b/pkg/result/ignore.go index 9a2e1c3156a2..ee7fef0d6ce7 100644 --- a/pkg/result/ignore.go +++ b/pkg/result/ignore.go @@ -2,6 +2,7 @@ package result import ( "bufio" + "context" "errors" "io/fs" "os" @@ -72,11 +73,11 @@ func pathMatch(path string, patterns []string) bool { return false } -func (f *IgnoreFindings) Filter() { +func (f *IgnoreFindings) Filter(ctx context.Context) { var findings IgnoreFindings for _, finding := range *f { // Filter out expired ignore findings - if !finding.ExpiredAt.IsZero() && finding.ExpiredAt.Before(clock.Now()) { + if !finding.ExpiredAt.IsZero() && finding.ExpiredAt.Before(clock.Now(ctx)) { continue } @@ -101,7 +102,7 @@ type IgnoreConfig struct { Licenses IgnoreFindings `yaml:"licenses"` } -func getIgnoredFindings(ignoreFile string) (IgnoreConfig, error) { +func getIgnoredFindings(ctx context.Context, ignoreFile string) (IgnoreConfig, error) { var conf IgnoreConfig if _, err := os.Stat(ignoreFile); errors.Is(err, fs.ErrNotExist) { // .trivyignore doesn't necessarily exist @@ -127,10 +128,10 @@ func getIgnoredFindings(ignoreFile string) (IgnoreConfig, error) { } } - conf.Vulnerabilities.Filter() - conf.Misconfigurations.Filter() - conf.Secrets.Filter() - conf.Licenses.Filter() + conf.Vulnerabilities.Filter(ctx) + conf.Misconfigurations.Filter(ctx) + conf.Secrets.Filter(ctx) + conf.Licenses.Filter(ctx) return conf, nil } diff --git a/pkg/rpc/server/listen.go b/pkg/rpc/server/listen.go index 7a6d4c46eeb6..33a3a8ee8a81 100644 --- a/pkg/rpc/server/listen.go +++ b/pkg/rpc/server/listen.go @@ -53,13 +53,12 @@ func NewServer(appVersion, addr, cacheDir, token, tokenHeader, dbRepository stri } // ListenAndServe starts Trivy server -func (s Server) ListenAndServe(serverCache cache.Cache, skipDBUpdate bool) error { +func (s Server) ListenAndServe(ctx context.Context, serverCache cache.Cache, skipDBUpdate bool) error { requestWg := &sync.WaitGroup{} dbUpdateWg := &sync.WaitGroup{} go func() { worker := newDBWorker(dbc.NewClient(s.cacheDir, true, dbc.WithDBRepository(s.dbRepository))) - ctx := context.Background() for { time.Sleep(updateInterval) if err := worker.update(ctx, s.appVersion, s.cacheDir, skipDBUpdate, dbUpdateWg, requestWg, s.RegistryOptions); err != nil { @@ -68,13 +67,13 @@ func (s Server) ListenAndServe(serverCache cache.Cache, skipDBUpdate bool) error } }() - mux := newServeMux(serverCache, dbUpdateWg, requestWg, s.token, s.tokenHeader, s.cacheDir) + mux := newServeMux(ctx, serverCache, dbUpdateWg, requestWg, s.token, s.tokenHeader, s.cacheDir) log.Logger.Infof("Listening %s...", s.addr) return http.ListenAndServe(s.addr, mux) } -func newServeMux(serverCache cache.Cache, dbUpdateWg, requestWg *sync.WaitGroup, +func newServeMux(ctx context.Context, serverCache cache.Cache, dbUpdateWg, requestWg *sync.WaitGroup, token, tokenHeader, cacheDir string) *http.ServeMux { withWaitGroup := func(base http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -85,7 +84,7 @@ func newServeMux(serverCache cache.Cache, dbUpdateWg, requestWg *sync.WaitGroup, requestWg.Add(1) defer requestWg.Done() - base.ServeHTTP(w, r) + base.ServeHTTP(w, r.WithContext(ctx)) }) } diff --git a/pkg/rpc/server/listen_test.go b/pkg/rpc/server/listen_test.go index 834627b92762..5fff3f3bc46e 100644 --- a/pkg/rpc/server/listen_test.go +++ b/pkg/rpc/server/listen_test.go @@ -253,8 +253,8 @@ func Test_newServeMux(t *testing.T) { require.NoError(t, err) defer func() { _ = c.Close() }() - ts := httptest.NewServer(newServeMux( - c, dbUpdateWg, requestWg, tt.args.token, tt.args.tokenHeader, ""), + ts := httptest.NewServer(newServeMux(context.Background(), c, dbUpdateWg, requestWg, tt.args.token, + tt.args.tokenHeader, ""), ) defer ts.Close() @@ -284,8 +284,8 @@ func Test_VersionEndpoint(t *testing.T) { require.NoError(t, err) defer func() { _ = c.Close() }() - ts := httptest.NewServer(newServeMux( - c, dbUpdateWg, requestWg, "", "", "testdata/testcache"), + ts := httptest.NewServer(newServeMux(context.Background(), c, dbUpdateWg, requestWg, "", "", + "testdata/testcache"), ) defer ts.Close() diff --git a/pkg/sbom/cyclonedx/core/cyclonedx.go b/pkg/sbom/cyclonedx/core/cyclonedx.go index 5d61f2993f72..2c5945b35416 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx.go @@ -1,6 +1,7 @@ package core import ( + "context" "fmt" "sort" "strconv" @@ -60,10 +61,10 @@ func NewCycloneDX(version string) *CycloneDX { } } -func (c *CycloneDX) Marshal(root *Component) *cdx.BOM { +func (c *CycloneDX) Marshal(ctx context.Context, root *Component) *cdx.BOM { bom := cdx.NewBOM() bom.SerialNumber = uuid.New().URN() - bom.Metadata = c.Metadata() + bom.Metadata = c.Metadata(ctx) components := make(map[string]*cdx.Component) dependencies := make(map[string]*[]string) @@ -180,9 +181,9 @@ func (c *CycloneDX) BOMRef(component *Component) string { return component.PackageURL.BOMRef() } -func (c *CycloneDX) Metadata() *cdx.Metadata { +func (c *CycloneDX) Metadata(ctx context.Context) *cdx.Metadata { return &cdx.Metadata{ - Timestamp: clock.Now().UTC().Format(timeLayout), + Timestamp: clock.Now(ctx).UTC().Format(timeLayout), Tools: &[]cdx.Tool{ { Vendor: ToolVendor, diff --git a/pkg/sbom/cyclonedx/core/cyclonedx_test.go b/pkg/sbom/cyclonedx/core/cyclonedx_test.go index 2685a56ef733..d3b37308140f 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx_test.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx_test.go @@ -1,6 +1,7 @@ package core_test import ( + "context" "testing" "time" @@ -365,11 +366,11 @@ func TestMarshaler_CoreComponent(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d") marshaler := core.NewCycloneDX("dev") - got := marshaler.Marshal(tt.rootComponent) + got := marshaler.Marshal(ctx, tt.rootComponent) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index 586b82d3ee39..16cb37c2d2fc 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -1,6 +1,7 @@ package cyclonedx import ( + "context" "fmt" "strconv" "strings" @@ -57,14 +58,14 @@ func NewMarshaler(version string) *Marshaler { } // Marshal converts the Trivy report to the CycloneDX format -func (e *Marshaler) Marshal(report types.Report) (*cdx.BOM, error) { +func (e *Marshaler) Marshal(ctx context.Context, report types.Report) (*cdx.BOM, error) { // Convert root, err := e.MarshalReport(report) if err != nil { return nil, xerrors.Errorf("failed to marshal report: %w", err) } - return e.core.Marshal(root), nil + return e.core.Marshal(ctx, root), nil } func (e *Marshaler) MarshalReport(r types.Report) (*core.Component, error) { diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 234f2b9d0ae5..8169baf040bb 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -1,6 +1,7 @@ package cyclonedx_test import ( + "context" "github.com/package-url/packageurl-go" "testing" "time" @@ -1825,11 +1826,11 @@ func TestMarshaler_Marshal(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d") marshaler := cyclonedx.NewMarshaler("dev") - got, err := marshaler.Marshal(tt.inputReport) + got, err := marshaler.Marshal(ctx, tt.inputReport) require.NoError(t, err) assert.Equal(t, tt.want, got) }) diff --git a/pkg/sbom/spdx/marshal.go b/pkg/sbom/spdx/marshal.go index 642e7d7629ab..b88f92c1c23f 100644 --- a/pkg/sbom/spdx/marshal.go +++ b/pkg/sbom/spdx/marshal.go @@ -1,6 +1,7 @@ package spdx import ( + "context" "fmt" "sort" "strconv" @@ -106,7 +107,7 @@ func NewMarshaler(version string, opts ...marshalOption) *Marshaler { return m } -func (m *Marshaler) Marshal(r types.Report) (*spdx.Document, error) { +func (m *Marshaler) Marshal(ctx context.Context, r types.Report) (*spdx.Document, error) { var relationShips []*spdx.Relationship packages := make(map[spdx.ElementID]*spdx.Package) pkgDownloadLocation := getPackageDownloadLocation(r.ArtifactType, r.ArtifactName) @@ -186,7 +187,7 @@ func (m *Marshaler) Marshal(r types.Report) (*spdx.Document, error) { CreatorType: "Tool", }, }, - Created: clock.Now().UTC().Format(time.RFC3339), + Created: clock.Now(ctx).UTC().Format(time.RFC3339), }, Packages: toPackages(packages), Relationships: relationShips, diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index eb73274bbc30..abd356d6ec7e 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -1,6 +1,7 @@ package spdx_test import ( + "context" "github.com/package-url/packageurl-go" "hash/fnv" "testing" @@ -1105,11 +1106,11 @@ func TestMarshaler_Marshal(t *testing.T) { return h.Sum64(), nil } - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d") marshaler := tspdx.NewMarshaler("0.38.1", tspdx.WithHasher(hasher)) - spdxDoc, err := marshaler.Marshal(tc.inputReport) + spdxDoc, err := marshaler.Marshal(ctx, tc.inputReport) require.NoError(t, err) assert.Equal(t, tc.wantSBOM, spdxDoc) diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index edb39b15ae8f..f76c5c7ab0ea 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -120,7 +120,7 @@ func (s Scanner) ScanTarget(ctx context.Context, target types.ScanTarget, option // Scan packages for vulnerabilities if options.Scanners.Enabled(types.VulnerabilityScanner) { var vulnResults types.Results - vulnResults, eosl, err = s.scanVulnerabilities(target, options) + vulnResults, eosl, err = s.scanVulnerabilities(ctx, target, options) if err != nil { return nil, ftypes.OS{}, xerrors.Errorf("failed to detect vulnerabilities: %w", err) } @@ -166,13 +166,13 @@ func (s Scanner) ScanTarget(ctx context.Context, target types.ScanTarget, option return results, target.OS, nil } -func (s Scanner) scanVulnerabilities(target types.ScanTarget, options types.ScanOptions) ( +func (s Scanner) scanVulnerabilities(ctx context.Context, target types.ScanTarget, options types.ScanOptions) ( types.Results, bool, error) { var eosl bool var results types.Results if slices.Contains(options.VulnType, types.VulnTypeOS) { - vuln, detectedEOSL, err := s.osPkgScanner.Scan(target, options) + vuln, detectedEOSL, err := s.osPkgScanner.Scan(ctx, target, options) if err != nil { return nil, false, xerrors.Errorf("unable to scan OS packages: %w", err) } else if vuln.Target != "" { diff --git a/pkg/scanner/ospkg/scan.go b/pkg/scanner/ospkg/scan.go index a07d6e6b2091..ebc94b1dab9c 100644 --- a/pkg/scanner/ospkg/scan.go +++ b/pkg/scanner/ospkg/scan.go @@ -1,6 +1,8 @@ package ospkg import ( + "context" + "errors" "fmt" "sort" "time" @@ -14,7 +16,7 @@ import ( type Scanner interface { Packages(target types.ScanTarget, options types.ScanOptions) types.Result - Scan(target types.ScanTarget, options types.ScanOptions) (types.Result, bool, error) + Scan(ctx context.Context, target types.ScanTarget, options types.ScanOptions) (types.Result, bool, error) } type scanner struct{} @@ -37,7 +39,7 @@ func (s *scanner) Packages(target types.ScanTarget, _ types.ScanOptions) types.R } } -func (s *scanner) Scan(target types.ScanTarget, _ types.ScanOptions) (types.Result, bool, error) { +func (s *scanner) Scan(ctx context.Context, target types.ScanTarget, _ types.ScanOptions) (types.Result, bool, error) { if !target.OS.Detected() { log.Logger.Debug("Detected OS: unknown") return types.Result{}, false, nil @@ -49,9 +51,9 @@ func (s *scanner) Scan(target types.ScanTarget, _ types.ScanOptions) (types.Resu target.OS.Name += "-ESM" } - vulns, eosl, err := ospkgDetector.Detect("", target.OS.Family, target.OS.Name, target.Repository, time.Time{}, + vulns, eosl, err := ospkgDetector.Detect(ctx, "", target.OS.Family, target.OS.Name, target.Repository, time.Time{}, target.Packages) - if err == ospkgDetector.ErrUnsupportedOS { + if errors.Is(err, ospkgDetector.ErrUnsupportedOS) { return types.Result{}, false, nil } else if err != nil { return types.Result{}, false, xerrors.Errorf("failed vulnerability detection of OS packages: %w", err) diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index cc1950b31fc9..82e900024acb 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -173,7 +173,7 @@ func (s Scanner) ScanArtifact(ctx context.Context, options types.ScanOptions) (t return types.Report{ SchemaVersion: report.SchemaVersion, - CreatedAt: clock.Now(), + CreatedAt: clock.Now(ctx), ArtifactName: artifactInfo.Name, ArtifactType: artifactInfo.Type, Metadata: types.Metadata{ diff --git a/pkg/scanner/scan_test.go b/pkg/scanner/scan_test.go index ba78193e7962..78606299303b 100644 --- a/pkg/scanner/scan_test.go +++ b/pkg/scanner/scan_test.go @@ -3,13 +3,13 @@ package scanner import ( "context" "errors" + "github.com/aquasecurity/trivy/pkg/clock" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/fanal/artifact" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" @@ -19,7 +19,6 @@ func TestScanner_ScanArtifact(t *testing.T) { type args struct { options types.ScanOptions } - clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) tests := []struct { name string args args @@ -192,6 +191,7 @@ func TestScanner_ScanArtifact(t *testing.T) { }, } for _, tt := range tests { + ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) t.Run(tt.name, func(t *testing.T) { d := new(MockDriver) d.ApplyScanExpectation(tt.scanExpectation) @@ -200,7 +200,7 @@ func TestScanner_ScanArtifact(t *testing.T) { mockArtifact.ApplyInspectExpectation(tt.inspectExpectation) s := NewScanner(d, mockArtifact) - got, err := s.ScanArtifact(context.Background(), tt.args.options) + got, err := s.ScanArtifact(ctx, tt.args.options) if tt.wantErr != "" { require.NotNil(t, err, tt.name) require.Contains(t, err.Error(), tt.wantErr, tt.name) From 7f2e4223ff87e05a475d19e952ed9a888a6b4eee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:43:57 +0000 Subject: [PATCH 057/108] chore(deps): bump google.golang.org/protobuf from 1.31.0 to 1.32.0 (#5855) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 550f357eeb93..25beafb0a2d1 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,7 @@ require ( golang.org/x/term v0.15.0 golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.28.4 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 diff --git a/go.sum b/go.sum index a9840929c6d0..6968a572969f 100644 --- a/go.sum +++ b/go.sum @@ -2467,8 +2467,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From b1489f3485fd004df99c01fe82df0ef2726a9967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:53:52 +0000 Subject: [PATCH 058/108] chore(deps): bump github.com/hashicorp/go-getter from 1.7.2 to 1.7.3 (#5856) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 25beafb0a2d1..fd6f4bf88ff2 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/google/licenseclassifier/v2 v2.0.0 github.com/google/uuid v1.4.0 github.com/google/wire v0.5.0 - github.com/hashicorp/go-getter v1.7.2 + github.com/hashicorp/go-getter v1.7.3 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.6 github.com/in-toto/in-toto-golang v0.9.0 diff --git a/go.sum b/go.sum index 6968a572969f..48c44a683ea9 100644 --- a/go.sum +++ b/go.sum @@ -1138,8 +1138,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.2 h1:uJDtyXwEfalmp1PqdxuhZqrNkUyClZAhVeZYTArbqkg= -github.com/hashicorp/go-getter v1.7.2/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= From 013df4c6b8f760adc8bf8a42d5d4623ed2ee5c2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:12:39 +0400 Subject: [PATCH 059/108] chore(deps): bump github.com/samber/lo from 1.38.1 to 1.39.0 (#5850) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fd6f4bf88ff2..0795f0a13e29 100644 --- a/go.mod +++ b/go.mod @@ -83,7 +83,7 @@ require ( github.com/owenrumney/go-sarif/v2 v2.3.0 github.com/package-url/packageurl-go v0.1.2 github.com/quasilyte/go-ruleguard/dsl v0.3.22 - github.com/samber/lo v1.38.1 + github.com/samber/lo v1.39.0 github.com/saracen/walker v0.1.3 github.com/secure-systems-lab/go-securesystemslib v0.7.0 github.com/sigstore/rekor v1.2.2 diff --git a/go.sum b/go.sum index 48c44a683ea9..b9809daebb5e 100644 --- a/go.sum +++ b/go.sum @@ -1576,8 +1576,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= -github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/saracen/walker v0.1.3 h1:YtcKKmpRPy6XJTHJ75J2QYXXZYWnZNQxPCVqZSHVV/g= github.com/saracen/walker v0.1.3/go.mod h1:FU+7qU8DeQQgSZDmmThMJi93kPkLFgy0oVAcLxurjIk= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= From 30eff9c83e4c06eaadb5c1f09d89d08c01014d79 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:16:35 +0600 Subject: [PATCH 060/108] feat(nodejs): add yarn alias support (#5818) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/coverage/language/nodejs.md | 5 +- .../nodejs/yarn/testdata/alias/package.json | 14 +++ .../nodejs/yarn/testdata/alias/yarn.lock | 44 +++++++ .../analyzer/language/nodejs/yarn/yarn.go | 38 ++++-- .../language/nodejs/yarn/yarn_test.go | 111 ++++++++++++++++++ 5 files changed, 201 insertions(+), 11 deletions(-) create mode 100644 pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/package.json create mode 100644 pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/yarn.lock diff --git a/docs/docs/coverage/language/nodejs.md b/docs/docs/coverage/language/nodejs.md index 1489c459cd7d..393491b34f46 100644 --- a/docs/docs/coverage/language/nodejs.md +++ b/docs/docs/coverage/language/nodejs.md @@ -42,7 +42,10 @@ By default, Trivy doesn't report development dependencies. Use the `--include-de ### Yarn Trivy parses `yarn.lock`, which doesn't contain information about development dependencies. -To exclude devDependencies, `package.json` also needs to be present next to `yarn.lock`. +Trivy also uses `package.json` file to handle [aliases](https://classic.yarnpkg.com/lang/en/docs/cli/add/#toc-yarn-add-alias). + +To exclude devDependencies and allow aliases, `package.json` also needs to be present next to `yarn.lock`. + Trivy analyzes `.yarn` (Yarn 2+) or `node_modules` (Yarn Classic) folder next to the yarn.lock file to detect licenses. By default, Trivy doesn't report development dependencies. Use the `--include-dev-deps` flag to include them. diff --git a/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/package.json b/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/package.json new file mode 100644 index 000000000000..caa6e0f3f637 --- /dev/null +++ b/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/package.json @@ -0,0 +1,14 @@ +{ + "name": "test", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "devDependencies": { + "foo-json": "npm:@types/jsonstream@0.8.33", + "foo-uuid": "npm:@types/uuid" + }, + "dependencies": { + "foo-debug": "npm:debug@^4.3", + "foo-ms": "npm:ms" + } +} diff --git a/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/yarn.lock b/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/yarn.lock new file mode 100644 index 000000000000..cb68abb657f9 --- /dev/null +++ b/pkg/fanal/analyzer/language/nodejs/yarn/testdata/alias/yarn.lock @@ -0,0 +1,44 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@*": + version "20.10.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.5.tgz#47ad460b514096b7ed63a1dae26fad0914ed3ab2" + integrity sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw== + dependencies: + undici-types "~5.26.4" + +"foo-debug@npm:debug@^4.3": + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +"foo-json@npm:@types/jsonstream@0.8.33": + version "0.8.33" + resolved "https://registry.yarnpkg.com/@types/jsonstream/-/jsonstream-0.8.33.tgz#7d37a16a78cf68a67858110dc1767023436fca23" + integrity sha512-yhg1SNOgJ8y2nOkvAQ1zZ1Z2xibxgFs7984+EeBPuWgo/TbuYo79+rj2wUVch3KF4GhhcwAi/AlJcehmLCXb3g== + dependencies: + "@types/node" "*" + +"foo-ms@npm:ms": + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +"foo-uuid@npm:@types/uuid": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.7.tgz#b14cebc75455eeeb160d5fe23c2fcc0c64f724d8" + integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== diff --git a/pkg/fanal/analyzer/language/nodejs/yarn/yarn.go b/pkg/fanal/analyzer/language/nodejs/yarn/yarn.go index d42c28e47128..3089b881e2e3 100644 --- a/pkg/fanal/analyzer/language/nodejs/yarn/yarn.go +++ b/pkg/fanal/analyzer/language/nodejs/yarn/yarn.go @@ -9,6 +9,7 @@ import ( "os" "path" "path/filepath" + "regexp" "sort" "strings" @@ -36,6 +37,10 @@ func init() { const version = 2 +// Taken from Yarn +// cf. https://github.com/yarnpkg/yarn/blob/328fd596de935acc6c3e134741748fcc62ec3739/src/resolvers/exotics/registry-resolver.js#L12 +var fragmentRegexp = regexp.MustCompile(`(\S+):(@?.*?)(@(.*?)|)$`) + type yarnAnalyzer struct { packageJsonParser *packagejson.Parser lockParser godeptypes.Parser @@ -193,17 +198,30 @@ func (a yarnAnalyzer) walkDependencies(libs []types.Package, pkgIDs map[string]t // Identify direct dependencies pkgs := make(map[string]types.Package) for _, pkg := range libs { - if constraint, ok := directDeps[pkg.Name]; ok { - // npm has own comparer to compare versions - if match, err := a.comparer.MatchVersion(pkg.Version, constraint); err != nil { - return nil, xerrors.Errorf("unable to match version for %s", pkg.Name) - } else if match { - // Mark as a direct dependency - pkg.Indirect = false - pkg.Dev = dev - pkgs[pkg.ID] = pkg - } + constraint, ok := directDeps[pkg.Name] + if !ok { + continue + } + + // Handle aliases + // cf. https://classic.yarnpkg.com/lang/en/docs/cli/add/#toc-yarn-add-alias + if m := fragmentRegexp.FindStringSubmatch(constraint); len(m) == 5 { + pkg.Name = m[2] // original name + constraint = m[4] } + + // npm has own comparer to compare versions + if match, err := a.comparer.MatchVersion(pkg.Version, constraint); err != nil { + return nil, xerrors.Errorf("unable to match version for %s", pkg.Name) + } else if !match { + continue + } + + // Mark as a direct dependency + pkg.Indirect = false + pkg.Dev = dev + pkgs[pkg.ID] = pkg + } // Walk indirect dependencies diff --git a/pkg/fanal/analyzer/language/nodejs/yarn/yarn_test.go b/pkg/fanal/analyzer/language/nodejs/yarn/yarn_test.go index eb8be228afd5..081d06c5954f 100644 --- a/pkg/fanal/analyzer/language/nodejs/yarn/yarn_test.go +++ b/pkg/fanal/analyzer/language/nodejs/yarn/yarn_test.go @@ -318,6 +318,117 @@ func Test_yarnLibraryAnalyzer_Analyze(t *testing.T) { }, }, }, + { + name: "happy path with alias rewrite", + dir: "testdata/alias", + want: &analyzer.AnalysisResult{ + Applications: []types.Application{ + { + Type: types.Yarn, + FilePath: "yarn.lock", + Libraries: types.Packages{ + { + ID: "foo-json@0.8.33", + Name: "@types/jsonstream", + Version: "0.8.33", + Indirect: false, + Dev: true, + Locations: []types.Location{ + { + StartLine: 19, + EndLine: 24, + }, + }, + DependsOn: []string{ + "@types/node@20.10.5", + }, + }, + { + ID: "@types/node@20.10.5", + Name: "@types/node", + Version: "20.10.5", + Indirect: true, + Dev: true, + Locations: []types.Location{ + { + StartLine: 5, + EndLine: 10, + }, + }, + DependsOn: []string{ + "undici-types@5.26.5", + }, + }, + { + ID: "foo-uuid@9.0.7", + Name: "@types/uuid", + Version: "9.0.7", + Indirect: false, + Dev: true, + Locations: []types.Location{ + { + StartLine: 31, + EndLine: 34, + }, + }, + }, + { + ID: "foo-debug@4.3.4", + Name: "debug", + Version: "4.3.4", + Indirect: false, + Locations: []types.Location{ + { + StartLine: 12, + EndLine: 17, + }, + }, + DependsOn: []string{ + "ms@2.1.2", + }, + }, + { + ID: "ms@2.1.2", + Name: "ms", + Version: "2.1.2", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 36, + EndLine: 39, + }, + }, + }, + { + ID: "foo-ms@2.1.3", + Name: "ms", + Version: "2.1.3", + Indirect: false, + Locations: []types.Location{ + { + StartLine: 26, + EndLine: 29, + }, + }, + }, + { + ID: "undici-types@5.26.5", + Name: "undici-types", + Version: "5.26.5", + Indirect: true, + Dev: true, + Locations: []types.Location{ + { + StartLine: 41, + EndLine: 44, + }, + }, + }, + }, + }, + }, + }, + }, { name: "monorepo", dir: "testdata/monorepo", From fa2e88360b13078484afb25f06d684953ec79a61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:29:08 +0400 Subject: [PATCH 061/108] chore(deps): bump github.com/secure-systems-lab/go-securesystemslib from 0.7.0 to 0.8.0 (#5852) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0795f0a13e29..cc317ab1f49e 100644 --- a/go.mod +++ b/go.mod @@ -85,7 +85,7 @@ require ( github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/samber/lo v1.39.0 github.com/saracen/walker v0.1.3 - github.com/secure-systems-lab/go-securesystemslib v0.7.0 + github.com/secure-systems-lab/go-securesystemslib v0.8.0 github.com/sigstore/rekor v1.2.2 github.com/sirupsen/logrus v1.9.3 github.com/sosedoff/gitkit v0.4.0 diff --git a/go.sum b/go.sum index b9809daebb5e..6815ebce3439 100644 --- a/go.sum +++ b/go.sum @@ -1584,8 +1584,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg= -github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI= +github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= +github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= From df3e90af8f70c5ee11aa984ddade806036fc63c3 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Fri, 5 Jan 2024 00:20:55 +0600 Subject: [PATCH 062/108] feat(python): parse licenses from dist-info folder (#4724) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- .../language/python/packaging/packaging.go | 172 +++++++++--- .../python/packaging/packaging_test.go | 89 +++--- .../setuptools-51.3.3.dist-info}/METADATA | 0 .../setuptools-51.3.3.egg-info}/PKG-INFO | 0 .../{ => egg-zip}/kitchen-1.2.6-py2.7.egg | Bin .../distlib-0.3.1.dist-info}/METADATA | 0 .../distlib-0.3.1.egg-info}/PKG-INFO | 0 .../LICENSE.txt | 254 ++++++++++++++++++ .../METADATA | 189 +++++++++++++ .../{ => no-req-files}/no-required-files.egg | Bin 10 files changed, 636 insertions(+), 68 deletions(-) rename pkg/fanal/analyzer/language/python/packaging/testdata/{classifier-license.dist-info => classifier-license-dist/setuptools-51.3.3.dist-info}/METADATA (100%) rename pkg/fanal/analyzer/language/python/packaging/testdata/{classifier-license.egg-info => classifier-license-egg/setuptools-51.3.3.egg-info}/PKG-INFO (100%) rename pkg/fanal/analyzer/language/python/packaging/testdata/{ => egg-zip}/kitchen-1.2.6-py2.7.egg (100%) rename pkg/fanal/analyzer/language/python/packaging/testdata/{happy.dist-info => happy-dist/distlib-0.3.1.dist-info}/METADATA (100%) rename pkg/fanal/analyzer/language/python/packaging/testdata/{happy.egg-info => happy-egg/distlib-0.3.1.egg-info}/PKG-INFO (100%) create mode 100644 pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/LICENSE.txt create mode 100644 pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/METADATA rename pkg/fanal/analyzer/language/python/packaging/testdata/{ => no-req-files}/no-required-files.egg (100%) diff --git a/pkg/fanal/analyzer/language/python/packaging/packaging.go b/pkg/fanal/analyzer/language/python/packaging/packaging.go index 790b8e16d25b..9cd03cf0f9a6 100644 --- a/pkg/fanal/analyzer/language/python/packaging/packaging.go +++ b/pkg/fanal/analyzer/language/python/packaging/packaging.go @@ -4,27 +4,43 @@ import ( "archive/zip" "bytes" "context" + "errors" "io" + "io/fs" "os" + "path" + "path/filepath" "strings" + "github.com/samber/lo" "golang.org/x/xerrors" dio "github.com/aquasecurity/go-dep-parser/pkg/io" "github.com/aquasecurity/go-dep-parser/pkg/python/packaging" + godeptypes "github.com/aquasecurity/go-dep-parser/pkg/types" "github.com/aquasecurity/trivy/pkg/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language" "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/licensing" + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/utils/fsutils" ) func init() { - analyzer.RegisterAnalyzer(&packagingAnalyzer{}) + analyzer.RegisterPostAnalyzer(analyzer.TypePythonPkg, newPackagingAnalyzer) } const version = 1 +func newPackagingAnalyzer(opt analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) { + return &packagingAnalyzer{ + pkgParser: packaging.NewParser(), + licenseClassifierConfidenceLevel: opt.LicenseScannerOption.ClassifierConfidenceLevel, + }, nil +} + var ( - requiredFiles = []string{ + eggFiles = []string{ // .egg format // https://setuptools.readthedocs.io/en/latest/deprecated/python_eggs.html#eggs-and-their-formats ".egg", // zip format @@ -34,35 +50,125 @@ var ( // https://setuptools.readthedocs.io/en/latest/deprecated/python_eggs.html#eggs-and-their-formats ".egg-info", ".egg-info/PKG-INFO", - - // wheel - ".dist-info/METADATA", } ) -type packagingAnalyzer struct{} +type packagingAnalyzer struct { + pkgParser godeptypes.Parser + licenseClassifierConfidenceLevel float64 +} + +// PostAnalyze analyzes egg and wheel files. +func (a packagingAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) { -// Analyze analyzes egg and wheel files. -func (a packagingAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) { - r := input.Content + var apps []types.Application + + required := func(path string, _ fs.DirEntry) bool { + return filepath.Base(path) == "METADATA" || isEggFile(path) + } + + err := fsutils.WalkDir(input.FS, ".", required, func(path string, d fs.DirEntry, r io.Reader) error { + rsa, ok := r.(dio.ReadSeekerAt) + if !ok { + return xerrors.New("invalid reader") + } - // .egg file is zip format and PKG-INFO needs to be extracted from the zip file. - if strings.HasSuffix(input.FilePath, ".egg") { - pkginfoInZip, err := a.analyzeEggZip(input.Content, input.Info.Size()) + // .egg file is zip format and PKG-INFO needs to be extracted from the zip file. + if strings.HasSuffix(path, ".egg") { + info, err := d.Info() + if err != nil { + return xerrors.Errorf("egg file error: %w", err) + } + pkginfoInZip, err := a.analyzeEggZip(rsa, info.Size()) + if err != nil { + return xerrors.Errorf("egg analysis error: %w", err) + } + + // Egg archive may not contain required files, then we will get nil. Skip this archives + if pkginfoInZip == nil { + return nil + } + rsa = pkginfoInZip + } + + app, err := a.parse(path, rsa, input.Options.FileChecksum) if err != nil { - return nil, xerrors.Errorf("egg analysis error: %w", err) + return xerrors.Errorf("parse error: %w", err) + } else if app == nil { + return nil + } + + if err := a.fillAdditionalData(input.FS, app); err != nil { + log.Logger.Warnf("Unable to collect additional info: %s", err) } - // Egg archive may not contain required files, then we will get nil. Skip this archives - if pkginfoInZip == nil { - return nil, nil + apps = append(apps, *app) + return nil + }) + + if err != nil { + return nil, xerrors.Errorf("python package walk error: %w", err) + } + return &analyzer.AnalysisResult{ + Applications: apps, + }, nil +} + +func (a packagingAnalyzer) fillAdditionalData(fsys fs.FS, app *types.Application) error { + for i, lib := range app.Libraries { + var licenses []string + for _, lic := range lib.Licenses { + // Parser adds `file://` prefix to filepath from `License-File` field + // We need to read this file to find licenses + // Otherwise, this is the name of the license + if !strings.HasPrefix(lic, "file://") { + licenses = append(licenses, lic) + continue + } + licenseFilePath := path.Base(strings.TrimPrefix(lic, "file://")) + + findings, err := classifyLicense(app.FilePath, licenseFilePath, a.licenseClassifierConfidenceLevel, fsys) + if err != nil { + return err + } else if len(findings) == 0 { + continue + } + + // License found + foundLicenses := lo.Map(findings, func(finding types.LicenseFinding, _ int) string { + return finding.Name + }) + licenses = append(licenses, foundLicenses...) } + app.Libraries[i].Licenses = licenses + } - r = pkginfoInZip + return nil +} + +func classifyLicense(dir, licPath string, classifierConfidenceLevel float64, fsys fs.FS) (types.LicenseFindings, error) { + // Note that fs.FS is always slashed regardless of the platform, + // and path.Join should be used rather than filepath.Join. + f, err := fsys.Open(path.Join(path.Dir(dir), licPath)) + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } else if err != nil { + return nil, xerrors.Errorf("file open error: %w", err) } + defer f.Close() - p := packaging.NewParser() - return language.AnalyzePackage(types.PythonPkg, input.FilePath, r, p, input.Options.FileChecksum) + l, err := licensing.Classify(licPath, f, classifierConfidenceLevel) + if err != nil { + return nil, xerrors.Errorf("license classify error: %w", err) + } else if l == nil { + return nil, nil + } + + return l.Findings, nil +} + +func (a packagingAnalyzer) parse(filePath string, r dio.ReadSeekerAt, checksum bool) (*types.Application, error) { + return language.ParsePackage(types.PythonPkg, filePath, r, a.pkgParser, checksum) } func (a packagingAnalyzer) analyzeEggZip(r io.ReaderAt, size int64) (dio.ReadSeekerAt, error) { @@ -71,17 +177,16 @@ func (a packagingAnalyzer) analyzeEggZip(r io.ReaderAt, size int64) (dio.ReadSee return nil, xerrors.Errorf("zip reader error: %w", err) } - for _, file := range zr.File { - if !a.Required(file.Name, nil) { - continue - } - - return a.open(file) + found, ok := lo.Find(zr.File, func(f *zip.File) bool { + return isEggFile(f.Name) + }) + if !ok { + return nil, nil } - - return nil, nil + return a.open(found) } +// open reads the file content in the zip archive to make it seekable. func (a packagingAnalyzer) open(file *zip.File) (dio.ReadSeekerAt, error) { f, err := file.Open() if err != nil { @@ -98,12 +203,13 @@ func (a packagingAnalyzer) open(file *zip.File) (dio.ReadSeekerAt, error) { } func (a packagingAnalyzer) Required(filePath string, _ os.FileInfo) bool { - for _, r := range requiredFiles { - if strings.HasSuffix(filePath, r) { - return true - } - } - return false + return strings.Contains(filePath, ".dist-info") || isEggFile(filePath) +} + +func isEggFile(filePath string) bool { + return lo.SomeBy(eggFiles, func(fileName string) bool { + return strings.HasSuffix(filePath, fileName) + }) } func (a packagingAnalyzer) Type() analyzer.Type { diff --git a/pkg/fanal/analyzer/language/python/packaging/packaging_test.go b/pkg/fanal/analyzer/language/python/packaging/packaging_test.go index 198c0bec273c..420cb7c3bc44 100644 --- a/pkg/fanal/analyzer/language/python/packaging/packaging_test.go +++ b/pkg/fanal/analyzer/language/python/packaging/packaging_test.go @@ -15,25 +15,25 @@ import ( func Test_packagingAnalyzer_Analyze(t *testing.T) { tests := []struct { name string - inputFile string + dir string includeChecksum bool want *analyzer.AnalysisResult wantErr string }{ { - name: "egg zip", - inputFile: "testdata/kitchen-1.2.6-py2.7.egg", + name: "egg zip", + dir: "testdata/egg-zip", want: &analyzer.AnalysisResult{ Applications: []types.Application{ { Type: types.PythonPkg, - FilePath: "testdata/kitchen-1.2.6-py2.7.egg", + FilePath: "kitchen-1.2.6-py2.7.egg", Libraries: types.Packages{ { Name: "kitchen", Version: "1.2.6", Licenses: []string{"LGPLv2+"}, - FilePath: "testdata/kitchen-1.2.6-py2.7.egg", + FilePath: "kitchen-1.2.6-py2.7.egg", }, }, }, @@ -42,19 +42,19 @@ func Test_packagingAnalyzer_Analyze(t *testing.T) { }, { name: "egg-info", - inputFile: "testdata/happy.egg-info/PKG-INFO", + dir: "testdata/happy-egg", includeChecksum: true, want: &analyzer.AnalysisResult{ Applications: []types.Application{ { Type: types.PythonPkg, - FilePath: "testdata/happy.egg-info/PKG-INFO", + FilePath: "distlib-0.3.1.egg-info/PKG-INFO", Libraries: types.Packages{ { Name: "distlib", Version: "0.3.1", Licenses: []string{"Python license"}, - FilePath: "testdata/happy.egg-info/PKG-INFO", + FilePath: "distlib-0.3.1.egg-info/PKG-INFO", Digest: "sha1:d9d89d8ed3b2b683767c96814c9c5d3e57ef2e1b", }, }, @@ -63,19 +63,19 @@ func Test_packagingAnalyzer_Analyze(t *testing.T) { }, }, { - name: "egg-info license classifiers", - inputFile: "testdata/classifier-license.egg-info/PKG-INFO", + name: "egg-info license classifiers", + dir: "testdata/classifier-license-egg", want: &analyzer.AnalysisResult{ Applications: []types.Application{ { Type: types.PythonPkg, - FilePath: "testdata/classifier-license.egg-info/PKG-INFO", + FilePath: "setuptools-51.3.3.egg-info/PKG-INFO", Libraries: types.Packages{ { Name: "setuptools", Version: "51.3.3", Licenses: []string{"MIT License"}, - FilePath: "testdata/classifier-license.egg-info/PKG-INFO", + FilePath: "setuptools-51.3.3.egg-info/PKG-INFO", }, }, }, @@ -83,19 +83,19 @@ func Test_packagingAnalyzer_Analyze(t *testing.T) { }, }, { - name: "dist-info license classifiers", - inputFile: "testdata/classifier-license.dist-info/METADATA", + name: "dist-info license classifiers", + dir: "testdata/classifier-license-dist", want: &analyzer.AnalysisResult{ Applications: []types.Application{ { Type: types.PythonPkg, - FilePath: "testdata/classifier-license.dist-info/METADATA", + FilePath: "setuptools-51.3.3.dist-info/METADATA", Libraries: types.Packages{ { Name: "setuptools", Version: "51.3.3", Licenses: []string{"MIT License"}, - FilePath: "testdata/classifier-license.dist-info/METADATA", + FilePath: "setuptools-51.3.3.dist-info/METADATA", }, }, }, @@ -103,19 +103,19 @@ func Test_packagingAnalyzer_Analyze(t *testing.T) { }, }, { - name: "wheel", - inputFile: "testdata/happy.dist-info/METADATA", + name: "wheel", + dir: "testdata/happy-dist", want: &analyzer.AnalysisResult{ Applications: []types.Application{ { Type: types.PythonPkg, - FilePath: "testdata/happy.dist-info/METADATA", + FilePath: "distlib-0.3.1.dist-info/METADATA", Libraries: types.Packages{ { Name: "distlib", Version: "0.3.1", Licenses: []string{"Python license"}, - FilePath: "testdata/happy.dist-info/METADATA", + FilePath: "distlib-0.3.1.dist-info/METADATA", }, }, }, @@ -123,27 +123,41 @@ func Test_packagingAnalyzer_Analyze(t *testing.T) { }, }, { - name: "egg zip doesn't contain required files", - inputFile: "testdata/no-required-files.egg", - want: nil, + name: "egg zip doesn't contain required files", + dir: "testdata/no-req-files", + want: &analyzer.AnalysisResult{}, + }, + { + name: "license file in dist.info", + dir: "testdata/license-file-dist", + want: &analyzer.AnalysisResult{ + Applications: []types.Application{ + { + Type: types.PythonPkg, + FilePath: "typing_extensions-4.4.0.dist-info/METADATA", + Libraries: []types.Package{ + { + Name: "typing_extensions", + Version: "4.4.0", + Licenses: []string{"BeOpen", "CNRI-Python-GPL-Compatible", "LicenseRef-MIT-Lucent", "Python-2.0"}, + FilePath: "typing_extensions-4.4.0.dist-info/METADATA", + }, + }, + }, + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - f, err := os.Open(tt.inputFile) - require.NoError(t, err) - defer f.Close() - stat, err := f.Stat() + a, err := newPackagingAnalyzer(analyzer.AnalyzerOptions{}) require.NoError(t, err) - - a := packagingAnalyzer{} - ctx := context.Background() - got, err := a.Analyze(ctx, analyzer.AnalysisInput{ - FilePath: tt.inputFile, - Info: stat, - Content: f, - Options: analyzer.AnalysisOptions{FileChecksum: tt.includeChecksum}, + got, err := a.PostAnalyze(context.Background(), analyzer.PostAnalysisInput{ + FS: os.DirFS(tt.dir), + Options: analyzer.AnalysisOptions{ + FileChecksum: tt.includeChecksum, + }, }) if tt.wantErr != "" { @@ -184,6 +198,11 @@ func Test_packagingAnalyzer_Required(t *testing.T) { filePath: "python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA", want: true, }, + { + name: "wheel license", + filePath: "python3.8/site-packages/wrapt-1.12.1.dist-info/LICENSE", + want: true, + }, { name: "sad", filePath: "random/PKG-INFO", diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license.dist-info/METADATA b/pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license-dist/setuptools-51.3.3.dist-info/METADATA similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license.dist-info/METADATA rename to pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license-dist/setuptools-51.3.3.dist-info/METADATA diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license.egg-info/PKG-INFO b/pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license-egg/setuptools-51.3.3.egg-info/PKG-INFO similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license.egg-info/PKG-INFO rename to pkg/fanal/analyzer/language/python/packaging/testdata/classifier-license-egg/setuptools-51.3.3.egg-info/PKG-INFO diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/kitchen-1.2.6-py2.7.egg b/pkg/fanal/analyzer/language/python/packaging/testdata/egg-zip/kitchen-1.2.6-py2.7.egg similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/kitchen-1.2.6-py2.7.egg rename to pkg/fanal/analyzer/language/python/packaging/testdata/egg-zip/kitchen-1.2.6-py2.7.egg diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/happy.dist-info/METADATA b/pkg/fanal/analyzer/language/python/packaging/testdata/happy-dist/distlib-0.3.1.dist-info/METADATA similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/happy.dist-info/METADATA rename to pkg/fanal/analyzer/language/python/packaging/testdata/happy-dist/distlib-0.3.1.dist-info/METADATA diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/happy.egg-info/PKG-INFO b/pkg/fanal/analyzer/language/python/packaging/testdata/happy-egg/distlib-0.3.1.egg-info/PKG-INFO similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/happy.egg-info/PKG-INFO rename to pkg/fanal/analyzer/language/python/packaging/testdata/happy-egg/distlib-0.3.1.egg-info/PKG-INFO diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/LICENSE.txt b/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/LICENSE.txt new file mode 100644 index 000000000000..1df6b3b8de0e --- /dev/null +++ b/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/LICENSE.txt @@ -0,0 +1,254 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/METADATA b/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/METADATA new file mode 100644 index 000000000000..e4fc961591e5 --- /dev/null +++ b/pkg/fanal/analyzer/language/python/packaging/testdata/license-file-dist/typing_extensions-4.4.0.dist-info/METADATA @@ -0,0 +1,189 @@ +Metadata-Version: 2.1 +Name: typing_extensions +Version: 4.4.0 +Summary: Backported and Experimental Type Hints for Python 3.7+ +Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing +Author-email: "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +License-File: licenses/LICENSE.txt +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Topic :: Software Development +Project-URL: Bug Tracker, https://github.com/python/typing_extensions/issues +Project-URL: Changes, https://github.com/python/typing_extensions/blob/main/CHANGELOG.md +Project-URL: Documentation, https://typing.readthedocs.io/ +Project-URL: Home, https://github.com/python/typing_extensions +Project-URL: Q & A, https://github.com/python/typing/discussions +Project-URL: Repository, https://github.com/python/typing_extensions + +# Typing Extensions + +[![Chat at https://gitter.im/python/typing](https://badges.gitter.im/python/typing.svg)](https://gitter.im/python/typing) + +## Overview + +The `typing_extensions` module serves two related purposes: + +- Enable use of new type system features on older Python versions. For example, + `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows + users on previous Python versions to use it too. +- Enable experimentation with new type system PEPs before they are accepted and + added to the `typing` module. + +New features may be added to `typing_extensions` as soon as they are specified +in a PEP that has been added to the [python/peps](https://github.com/python/peps) +repository. If the PEP is accepted, the feature will then be added to `typing` +for the next CPython release. No typing PEP has been rejected so far, so we +haven't yet figured out how to deal with that possibility. + +Starting with version 4.0.0, `typing_extensions` uses +[Semantic Versioning](https://semver.org/). The +major version is incremented for all backwards-incompatible changes. +Therefore, it's safe to depend +on `typing_extensions` like this: `typing_extensions >=x.y, <(x+1)`, +where `x.y` is the first version that includes all features you need. + +`typing_extensions` supports Python versions 3.7 and higher. In the future, +support for older Python versions will be dropped some time after that version +reaches end of life. + +## Included items + +This module currently contains the following: + +- Experimental features + + - `override` (see PEP 698) + - The `default=` argument to `TypeVar`, `ParamSpec`, and `TypeVarTuple` (see PEP 696) + - The `infer_variance=` argument to `TypeVar` (see PEP 695) + +- In `typing` since Python 3.11 + + - `assert_never` + - `assert_type` + - `clear_overloads` + - `@dataclass_transform()` (see PEP 681) + - `get_overloads` + - `LiteralString` (see PEP 675) + - `Never` + - `NotRequired` (see PEP 655) + - `reveal_type` + - `Required` (see PEP 655) + - `Self` (see PEP 673) + - `TypeVarTuple` (see PEP 646; the `typing_extensions` version supports the `default=` argument from PEP 696) + - `Unpack` (see PEP 646) + +- In `typing` since Python 3.10 + + - `Concatenate` (see PEP 612) + - `ParamSpec` (see PEP 612; the `typing_extensions` version supports the `default=` argument from PEP 696) + - `ParamSpecArgs` (see PEP 612) + - `ParamSpecKwargs` (see PEP 612) + - `TypeAlias` (see PEP 613) + - `TypeGuard` (see PEP 647) + - `is_typeddict` + +- In `typing` since Python 3.9 + + - `Annotated` (see PEP 593) + +- In `typing` since Python 3.8 + + - `final` (see PEP 591) + - `Final` (see PEP 591) + - `Literal` (see PEP 586) + - `Protocol` (see PEP 544) + - `runtime_checkable` (see PEP 544) + - `TypedDict` (see PEP 589) + - `get_origin` (`typing_extensions` provides this function only in Python 3.7+) + - `get_args` (`typing_extensions` provides this function only in Python 3.7+) + +- In `typing` since Python 3.7 + + - `OrderedDict` + +- In `typing` since Python 3.5 or 3.6 (see [the typing documentation](https://docs.python.org/3.10/library/typing.html) for details) + + - `AsyncContextManager` + - `AsyncGenerator` + - `AsyncIterable` + - `AsyncIterator` + - `Awaitable` + - `ChainMap` + - `ClassVar` (see PEP 526) + - `ContextManager` + - `Coroutine` + - `Counter` + - `DefaultDict` + - `Deque` + - `NewType` + - `NoReturn` + - `overload` + - `Text` + - `Type` + - `TYPE_CHECKING` + - `get_type_hints` + +- The following have always been present in `typing`, but the `typing_extensions` versions provide + additional features: + + - `Any` (supports inheritance since Python 3.11) + - `NamedTuple` (supports multiple inheritance with `Generic` since Python 3.11) + - `TypeVar` (see PEPs 695 and 696) + +# Other Notes and Limitations + +Certain objects were changed after they were added to `typing`, and +`typing_extensions` provides a backport even on newer Python versions: + +- `TypedDict` does not store runtime information + about which (if any) keys are non-required in Python 3.8, and does not + honor the `total` keyword with old-style `TypedDict()` in Python + 3.9.0 and 3.9.1. `TypedDict` also does not support multiple inheritance + with `typing.Generic` on Python <3.11. +- `get_origin` and `get_args` lack support for `Annotated` in + Python 3.8 and lack support for `ParamSpecArgs` and `ParamSpecKwargs` + in 3.9. +- `@final` was changed in Python 3.11 to set the `.__final__` attribute. +- `@overload` was changed in Python 3.11 to make function overloads + introspectable at runtime. In order to access overloads with + `typing_extensions.get_overloads()`, you must use + `@typing_extensions.overload`. +- `NamedTuple` was changed in Python 3.11 to allow for multiple inheritance + with `typing.Generic`. +- Since Python 3.11, it has been possible to inherit from `Any` at + runtime. `typing_extensions.Any` also provides this capability. +- `TypeVar` gains two additional parameters, `default=` and `infer_variance=`, + in the draft PEPs 695 and 696, which are being considered for inclusion + in Python 3.12. + +There are a few types whose interface was modified between different +versions of typing. For example, `typing.Sequence` was modified to +subclass `typing.Reversible` as of Python 3.5.3. + +These changes are _not_ backported to prevent subtle compatibility +issues when mixing the differing implementations of modified classes. + +Certain types have incorrect runtime behavior due to limitations of older +versions of the typing module: + +- `ParamSpec` and `Concatenate` will not work with `get_args` and + `get_origin`. Certain PEP 612 special cases in user-defined + `Generic`s are also not available. + +These types are only guaranteed to work for static type checking. + +## Running tests + +To run tests, navigate into the appropriate source directory and run +`test_typing_extensions.py`. + diff --git a/pkg/fanal/analyzer/language/python/packaging/testdata/no-required-files.egg b/pkg/fanal/analyzer/language/python/packaging/testdata/no-req-files/no-required-files.egg similarity index 100% rename from pkg/fanal/analyzer/language/python/packaging/testdata/no-required-files.egg rename to pkg/fanal/analyzer/language/python/packaging/testdata/no-req-files/no-required-files.egg From b508414ca23699772ecaeebdc15b4d059329b4dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:01:57 +0000 Subject: [PATCH 063/108] chore(deps): bump actions/setup-python from 4 to 5 (#5848) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/mkdocs-dev.yaml | 2 +- .github/workflows/mkdocs-latest.yaml | 2 +- .github/workflows/publish-chart.yaml | 2 +- .github/workflows/test-docs.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mkdocs-dev.yaml b/.github/workflows/mkdocs-dev.yaml index a00da7666d61..4f378f7e0665 100644 --- a/.github/workflows/mkdocs-dev.yaml +++ b/.github/workflows/mkdocs-dev.yaml @@ -16,7 +16,7 @@ jobs: with: fetch-depth: 0 persist-credentials: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: 3.x - name: Install dependencies diff --git a/.github/workflows/mkdocs-latest.yaml b/.github/workflows/mkdocs-latest.yaml index 4dac23fa748f..3b0fd13fd17d 100644 --- a/.github/workflows/mkdocs-latest.yaml +++ b/.github/workflows/mkdocs-latest.yaml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 persist-credentials: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: 3.x - name: Install dependencies diff --git a/.github/workflows/publish-chart.yaml b/.github/workflows/publish-chart.yaml index 349ae1f47202..60ba0b497f2b 100644 --- a/.github/workflows/publish-chart.yaml +++ b/.github/workflows/publish-chart.yaml @@ -30,7 +30,7 @@ jobs: with: version: v3.5.0 - name: Set up python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.7 - name: Setup Chart Linting diff --git a/.github/workflows/test-docs.yaml b/.github/workflows/test-docs.yaml index 48ee68928074..98961a35de97 100644 --- a/.github/workflows/test-docs.yaml +++ b/.github/workflows/test-docs.yaml @@ -14,7 +14,7 @@ jobs: with: fetch-depth: 0 persist-credentials: true - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: 3.x - name: Install dependencies From e1a60cc88c55594f81184748693e9f71cea65f47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:03:00 +0000 Subject: [PATCH 064/108] chore(deps): bump alpine from 3.18.5 to 3.19.0 (#5849) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.canary | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f8a548e2af86..ed943e5a389f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.18.5 +FROM alpine:3.19.0 RUN apk --no-cache add ca-certificates git COPY trivy /usr/local/bin/trivy COPY contrib/*.tpl contrib/ diff --git a/Dockerfile.canary b/Dockerfile.canary index 93a38cbc5138..d247693262e0 100644 --- a/Dockerfile.canary +++ b/Dockerfile.canary @@ -1,4 +1,4 @@ -FROM alpine:3.18.5 +FROM alpine:3.19.0 RUN apk --no-cache add ca-certificates git # binaries were created with GoReleaser From 682210ac64476c0a3d73218814d36f2909a0e9c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:10:54 +0000 Subject: [PATCH 065/108] chore(deps): bump modernc.org/sqlite from 1.23.1 to 1.28.0 (#5854) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 17 ++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index cc317ab1f49e..64e0039cf291 100644 --- a/go.mod +++ b/go.mod @@ -113,7 +113,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.28.4 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 - modernc.org/sqlite v1.23.1 + modernc.org/sqlite v1.28.0 ) require github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c @@ -399,9 +399,9 @@ require ( lukechampine.com/uint128 v1.2.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect - modernc.org/libc v1.22.5 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.5.0 // indirect + modernc.org/libc v1.29.0 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect modernc.org/opt v0.1.3 // indirect modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.0.1 // indirect diff --git a/go.sum b/go.sum index 6815ebce3439..bf76848fa214 100644 --- a/go.sum +++ b/go.sum @@ -1557,7 +1557,6 @@ github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= @@ -2590,16 +2589,16 @@ modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= -modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= -modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= -modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/libc v1.29.0 h1:tTFRFq69YKCF2QyGNuRUQxKBm1uZZLubf6Cjh/pVHXs= +modernc.org/libc v1.29.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= -modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= From 121898423bca55ed70b540a020881b675caa665d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:31:32 +0000 Subject: [PATCH 066/108] chore(deps): bump sigstore/cosign-installer from 3.2.0 to 3.3.0 (#5847) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-release.yaml b/.github/workflows/reusable-release.yaml index 4943da9522e7..48b4601a07a5 100644 --- a/.github/workflows/reusable-release.yaml +++ b/.github/workflows/reusable-release.yaml @@ -36,7 +36,7 @@ jobs: remove-haskell: 'true' - name: Cosign install - uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 + uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 - name: Set up QEMU uses: docker/setup-qemu-action@v3 From c72dfbfbb0e4c04ebfc2b611d635ceb1d1cd98c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:31:33 +0000 Subject: [PATCH 067/108] chore(deps): bump github.com/open-policy-agent/opa from 0.58.0 to 0.60.0 (#5853) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 43 ++++++++++++++------------- go.sum | 94 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 70 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 64e0039cf291..0e8aa580f494 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/go-containerregistry v0.17.0 github.com/google/licenseclassifier/v2 v2.0.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/google/wire v0.5.0 github.com/hashicorp/go-getter v1.7.3 github.com/hashicorp/go-multierror v1.1.1 @@ -76,7 +76,7 @@ require ( github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 github.com/moby/buildkit v0.11.6 - github.com/open-policy-agent/opa v0.58.0 + github.com/open-policy-agent/opa v0.60.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc5 github.com/openvex/go-vex v0.2.5 @@ -91,7 +91,7 @@ require ( github.com/sosedoff/gitkit v0.4.0 github.com/spdx/tools-golang v0.5.4-0.20231108154018-0c0f394b5e1a // v0.5.3 with necessary changes. Can be upgraded to version 0.5.4 after release. github.com/spf13/cast v1.5.1 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 @@ -119,10 +119,10 @@ require ( require github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c require ( - cloud.google.com/go v0.110.7 // indirect + cloud.google.com/go v0.110.8 // indirect cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.1 // indirect + cloud.google.com/go/iam v1.1.2 // indirect cloud.google.com/go/storage v1.31.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect @@ -218,7 +218,7 @@ require ( github.com/containerd/typeurl v1.0.2 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -235,7 +235,7 @@ require ( github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect @@ -267,7 +267,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -342,7 +342,7 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sergi/go-diff v1.2.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/skeema/knownhosts v1.2.1 // indirect @@ -362,25 +362,26 @@ require ( github.com/zclconf/go-cty-yaml v1.0.3 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/sdk v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.11.0 // indirect + golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/sys v0.15.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/api v0.138.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/grpc v1.60.1 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index bf76848fa214..14f1b6c11d89 100644 --- a/go.sum +++ b/go.sum @@ -33,8 +33,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= -cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME= +cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -113,8 +113,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4= +cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -700,8 +700,9 @@ github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoY github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= @@ -799,8 +800,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -1081,8 +1082,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= @@ -1111,8 +1112,8 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -1444,8 +1445,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/open-policy-agent/opa v0.58.0 h1:S5qvevW8JoFizU7Hp66R/Y1SOXol0aCdFYVkzIqIpUo= -github.com/open-policy-agent/opa v0.58.0/go.mod h1:EGWBwvmyt50YURNvL8X4W5hXdlKeNhAHn3QXsetmYcc= +github.com/open-policy-agent/opa v0.60.0 h1:ZPoPt4yeNs5UXCpd/P/btpSyR8CR0wfhVoh9BOwgJNs= +github.com/open-policy-agent/opa v0.60.0/go.mod h1:aD5IK6AiLNYBjNXn7E02++yC8l4Z+bRDvgM6Ss0bBzA= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1586,8 +1587,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -1633,8 +1634,8 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1780,20 +1781,20 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= @@ -1802,8 +1803,8 @@ go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -1978,8 +1979,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= +golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2155,8 +2156,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2294,8 +2295,9 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -2403,12 +2405,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2448,8 +2450,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From d990e702a20f061cb0bd90e4eb9930d4e752f2e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:35:25 +0000 Subject: [PATCH 068/108] chore(deps): bump actions/stale from 8 to 9 (#5846) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale-issues.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale-issues.yaml b/.github/workflows/stale-issues.yaml index 8827397755c8..fa30a6d1cc01 100644 --- a/.github/workflows/stale-issues.yaml +++ b/.github/workflows/stale-issues.yaml @@ -7,7 +7,7 @@ jobs: timeout-minutes: 1 runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: 'This PR is stale because it has been labeled with inactivity.' From cba67d1f065c90b4a4a1edf73349cc9ac3a9393f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:31:44 +0000 Subject: [PATCH 069/108] chore(deps): bump actions/setup-go from 4 to 5 (#5845) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/auto-update-labels.yaml | 2 +- .github/workflows/reusable-release.yaml | 2 +- .github/workflows/test.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/auto-update-labels.yaml b/.github/workflows/auto-update-labels.yaml index faf89e218d19..26307a3f50c5 100644 --- a/.github/workflows/auto-update-labels.yaml +++ b/.github/workflows/auto-update-labels.yaml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod diff --git a/.github/workflows/reusable-release.yaml b/.github/workflows/reusable-release.yaml index 48b4601a07a5..0799506c9af9 100644 --- a/.github/workflows/reusable-release.yaml +++ b/.github/workflows/reusable-release.yaml @@ -74,7 +74,7 @@ jobs: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e2552b0d2566..a6401facaa68 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod @@ -72,7 +72,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod @@ -101,7 +101,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod @@ -121,7 +121,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod @@ -152,7 +152,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod - name: Install tools @@ -186,7 +186,7 @@ jobs: uses: actions/checkout@v4.1.1 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: go.mod From 2cdd65dd6445ac3d43da0085e6e5c7b69df8c5ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 23:38:44 +0400 Subject: [PATCH 070/108] chore(deps): bump github.com/aws/aws-sdk-go-v2/service/sts from 1.26.2 to 1.26.7 (#5880) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 0e8aa580f494..ba284038c23f 100644 --- a/go.mod +++ b/go.mod @@ -29,14 +29,14 @@ require ( github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 - github.com/aws/aws-sdk-go-v2 v1.23.5 + github.com/aws/aws-sdk-go-v2 v1.24.1 github.com/aws/aws-sdk-go-v2/config v1.25.11 github.com/aws/aws-sdk-go-v2/credentials v1.16.9 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 - github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 + github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cheggaaa/pb/v3 v3.1.4 @@ -158,8 +158,8 @@ require ( github.com/aws/aws-sdk-go v1.48.4 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 // indirect @@ -182,10 +182,10 @@ require ( github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.20.6 // indirect github.com/aws/aws-sdk-go-v2/service/emr v1.28.7 // indirect github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 // indirect github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 // indirect github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 // indirect github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.5 // indirect @@ -201,7 +201,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 // indirect github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 // indirect - github.com/aws/smithy-go v1.18.1 // indirect + github.com/aws/smithy-go v1.19.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/briandowns/spinner v1.23.0 // indirect diff --git a/go.sum b/go.sum index 14f1b6c11d89..aeba5c1a5a92 100644 --- a/go.sum +++ b/go.sum @@ -376,8 +376,8 @@ github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDL github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg= -github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds= +github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= +github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 h1:Sc82v7tDQ/vdU1WtuSyzZ1I7y/68j//HJ6uozND1IDs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= @@ -396,14 +396,14 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49 github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42/go.mod h1:oDfgXoBBmj+kXnqxDDnIDnC56QBosglKp8ftRCTxR+0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36/go.mod h1:rwr4WnmFi3RJO0M4dxbJtgi9BPLMpVBMX1nUte5ha9U= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= @@ -455,16 +455,16 @@ github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 h1:qGv+oW4uV1T3kbE9uSYEfdZbo38O github.com/aws/aws-sdk-go-v2/service/iam v1.22.5/go.mod h1:8lyPrjQczmx72ac9s82zTjf9xLqs7uuFMG9TVEZ07XU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15/go.mod h1:26SQUPcTNgV1Tapwdt4a1rOsYRsnBsJHLMPoxK2b0d8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 h1:e3PCNeEaev/ZF01cQyNZgmYE9oYYePIMJs2mWSKG514= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3/go.mod h1:gIeeNyaL8tIEqZrzAnTeyhHcE0yysCtcaP+N9kxLZ+E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 h1:skaFGzv+3kA+v2BPKhuekeb1Hbb105+44r8ASC+q5SE= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38/go.mod h1:epIZoRSSbRIwLPJU5F+OldHhwZPBdpDeQkRdCeY3+00= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 h1:UKjpIDLVF90RfV88XurdduMoTxPqtGHZMIDYZQM7RO4= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35/go.mod h1:B3dUg0V6eJesUTi+m27NUkj7n8hdDKYUpxj8f4+TqaQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 h1:EamsKe+ZjkOQjDdHd86/JCEucjFKQ9T0atWKO4s2Lgs= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8/go.mod h1:Q0vV3/csTpbkfKLI5Sb56cJQTCTtJ0ixdb7P+Wedqiw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 h1:9ulSU5ClouoPIYhDQdg9tpl83d5Yb91PXTKK+17q+ow= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6/go.mod h1:lnc2taBsR9nTlz9meD+lhFZZ9EWY712QHrRflWpTcOA= github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 h1:DyJVI9uQB+mO4IuKEE4AloqOvo9XFg7olhZkwWZJ7wc= @@ -498,15 +498,15 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSW github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 h1:8dU9zqA77C5egbU6yd4hFLaiIdPv3rU+6cp7sz5FjCU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2/go.mod h1:7Lt5mjQ8x5rVdKqg+sKKDeuwoszDJIIPmkd8BVsEdS0= github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 h1:fFrLsy08wEbAisqW3KDl/cPHrF43GmV79zXB9EwJiZw= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.2/go.mod h1:7Ld9eTqocTvJqqJ5K/orbSDwmGcpRdlDiLjz2DO+SL8= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 h1:+gN/oR6jT53ggl+jd/7wO4A7u9r1GLCpMiRiatD79WQ= github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1/go.mod h1:56TIMTOeThR8Ep+O82yxpTuGzCOzZuo3XmsJXxukgUo= github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.18.1 h1:pOdBTUfXNazOlxLrgeYalVnuTpKreACHtc62xLwIB3c= -github.com/aws/smithy-go v1.18.1/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= From c47ed0d816a8bedbfbef86b634790d604e623e43 Mon Sep 17 00:00:00 2001 From: Juan Ariza Toledano Date: Sat, 6 Jan 2024 11:48:39 +0100 Subject: [PATCH 071/108] feat(vex): Add support for CSAF format (#5535) Signed-off-by: juan131 Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/supply-chain/vex.md | 140 ++++++++++++++++++++- go.mod | 31 +++-- go.sum | 79 +++++++----- pkg/vex/csaf.go | 78 ++++++++++++ pkg/vex/cyclonedx.go | 94 +++++++++++++++ pkg/vex/openvex.go | 46 +++++++ pkg/vex/testdata/csaf-affected.json | 93 ++++++++++++++ pkg/vex/testdata/csaf-not-affected.json | 93 ++++++++++++++ pkg/vex/testdata/unknown.json | 2 +- pkg/vex/vex.go | 154 ++++-------------------- pkg/vex/vex_test.go | 92 +++++++++++++- 11 files changed, 722 insertions(+), 180 deletions(-) create mode 100644 pkg/vex/csaf.go create mode 100644 pkg/vex/cyclonedx.go create mode 100644 pkg/vex/openvex.go create mode 100644 pkg/vex/testdata/csaf-affected.json create mode 100644 pkg/vex/testdata/csaf-not-affected.json diff --git a/docs/docs/supply-chain/vex.md b/docs/docs/supply-chain/vex.md index a0b46fbbc1f0..a551629943cc 100644 --- a/docs/docs/supply-chain/vex.md +++ b/docs/docs/supply-chain/vex.md @@ -5,10 +5,11 @@ Trivy supports filtering detected vulnerabilities using [the Vulnerability Exploitability Exchange (VEX)](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf), a standardized format for sharing and exchanging information about vulnerabilities. By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status. -Currently, Trivy supports the following two formats: +Currently, Trivy supports the following three formats: - [CycloneDX](https://cyclonedx.org/capabilities/vex/) - [OpenVEX](https://github.com/openvex/spec) +- [CSAF](https://oasis-open.github.io/csaf-documentation/specification.html) This is still an experimental implementation, with only minimal functionality added. @@ -182,4 +183,139 @@ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document. [openvex]: https://github.com/openvex/spec -[purl]: https://github.com/package-url/purl-spec \ No newline at end of file +[purl]: https://github.com/package-url/purl-spec + +## CSAF +Trivy also supports [CSAF][csaf] format for VEX. +Since CSAF aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy. + +The following steps are required: + +1. Generate a SBOM (CycloneDX or SPDX) +2. Create a CSAF document based on the SBOM generated in step 1 +3. Provide the CSAF document when scanning the SBOM + +### Generating the SBOM +You can generate a CycloneDX or SPDX SBOM with Trivy as follows: + +```shell +$ trivy image --format spdx-json --output debian11.spdx.json debian:11 +``` + +### Create the CSAF document +Create a CSAF document in JSON format as follows: + +``` +$ cat < debian11.vex.csaf +{ + "document": { + "category": "csaf_vex", + "csaf_version": "2.0", + "notes": [ + { + "category": "summary", + "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", + "title": "Author comment" + } + ], + "publisher": { + "category": "vendor", + "name": "Example Company ProductCERT", + "namespace": "https://psirt.example.com" + }, + "title": "AquaSecurity example VEX document", + "tracking": { + "current_release_date": "2024-01-01T11:00:00.000Z", + "generator": { + "date": "2024-01-01T11:00:00.000Z", + "engine": { + "name": "Secvisogram", + "version": "1.11.0" + } + }, + "id": "2024-EVD-UC-01-A-001", + "initial_release_date": "2024-01-01T11:00:00.000Z", + "revision_history": [ + { + "date": "2024-01-01T11:00:00.000Z", + "number": "1", + "summary": "Initial version." + } + ], + "status": "final", + "version": "1" + } + }, + "product_tree": { + "branches": [ + { + "branches": [ + { + "branches": [ + { + "category": "product_version", + "name": "5.3", + "product": { + "name": "Database Libraries 5.3", + "product_id": "LIBDB-5328", + "product_identification_helper": { + "purl": "pkg:deb/debian/libdb5.3@5.3.28%2Bdfsg1-0.8?arch=amd64\u0026distro=debian-11.8" + } + } + } + ], + "category": "product_name", + "name": "Database Libraries" + } + ], + "category": "vendor", + "name": "Debian" + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2019-8457", + "notes": [ + { + "category": "description", + "text": "SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-of-bound read in the rtreenode() function when handling invalid rtree tables.", + "title": "CVE description" + } + ], + "product_status": { + "known_not_affected": [ + "LIBDB-5328" + ] + }, + "threats": [ + { + "category": "impact", + "details": "Vulnerable code not in execute path.", + "product_ids": [ + "LIBDB-5328" + ] + } + ] + } + ] +} +EOF +``` + +### Scan SBOM with CSAF document +Provide the CSAF document when scanning the SBOM. + +```console +$ trivy sbom debian11.spdx.json --vex debian11.vex.csaf +... +2024-01-02T10:28:26.704+0100 INFO Filtered out the detected vulnerability {"VEX format": "CSAF", "vulnerability-id": "CVE-2019-8457", "status": "not_affected"} + +debian11.spdx.json (debian 11.6) +================================ +Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) +``` + +CVE-2019-8457 is no longer shown as it is filtered out according to the given CSAF document. + +[csaf]: https://oasis-open.github.io/csaf-documentation/specification.html diff --git a/go.mod b/go.mod index ba284038c23f..d85faa5eaf6c 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/cheggaaa/pb/v3 v3.1.4 github.com/containerd/containerd v1.7.11 + github.com/csaf-poc/csaf_distribution/v3 v3.0.0 github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/color v1.15.0 @@ -101,11 +102,11 @@ require ( github.com/twitchtv/twirp v8.1.2+incompatible github.com/xeipuuv/gojsonschema v1.2.0 github.com/xlab/treeprint v1.2.0 - go.etcd.io/bbolt v1.3.7 + go.etcd.io/bbolt v1.3.8 go.uber.org/zap v1.26.0 - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/mod v0.14.0 - golang.org/x/sync v0.4.0 + golang.org/x/sync v0.5.0 golang.org/x/term v0.15.0 golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 @@ -131,11 +132,13 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect + github.com/Intevation/gval v1.3.0 // indirect + github.com/Intevation/jsonpath v0.2.1 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -144,7 +147,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/VividCortex/ewma v1.2.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect @@ -208,7 +211,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.6 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/fifo v1.1.0 // indirect @@ -252,29 +255,34 @@ require ( github.com/go-openapi/spec v0.20.9 // indirect github.com/go-openapi/swag v0.22.4 // indirect github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-sql-driver/mysql v1.7.1 // indirect + github.com/go-test/deep v1.1.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-yaml v1.8.1 // indirect + github.com/goccy/go-yaml v1.9.5 // indirect github.com/gofrs/uuid v4.3.1+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/flatbuffers v2.0.8+incompatible // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20230406165453-00490a63f317 // indirect github.com/google/s2a-go v0.1.5 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gosuri/uitable v0.0.4 // indirect - github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect @@ -302,7 +310,7 @@ require ( github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -342,6 +350,7 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect @@ -375,7 +384,7 @@ require ( golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.15.0 // indirect google.golang.org/api v0.138.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect @@ -405,7 +414,7 @@ require ( modernc.org/memory v1.7.2 // indirect modernc.org/opt v0.1.3 // indirect modernc.org/strutil v1.1.3 // indirect - modernc.org/token v1.0.1 // indirect + modernc.org/token v1.1.0 // indirect oras.land/oras-go v1.2.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect diff --git a/go.sum b/go.sum index aeba5c1a5a92..ddba197f208d 100644 --- a/go.sum +++ b/go.sum @@ -216,8 +216,9 @@ github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/ github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc= github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= @@ -243,6 +244,10 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible h1:juIaKLLVhqzP55d8x4cSVgwyQv76Z55/fRv/UBr2KkQ= github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs= +github.com/Intevation/gval v1.3.0 h1:+Ze5sft5MmGbZrHj06NVUbcxCb67l9RaPTLMNr37mjw= +github.com/Intevation/gval v1.3.0/go.mod h1:xmGyGpP5be12EL0P12h+dqiYG8qn2j3PJxIgkoOHO5o= +github.com/Intevation/jsonpath v0.2.1 h1:rINNQJ0Pts5XTFEG+zamtdL7l9uuE1z0FBA+r55Sw+A= +github.com/Intevation/jsonpath v0.2.1/go.mod h1:WnZ8weMmwAx/fAO3SutjYFU+v7DFreNYnibV7CiaYIw= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -285,8 +290,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= @@ -567,8 +572,9 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= +github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -707,6 +713,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/csaf-poc/csaf_distribution/v3 v3.0.0 h1:ob9+Fmpff0YWgTP3dYaw7G2hKQ9cegh9l3zksc+q3sM= +github.com/csaf-poc/csaf_distribution/v3 v3.0.0/go.mod h1:uilCTiNKivq+6zrDvjtZaUeLk70oe21iwKivo6ILwlQ= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -798,6 +806,7 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -815,6 +824,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -894,21 +905,26 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= +github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -941,8 +957,9 @@ github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXs github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-yaml v1.8.1 h1:JuZRFlqLM5cWF6A+waL8AKVuCcqvKOuhJtUQI+L3ez0= github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y= +github.com/goccy/go-yaml v1.9.5 h1:Eh/+3uk9kLxG4koCX6lRMAPS1OaMSAi+FJcya0INdB0= +github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= @@ -1017,8 +1034,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1069,8 +1086,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230406165453-00490a63f317 h1:hFhpt7CTmR3DX+b4R19ydQFtofxT0Sv3QsKNMVQYTMQ= +github.com/google/pprof v0.0.0-20230406165453-00490a63f317/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg= github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -1119,8 +1136,9 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -1163,8 +1181,8 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= +github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.6 h1:3xi/Cafd1NaoEnS/yDssIiuVeDVywU0QdFGl3aQaQHM= github.com/hashicorp/golang-lru/v2 v2.0.6/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -1319,6 +1337,7 @@ github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70/go.m github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -1348,8 +1367,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 h1:TLygBUBxikNJJfLwgm+Qwdgq1FtfV8Uh7bcxRyTzK8s= github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032/go.mod h1:vYT9HE7WCvL64iVeZylKmCsWKfE+JZ8105iuh2Trk8g= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -1578,6 +1597,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/saracen/walker v0.1.3 h1:YtcKKmpRPy6XJTHJ75J2QYXXZYWnZNQxPCVqZSHVV/g= github.com/saracen/walker v0.1.3/go.mod h1:FU+7qU8DeQQgSZDmmThMJi93kPkLFgy0oVAcLxurjIk= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -1667,6 +1688,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -1760,8 +1782,8 @@ github.com/zclconf/go-cty-yaml v1.0.3/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JApr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= @@ -1852,8 +1874,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1934,7 +1956,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1997,8 +2018,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2223,11 +2244,10 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2487,7 +2507,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.30.0 h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss= gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -2605,8 +2624,8 @@ modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= -modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= -modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= oras.land/oras-go v1.2.4-0.20230801060855-932dd06d38af h1:FX1C64cT+tNHJpuaHqbu48DEUp8gqtu6eBXtoP7CPyM= diff --git a/pkg/vex/csaf.go b/pkg/vex/csaf.go new file mode 100644 index 000000000000..efed27b83f22 --- /dev/null +++ b/pkg/vex/csaf.go @@ -0,0 +1,78 @@ +package vex + +import ( + csaf "github.com/csaf-poc/csaf_distribution/v3/csaf" + "github.com/samber/lo" + "go.uber.org/zap" + "golang.org/x/exp/slices" + + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/types" +) + +type CSAF struct { + advisory csaf.Advisory + logger *zap.SugaredLogger +} + +func newCSAF(advisory csaf.Advisory) VEX { + return &CSAF{ + advisory: advisory, + logger: log.Logger.With(zap.String("VEX format", "CSAF")), + } +} + +func (v *CSAF) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { + return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { + found, ok := lo.Find(v.advisory.Vulnerabilities, func(item *csaf.Vulnerability) bool { + return string(*item.CVE) == vuln.VulnerabilityID + }) + if !ok { + return true + } + + return v.affected(found, vuln.PkgIdentifier.PURL) + }) +} + +func (v *CSAF) affected(vuln *csaf.Vulnerability, purl *ftypes.PackageURL) bool { + if purl == nil || vuln.ProductStatus == nil { + return true + } + + var status Status + switch { + case v.matchPURL(purl, vuln.ProductStatus.KnownNotAffected): + status = StatusNotAffected + case v.matchPURL(purl, vuln.ProductStatus.Fixed): + status = StatusFixed + } + + if status != "" { + v.logger.Infow("Filtered out the detected vulnerability", + zap.String("vulnerability-id", string(*vuln.CVE)), + zap.String("status", string(status))) + return false + } + + return true +} + +// matchPURL returns true if the given PackageURL is found in the ProductTree. +func (v *CSAF) matchPURL(purl *ftypes.PackageURL, products *csaf.Products) bool { + for _, product := range lo.FromPtr(products) { + helpers := v.advisory.ProductTree.CollectProductIdentificationHelpers(lo.FromPtr(product)) + purls := lo.FilterMap(helpers, func(helper *csaf.ProductIdentificationHelper, _ int) (string, bool) { + if helper == nil || helper.PURL == nil { + return "", false + } + return string(*helper.PURL), true + }) + if slices.Contains(purls, purl.String()) { + return true + } + } + + return false +} diff --git a/pkg/vex/cyclonedx.go b/pkg/vex/cyclonedx.go new file mode 100644 index 000000000000..dbe65b5820a8 --- /dev/null +++ b/pkg/vex/cyclonedx.go @@ -0,0 +1,94 @@ +package vex + +import ( + cdx "github.com/CycloneDX/cyclonedx-go" + "github.com/samber/lo" + "go.uber.org/zap" + + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/types" +) + +type CycloneDX struct { + sbom *ftypes.CycloneDX + statements []Statement + logger *zap.SugaredLogger +} + +type Statement struct { + VulnerabilityID string + Affects []string + Status Status + Justification string // TODO: define a type +} + +func newCycloneDX(cdxSBOM *ftypes.CycloneDX, vex *cdx.BOM) *CycloneDX { + var stmts []Statement + for _, vuln := range lo.FromPtr(vex.Vulnerabilities) { + affects := lo.Map(lo.FromPtr(vuln.Affects), func(item cdx.Affects, index int) string { + return item.Ref + }) + + analysis := lo.FromPtr(vuln.Analysis) + stmts = append(stmts, Statement{ + VulnerabilityID: vuln.ID, + Affects: affects, + Status: cdxStatus(analysis.State), + Justification: string(analysis.Justification), + }) + } + return &CycloneDX{ + sbom: cdxSBOM, + statements: stmts, + logger: log.Logger.With(zap.String("VEX format", "CycloneDX")), + } +} + +func (v *CycloneDX) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { + return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { + stmt, ok := lo.Find(v.statements, func(item Statement) bool { + return item.VulnerabilityID == vuln.VulnerabilityID + }) + if !ok { + return true + } + return v.affected(vuln, stmt) + }) +} + +func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) bool { + for _, affect := range stmt.Affects { + // Affect must be BOM-Link at the moment + link, err := cdx.ParseBOMLink(affect) + if err != nil { + v.logger.Warnw("Unable to parse BOM-Link", zap.String("affect", affect)) + continue + } + if v.sbom.SerialNumber != link.SerialNumber() || v.sbom.Version != link.Version() { + v.logger.Warnw("URN doesn't match with SBOM", zap.String("serial number", link.SerialNumber()), + zap.Int("version", link.Version())) + continue + } + if vuln.PkgIdentifier.Match(link.Reference()) && (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { + v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), + zap.String("status", string(stmt.Status)), zap.String("justification", stmt.Justification)) + return false + } + } + return true +} + +func cdxStatus(s cdx.ImpactAnalysisState) Status { + switch s { + case cdx.IASResolved, cdx.IASResolvedWithPedigree: + return StatusFixed + case cdx.IASExploitable: + return StatusAffected + case cdx.IASInTriage: + return StatusUnderInvestigation + case cdx.IASFalsePositive, cdx.IASNotAffected: + return StatusNotAffected + } + return StatusUnknown +} diff --git a/pkg/vex/openvex.go b/pkg/vex/openvex.go new file mode 100644 index 000000000000..796439291b95 --- /dev/null +++ b/pkg/vex/openvex.go @@ -0,0 +1,46 @@ +package vex + +import ( + openvex "github.com/openvex/go-vex/pkg/vex" + "github.com/samber/lo" + "go.uber.org/zap" + + "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/types" +) + +type OpenVEX struct { + vex openvex.VEX + logger *zap.SugaredLogger +} + +func newOpenVEX(vex openvex.VEX) VEX { + return &OpenVEX{ + vex: vex, + logger: log.Logger.With(zap.String("VEX format", "OpenVEX")), + } +} + +func (v *OpenVEX) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { + return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { + var stmts []openvex.Statement + if vuln.PkgIdentifier.PURL != nil { + matchedStmts := v.vex.Matches(vuln.VulnerabilityID, vuln.PkgIdentifier.PURL.String(), nil) + stmts = append(stmts, matchedStmts...) + } + if len(stmts) == 0 { + return true + } + + // Take the latest statement for a given vulnerability and product + // as a sequence of statements can be overridden by the newer one. + // cf. https://github.com/openvex/spec/blob/fa5ba0c0afedb008dc5ebad418548cacf16a3ca7/OPENVEX-SPEC.md#the-vex-statement + stmt := stmts[len(stmts)-1] + if stmt.Status == openvex.StatusNotAffected || stmt.Status == openvex.StatusFixed { + v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), + zap.String("status", string(stmt.Status)), zap.String("justification", string(stmt.Justification))) + return false + } + return true + }) +} diff --git a/pkg/vex/testdata/csaf-affected.json b/pkg/vex/testdata/csaf-affected.json new file mode 100644 index 000000000000..56e9bb4d8a53 --- /dev/null +++ b/pkg/vex/testdata/csaf-affected.json @@ -0,0 +1,93 @@ +{ + "document": { + "category": "csaf_vex", + "csaf_version": "2.0", + "notes": [ + { + "category": "summary", + "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", + "title": "Author comment" + } + ], + "publisher": { + "category": "vendor", + "name": "Example Company ProductCERT", + "namespace": "https://psirt.example.com" + }, + "title": "Example VEX Document Use Case 1 - Affected", + "tracking": { + "current_release_date": "2022-03-03T11:00:00.000Z", + "generator": { + "date": "2022-03-03T11:00:00.000Z", + "engine": { + "name": "Secvisogram", + "version": "1.11.0" + } + }, + "id": "2022-EVD-UC-01-A-001", + "initial_release_date": "2022-03-03T11:00:00.000Z", + "revision_history": [ + { + "date": "2022-03-03T11:00:00.000Z", + "number": "1", + "summary": "Initial version." + } + ], + "status": "final", + "version": "1" + } + }, + "product_tree": { + "branches": [ + { + "branches": [ + { + "branches": [ + { + "category": "product_version", + "name": "1.0", + "product": { + "name": "Example Company DEF 1.0", + "product_id": "CSAFPID-0001", + "product_identification_helper": { + "purl": "pkg:maven/org.example.company/def@1.0" + } + } + } + ], + "category": "product_name", + "name": "DEF" + } + ], + "category": "vendor", + "name": "Example Company" + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2021-44228", + "notes": [ + { + "category": "description", + "text": "Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.", + "title": "CVE description" + } + ], + "product_status": { + "known_affected": [ + "CSAFPID-0001" + ] + }, + "remediations": [ + { + "category": "vendor_fix", + "details": "Customers should update to version 1.1 of product DEF which fixes the issue.", + "product_ids": [ + "CSAFPID-0001" + ] + } + ] + } + ] +} diff --git a/pkg/vex/testdata/csaf-not-affected.json b/pkg/vex/testdata/csaf-not-affected.json new file mode 100644 index 000000000000..dce0b4a712d6 --- /dev/null +++ b/pkg/vex/testdata/csaf-not-affected.json @@ -0,0 +1,93 @@ +{ + "document": { + "category": "csaf_vex", + "csaf_version": "2.0", + "notes": [ + { + "category": "summary", + "text": "Example Company VEX document. Unofficial content for demonstration purposes only.", + "title": "Author comment" + } + ], + "publisher": { + "category": "vendor", + "name": "Example Company ProductCERT", + "namespace": "https://psirt.example.com" + }, + "title": "AquaSecurity example VEX document", + "tracking": { + "current_release_date": "2022-03-03T11:00:00.000Z", + "generator": { + "date": "2022-03-03T11:00:00.000Z", + "engine": { + "name": "Secvisogram", + "version": "1.11.0" + } + }, + "id": "2022-EVD-UC-01-A-001", + "initial_release_date": "2022-03-03T11:00:00.000Z", + "revision_history": [ + { + "date": "2022-03-03T11:00:00.000Z", + "number": "1", + "summary": "Initial version." + } + ], + "status": "final", + "version": "1" + } + }, + "product_tree": { + "branches": [ + { + "branches": [ + { + "branches": [ + { + "category": "product_version", + "name": "2.6.0", + "product": { + "name": "Spring Boot 2.6.0", + "product_id": "SPB-00260", + "product_identification_helper": { + "purl": "pkg:maven/org.springframework.boot/spring-boot@2.6.0" + } + } + } + ], + "category": "product_name", + "name": "Spring Boot" + } + ], + "category": "vendor", + "name": "Spring" + } + ] + }, + "vulnerabilities": [ + { + "cve": "CVE-2021-44228", + "notes": [ + { + "category": "description", + "text": "Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.", + "title": "CVE description" + } + ], + "product_status": { + "known_not_affected": [ + "SPB-00260" + ] + }, + "threats": [ + { + "category": "impact", + "details": "Class with vulnerable code was removed before shipping.", + "product_ids": [ + "SPB-00260" + ] + } + ] + } + ] +} diff --git a/pkg/vex/testdata/unknown.json b/pkg/vex/testdata/unknown.json index e0415f90563c..9e26dfeeb6e6 100644 --- a/pkg/vex/testdata/unknown.json +++ b/pkg/vex/testdata/unknown.json @@ -1 +1 @@ -{unknown} \ No newline at end of file +{} \ No newline at end of file diff --git a/pkg/vex/vex.go b/pkg/vex/vex.go index 1042e0886515..644b00d62b3a 100644 --- a/pkg/vex/vex.go +++ b/pkg/vex/vex.go @@ -5,16 +5,12 @@ import ( "io" "os" - cdx "github.com/CycloneDX/cyclonedx-go" + csaf "github.com/csaf-poc/csaf_distribution/v3/csaf" "github.com/hashicorp/go-multierror" openvex "github.com/openvex/go-vex/pkg/vex" - "github.com/samber/lo" "github.com/sirupsen/logrus" - "go.uber.org/zap" "golang.org/x/xerrors" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" - "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/sbom" "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx" "github.com/aquasecurity/trivy/pkg/types" @@ -27,130 +23,6 @@ type VEX interface { Filter([]types.DetectedVulnerability) []types.DetectedVulnerability } -type Statement struct { - VulnerabilityID string - Affects []string - Status Status - Justification string // TODO: define a type -} - -type OpenVEX struct { - vex openvex.VEX - logger *zap.SugaredLogger -} - -func newOpenVEX(vex openvex.VEX) VEX { - logger := log.Logger.With(zap.String("VEX format", "OpenVEX")) - - return &OpenVEX{ - vex: vex, - logger: logger, - } -} - -func (v *OpenVEX) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { - return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { - var stmts []openvex.Statement - if vuln.PkgIdentifier.PURL != nil { - matchedStmts := v.vex.Matches(vuln.VulnerabilityID, vuln.PkgIdentifier.PURL.String(), nil) - if len(matchedStmts) > 0 { - stmts = append(stmts, matchedStmts...) - } - } - if len(stmts) == 0 { - return true - } - - // Take the latest statement for a given vulnerability and product - // as a sequence of statements can be overridden by the newer one. - // cf. https://github.com/openvex/spec/blob/fa5ba0c0afedb008dc5ebad418548cacf16a3ca7/OPENVEX-SPEC.md#the-vex-statement - stmt := stmts[len(stmts)-1] - if stmt.Status == openvex.StatusNotAffected || stmt.Status == openvex.StatusFixed { - v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), - zap.String("status", string(stmt.Status)), zap.String("justification", string(stmt.Justification))) - return false - } - return true - }) -} - -type CycloneDX struct { - sbom *ftypes.CycloneDX - statements []Statement - logger *zap.SugaredLogger -} - -func newCycloneDX(cdxSBOM *ftypes.CycloneDX, vex *cdx.BOM) *CycloneDX { - var stmts []Statement - for _, vuln := range lo.FromPtr(vex.Vulnerabilities) { - affects := lo.Map(lo.FromPtr(vuln.Affects), func(item cdx.Affects, index int) string { - return item.Ref - }) - - analysis := lo.FromPtr(vuln.Analysis) - - stmts = append(stmts, Statement{ - VulnerabilityID: vuln.ID, - Affects: affects, - Status: cdxStatus(analysis.State), - Justification: string(analysis.Justification), - }) - } - return &CycloneDX{ - sbom: cdxSBOM, - statements: stmts, - logger: log.Logger.With(zap.String("VEX format", "CycloneDX")), - } -} - -func (v *CycloneDX) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulnerability { - return lo.Filter(vulns, func(vuln types.DetectedVulnerability, _ int) bool { - stmt, ok := lo.Find(v.statements, func(item Statement) bool { - return item.VulnerabilityID == vuln.VulnerabilityID - }) - if !ok { - return true - } - return v.affected(vuln, stmt) - }) -} - -func (v *CycloneDX) affected(vuln types.DetectedVulnerability, stmt Statement) bool { - for _, affect := range stmt.Affects { - // Affect must be BOM-Link at the moment - link, err := cdx.ParseBOMLink(affect) - if err != nil { - v.logger.Warnw("Unable to parse BOM-Link", zap.String("affect", affect)) - continue - } - if v.sbom.SerialNumber != link.SerialNumber() || v.sbom.Version != link.Version() { - v.logger.Warnw("URN doesn't match with SBOM", zap.String("serial number", link.SerialNumber()), - zap.Int("version", link.Version())) - continue - } - if vuln.PkgIdentifier.Match(link.Reference()) && (stmt.Status == StatusNotAffected || stmt.Status == StatusFixed) { - v.logger.Infow("Filtered out the detected vulnerability", zap.String("vulnerability-id", vuln.VulnerabilityID), - zap.String("status", string(stmt.Status)), zap.String("justification", stmt.Justification)) - return false - } - } - return true -} - -func cdxStatus(s cdx.ImpactAnalysisState) Status { - switch s { - case cdx.IASResolved, cdx.IASResolvedWithPedigree: - return StatusFixed - case cdx.IASExploitable: - return StatusAffected - case cdx.IASInTriage: - return StatusUnderInvestigation - case cdx.IASFalsePositive, cdx.IASNotAffected: - return StatusNotAffected - } - return StatusUnknown -} - func New(filePath string, report types.Report) (VEX, error) { if filePath == "" { return nil, nil @@ -162,7 +34,6 @@ func New(filePath string, report types.Report) (VEX, error) { defer f.Close() var errs error - // Try CycloneDX JSON if ok, err := sbom.IsCycloneDXJSON(f); err != nil { errs = multierror.Append(errs, err) @@ -173,7 +44,14 @@ func New(filePath string, report types.Report) (VEX, error) { // Try OpenVEX if v, err := decodeOpenVEX(f); err != nil { errs = multierror.Append(errs, err) - } else { + } else if v != nil { + return v, nil + } + + // Try CSAF + if v, err := decodeCSAF(f); err != nil { + errs = multierror.Append(errs, err) + } else if v != nil { return v, nil } @@ -210,3 +88,17 @@ func decodeOpenVEX(r io.ReadSeeker) (VEX, error) { } return newOpenVEX(openVEX), nil } + +func decodeCSAF(r io.ReadSeeker) (VEX, error) { + if _, err := r.Seek(0, io.SeekStart); err != nil { + return nil, xerrors.Errorf("seek error: %w", err) + } + var adv csaf.Advisory + if err := json.NewDecoder(r).Decode(&adv); err != nil { + return nil, err + } + if adv.Vulnerabilities == nil { + return nil, nil + } + return newCSAF(adv), nil +} diff --git a/pkg/vex/vex_test.go b/pkg/vex/vex_test.go index 16abcf2a7ffa..1feb37a7c41d 100644 --- a/pkg/vex/vex_test.go +++ b/pkg/vex/vex_test.go @@ -1,10 +1,11 @@ package vex_test import ( - "github.com/package-url/packageurl-go" "os" "testing" + "github.com/package-url/packageurl-go" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -28,10 +29,11 @@ func TestVEX_Filter(t *testing.T) { vulns []types.DetectedVulnerability } tests := []struct { - name string - fields fields - args args - want []types.DetectedVulnerability + name string + fields fields + args args + want []types.DetectedVulnerability + wantErr string }{ { name: "OpenVEX", @@ -227,11 +229,91 @@ func TestVEX_Filter(t *testing.T) { }, }, }, + { + name: "CSAF (not affected vuln)", + fields: fields{ + filePath: "testdata/csaf-not-affected.json", + }, + args: args{ + vulns: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2021-44228", + PkgName: "spring-boot", + InstalledVersion: "2.6.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", + }, + }, + }, + }, + }, + }, + want: []types.DetectedVulnerability{}, + }, + { + name: "CSAF (affected vuln)", + fields: fields{ + filePath: "testdata/csaf-affected.json", + }, + args: args{ + vulns: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2021-44228", + PkgName: "def", + InstalledVersion: "1.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.example.company", + Name: "def", + Version: "1.0", + }, + }, + }, + }, + }, + }, + want: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2021-44228", + PkgName: "def", + InstalledVersion: "1.0", + PkgIdentifier: ftypes.PkgIdentifier{ + PURL: &ftypes.PackageURL{ + PackageURL: packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.example.company", + Name: "def", + Version: "1.0", + }, + }, + }, + }, + }, + }, + { + name: "unknown format", + fields: fields{ + filePath: "testdata/unknown.json", + }, + args: args{}, + wantErr: "unable to load VEX", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { v, err := vex.New(tt.fields.filePath, tt.fields.report) + if tt.wantErr != "" { + require.ErrorContains(t, err, tt.wantErr) + return + } require.NoError(t, err) assert.Equal(t, tt.want, v.Filter(tt.args.vulns)) }) From 0ebb6c46820f682f5c153f0b697b4e6785078edf Mon Sep 17 00:00:00 2001 From: yusuke-koyoshi <92022336+yusuke-koyoshi@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:06:37 +0900 Subject: [PATCH 072/108] fix(vm): update ext4-filesystem fix reading groupdescriptor in 32bit mode (#5888) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d85faa5eaf6c..4f6aa25a6b9b 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/mailru/easyjson v0.7.7 github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43 - github.com/masahiro331/go-ext4-filesystem v0.0.0-20230612143131-27ccd485b7a1 + github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4 github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70 diff --git a/go.sum b/go.sum index ddba197f208d..1ced79aa0f49 100644 --- a/go.sum +++ b/go.sum @@ -1326,8 +1326,8 @@ github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac h1:QyRucnGOLHJ github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac/go.mod h1:J7Vb0sf0JzOhT0uHTeCqO6dqP/ELVcQvQ6yQ/56ZRGw= github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43 h1:umYrurEClKuDjU29DKNNPmnWJNt4mnR0fWLOpWsDg0M= github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43/go.mod h1:5NOkqebMwu8UiOTSjwqam1Ykdr7fci52TVE2xDQnIiM= -github.com/masahiro331/go-ext4-filesystem v0.0.0-20230612143131-27ccd485b7a1 h1:jQ0px48V+wp35FSimlg9e/bB8XSrBz0SxPLbnYCq6/4= -github.com/masahiro331/go-ext4-filesystem v0.0.0-20230612143131-27ccd485b7a1/go.mod h1:3XMMY1M486mWGTD13WPItg6FsgflQR72ZMAkd+gsyoQ= +github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4 h1:uHO44vOunB0oEtk+r8ifBbFOD0mr6+fmoyFNCgLE66k= +github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4/go.mod h1:3XMMY1M486mWGTD13WPItg6FsgflQR72ZMAkd+gsyoQ= github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 h1:AevUBW4cc99rAF8q8vmddIP8qd/0J5s/UyltGbp66dg= github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08/go.mod h1:JOkBRrE1HvgTyjk6diFtNGgr8XJMtIfiBzkL5krqzVk= github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd h1:Y30EzvuoVp97b0unb/GOFXzBUKRXZXUN2e0wYmvC+ic= From 47b6c2817a1791b6892868b6dedaf9b99a7a8e9a Mon Sep 17 00:00:00 2001 From: Fatih Tokus Date: Mon, 8 Jan 2024 10:33:20 +0000 Subject: [PATCH 073/108] docs: add_scan2html_to_trivy_ecosystem (#5875) --- docs/ecosystem/{security.md => miscellaneous.md} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename docs/ecosystem/{security.md => miscellaneous.md} (72%) diff --git a/docs/ecosystem/security.md b/docs/ecosystem/miscellaneous.md similarity index 72% rename from docs/ecosystem/security.md rename to docs/ecosystem/miscellaneous.md index e5f99ac63c67..ba37e65160e5 100644 --- a/docs/ecosystem/security.md +++ b/docs/ecosystem/miscellaneous.md @@ -1,4 +1,4 @@ -# Security Management +# Miscellaneous ## SonarQube (Community) A Trivy plugin that converts JSON report to SonarQube [generic issues format](https://docs.sonarqube.org/9.6/analyzing-source-code/importing-external-issues/generic-issue-import-format/). @@ -9,3 +9,8 @@ A Trivy plugin that converts JSON report to SonarQube [generic issues format](ht DefectDojo can parse Trivy JSON reports. The parser supports deduplication and auto-close features. 👉 Get it at: + +## Scan2html (Community) +A Trivy plugin that scans and outputs the results to an interactive html file. + +👉 Get it at: From a626cdf334d7ba38e838925746619261700721bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:33:06 +0400 Subject: [PATCH 074/108] chore(deps): bump github.com/cloudflare/circl from 1.3.6 to 1.3.7 (#5892) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4f6aa25a6b9b..cb5fd7b3fccf 100644 --- a/go.mod +++ b/go.mod @@ -211,7 +211,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/cloudflare/circl v1.3.6 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/fifo v1.1.0 // indirect diff --git a/go.sum b/go.sum index 1ced79aa0f49..e87fee70e846 100644 --- a/go.sum +++ b/go.sum @@ -573,8 +573,8 @@ github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= -github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= From 92d9b3dbba239b7a0d7b9e8b02d67726f7cadf22 Mon Sep 17 00:00:00 2001 From: Itay Shakury Date: Tue, 9 Jan 2024 07:52:03 +0200 Subject: [PATCH 075/108] docs: improve filter by rego (#5402) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/configuration/filtering.md | 111 +++++++++++++-------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/docs/docs/configuration/filtering.md b/docs/docs/configuration/filtering.md index a3d08daa897d..2ca0c2d1adf3 100644 --- a/docs/docs/configuration/filtering.md +++ b/docs/docs/configuration/filtering.md @@ -408,7 +408,7 @@ Total: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2) -## By Open Policy Agent +## By Rego | Scanner | Supported | |:----------------:|:---------:| @@ -420,75 +420,68 @@ Total: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2) !!! warning "EXPERIMENTAL" This feature might change without preserving backwards compatibility. -Trivy supports Open Policy Agent (OPA) to filter vulnerabilities. -You can specify a Rego file with `--ignore-policy` option. +[Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) is a policy language that allows you to express decision logic in a concise syntax. +Rego is part of the popular [Open Policy Agent (OPA)](https://www.openpolicyagent.org) CNCF project. +For advanced filtering, Trivy allows you to use Rego language to filter vulnerabilities. -The Rego package name must be `trivy` and it must include a rule called `ignore` which determines if each individual vulnerability should be excluded (ignore=true) or not (ignore=false). In the policy, each vulnerability will be available for inspection as the `input` variable. The structure of each vulnerability input is the same as for the Trivy JSON output. -There is a built-in Rego library with helper functions that you can import into your policy using: `import data.lib.trivy`. For more info about the helper functions, look at the library [here][helper] +Use the `--ignore-policy` flag which takes a path to a Rego file that defines the filtering policy. +The Rego package name must be `trivy` and it must include a "rule" named `ignore` which determines if each individual scan result should be excluded (ignore=true) or not (ignore=false). +The `input` for the evaluation is each [DetectedVulnerability](https://github.com/aquasecurity/trivy/blob/00f2059e5d7bc2ca2e3e8b1562bdfede1ed570e3/pkg/types/vulnerability.go#L9) and [DetectedMisconfiguration](https://github.com/aquasecurity/trivy/blob/00f2059e5d7bc2ca2e3e8b1562bdfede1ed570e3/pkg/types/misconfiguration.go#L6). -To get started, see the [example policy][policy]. +A practical way to observe the filtering policy input in your case, is to run a scan with the `--format json` option and look at the resulting structure: ```bash -$ trivy image --ignore-policy contrib/example_policy/basic.rego centos:7 +trivy image -f json centos:7 + +... + "Results": [ + { + "Target": "centos:7 (centos 7.9.2009)", + "Class": "os-pkgs", + "Type": "centos", + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2015-5186", + "PkgID": "audit-libs@2.8.5-4.el7.x86_64", + "PkgName": "audit-libs", + "InstalledVersion": "2.8.5-4.el7", + "Layer": { + "Digest": "sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc", + "DiffID": "sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02" + }, + "SeveritySource": "redhat", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2015-5186", + "Title": "log terminal emulator escape sequences handling", + "Description": "Audit before 2.4.4 in Linux does not sanitize escape characters in filenames.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-20" + ], +... ``` -
-Result +Each individual vulnerability (under `Results.Vulnerabilities`) or Misconfiguration (under `Results.Misconfigurations`) is evaluated for exclusion or inclusion by the `ignore` rule. + +The following is a Rego ignore policy that filters out every vulnerability with a specific CWE ID (as seen in the JSON example above): + +```rego +package trivy + +default ignore = false + +ignore { + input.CweIDs[_] == "CWE-20" +} +``` ```bash -centos:7 (centos 7.9.2009) -========================== -Total: 9 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 4, CRITICAL: 5) - -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ -| glib2 | CVE-2015-8385 | HIGH | 2.56.1-7.el7 | | pcre: buffer overflow caused | -| | | | | | by named forward reference | -| | | | | | to duplicate group number... | -| | | | | | -->avd.aquasec.com/nvd/cve-2015-8385 | -+ +------------------+ + +-------------------+-----------------------------------------+ -| | CVE-2016-3191 | | | | pcre: workspace overflow for | -| | | | | | (*ACCEPT) with deeply nested | -| | | | | | parentheses (8.39/13, 10.22/12) | -| | | | | | -->avd.aquasec.com/nvd/cve-2016-3191 | -+ +------------------+ + +-------------------+-----------------------------------------+ -| | CVE-2021-27219 | | | 2.56.1-9.el7_9 | glib: integer overflow in | -| | | | | | g_bytes_new function on | -| | | | | | 64-bit platforms due to an... | -| | | | | | -->avd.aquasec.com/nvd/cve-2021-27219 | -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ -| glibc | CVE-2019-1010022 | CRITICAL | 2.17-317.el7 | | glibc: stack guard protection bypass | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-1010022 | -+--------------+ + + +-------------------+ + -| glibc-common | | | | | | -| | | | | | | -+--------------+------------------+ +-------------------+-------------------+-----------------------------------------+ -| nss | CVE-2021-43527 | | 3.53.1-3.el7_9 | 3.67.0-4.el7_9 | nss: Memory corruption in | -| | | | | | decodeECorDsaSignature with | -| | | | | | DSA signatures (and RSA-PSS) | -| | | | | | -->avd.aquasec.com/nvd/cve-2021-43527 | -+--------------+ + + + + + -| nss-sysinit | | | | | | -| | | | | | | -| | | | | | | -| | | | | | | -+--------------+ + + + + + -| nss-tools | | | | | | -| | | | | | | -| | | | | | | -| | | | | | | -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ -| openssl-libs | CVE-2020-1971 | HIGH | 1:1.0.2k-19.el7 | 1:1.0.2k-21.el7_9 | openssl: EDIPARTYNAME | -| | | | | | NULL pointer de-reference | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-1971 | -+--------------+------------------+----------+-------------------+-------------------+-----------------------------------------+ +trivy image --ignore-policy contrib/example_policy/basic.rego centos:7 ``` -
+For more advanced use cases, there is a built-in Rego library with helper functions that you can import into your policy using: `import data.lib.trivy`. +More info about the helper functions are in the library [here](https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/pkg/result/module.go). -[helper]: https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/pkg/result/module.go -[policy]: https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/contrib/example_policy +You can find more example policies [here](https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/pkg/result/module.go) ## By Inline Comments From 56c4e248aa3fe95097ce495bac459208a4cf8baa Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:50:35 +0600 Subject: [PATCH 076/108] revert(report): don't escape new line characters for sarif format (#5897) --- integration/testdata/alpine-310.sarif.golden | 16 +++++------ pkg/report/sarif.go | 24 ++++++++-------- pkg/report/sarif_test.go | 30 ++++++++++---------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/integration/testdata/alpine-310.sarif.golden b/integration/testdata/alpine-310.sarif.golden index cf7b55af852a..535bd2d09f71 100644 --- a/integration/testdata/alpine-310.sarif.golden +++ b/integration/testdata/alpine-310.sarif.golden @@ -23,8 +23,8 @@ }, "helpUri": "https://avd.aquasec.com/nvd/cve-2019-1549", "help": { - "text": "Vulnerability CVE-2019-1549\\nSeverity: MEDIUM\\nPackage: libssl1.1\\nFixed Version: 1.1.1d-r0\\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)\\nOpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).", - "markdown": "**Vulnerability CVE-2019-1549**\\n| Severity | Package | Fixed Version | Link |\\n| --- | --- | --- | --- |\\n|MEDIUM|libssl1.1|1.1.1d-r0|[CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)|\\n\\nOpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c)." + "text": "Vulnerability CVE-2019-1549\nSeverity: MEDIUM\nPackage: libssl1.1\nFixed Version: 1.1.1d-r0\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)\nOpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).", + "markdown": "**Vulnerability CVE-2019-1549**\n| Severity | Package | Fixed Version | Link |\n| --- | --- | --- | --- |\n|MEDIUM|libssl1.1|1.1.1d-r0|[CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)|\n\nOpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c)." }, "properties": { "precision": "very-high", @@ -50,8 +50,8 @@ }, "helpUri": "https://avd.aquasec.com/nvd/cve-2019-1551", "help": { - "text": "Vulnerability CVE-2019-1551\\nSeverity: MEDIUM\\nPackage: libssl1.1\\nFixed Version: 1.1.1d-r2\\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)\\nThere is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t).", - "markdown": "**Vulnerability CVE-2019-1551**\\n| Severity | Package | Fixed Version | Link |\\n| --- | --- | --- | --- |\\n|MEDIUM|libssl1.1|1.1.1d-r2|[CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)|\\n\\nThere is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t)." + "text": "Vulnerability CVE-2019-1551\nSeverity: MEDIUM\nPackage: libssl1.1\nFixed Version: 1.1.1d-r2\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)\nThere is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t).", + "markdown": "**Vulnerability CVE-2019-1551**\n| Severity | Package | Fixed Version | Link |\n| --- | --- | --- | --- |\n|MEDIUM|libssl1.1|1.1.1d-r2|[CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)|\n\nThere is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t)." }, "properties": { "precision": "very-high", @@ -73,7 +73,7 @@ "ruleIndex": 0, "level": "warning", "message": { - "text": "Package: libcrypto1.1\\nInstalled Version: 1.1.1c-r0\\nVulnerability CVE-2019-1549\\nSeverity: MEDIUM\\nFixed Version: 1.1.1d-r0\\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)" + "text": "Package: libcrypto1.1\nInstalled Version: 1.1.1c-r0\nVulnerability CVE-2019-1549\nSeverity: MEDIUM\nFixed Version: 1.1.1d-r0\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)" }, "locations": [ { @@ -100,7 +100,7 @@ "ruleIndex": 1, "level": "warning", "message": { - "text": "Package: libcrypto1.1\\nInstalled Version: 1.1.1c-r0\\nVulnerability CVE-2019-1551\\nSeverity: MEDIUM\\nFixed Version: 1.1.1d-r2\\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)" + "text": "Package: libcrypto1.1\nInstalled Version: 1.1.1c-r0\nVulnerability CVE-2019-1551\nSeverity: MEDIUM\nFixed Version: 1.1.1d-r2\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)" }, "locations": [ { @@ -127,7 +127,7 @@ "ruleIndex": 0, "level": "warning", "message": { - "text": "Package: libssl1.1\\nInstalled Version: 1.1.1c-r0\\nVulnerability CVE-2019-1549\\nSeverity: MEDIUM\\nFixed Version: 1.1.1d-r0\\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)" + "text": "Package: libssl1.1\nInstalled Version: 1.1.1c-r0\nVulnerability CVE-2019-1549\nSeverity: MEDIUM\nFixed Version: 1.1.1d-r0\nLink: [CVE-2019-1549](https://avd.aquasec.com/nvd/cve-2019-1549)" }, "locations": [ { @@ -154,7 +154,7 @@ "ruleIndex": 1, "level": "warning", "message": { - "text": "Package: libssl1.1\\nInstalled Version: 1.1.1c-r0\\nVulnerability CVE-2019-1551\\nSeverity: MEDIUM\\nFixed Version: 1.1.1d-r2\\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)" + "text": "Package: libssl1.1\nInstalled Version: 1.1.1c-r0\nVulnerability CVE-2019-1551\nSeverity: MEDIUM\nFixed Version: 1.1.1d-r2\nLink: [CVE-2019-1551](https://avd.aquasec.com/nvd/cve-2019-1551)" }, "locations": [ { diff --git a/pkg/report/sarif.go b/pkg/report/sarif.go index 800737a84258..25f1ba47bee5 100644 --- a/pkg/report/sarif.go +++ b/pkg/report/sarif.go @@ -169,11 +169,11 @@ func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { resultIndex: getRuleIndex(vuln.VulnerabilityID, ruleIndexes), shortDescription: html.EscapeString(vuln.Title), fullDescription: html.EscapeString(fullDescription), - helpText: fmt.Sprintf(`Vulnerability %v\nSeverity: %v\nPackage: %v\nFixed Version: %v\nLink: [%v](%v)\n%v`, + helpText: fmt.Sprintf("Vulnerability %v\nSeverity: %v\nPackage: %v\nFixed Version: %v\nLink: [%v](%v)\n%v", vuln.VulnerabilityID, vuln.Severity, vuln.PkgName, vuln.FixedVersion, vuln.VulnerabilityID, vuln.PrimaryURL, vuln.Description), - helpMarkdown: fmt.Sprintf(`**Vulnerability %v**\n| Severity | Package | Fixed Version | Link |\n| --- | --- | --- | --- |\n|%v|%v|%v|[%v](%v)|\n\n%v`, + helpMarkdown: fmt.Sprintf("**Vulnerability %v**\n| Severity | Package | Fixed Version | Link |\n| --- | --- | --- | --- |\n|%v|%v|%v|[%v](%v)|\n\n%v", vuln.VulnerabilityID, vuln.Severity, vuln.PkgName, vuln.FixedVersion, vuln.VulnerabilityID, vuln.PrimaryURL, vuln.Description), - message: fmt.Sprintf(`Package: %v\nInstalled Version: %v\nVulnerability %v\nSeverity: %v\nFixed Version: %v\nLink: [%v](%v)`, + message: fmt.Sprintf("Package: %v\nInstalled Version: %v\nVulnerability %v\nSeverity: %v\nFixed Version: %v\nLink: [%v](%v)", vuln.PkgName, vuln.InstalledVersion, vuln.VulnerabilityID, vuln.Severity, vuln.FixedVersion, vuln.VulnerabilityID, vuln.PrimaryURL), }) } @@ -196,11 +196,11 @@ func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { resultIndex: getRuleIndex(misconf.ID, ruleIndexes), shortDescription: html.EscapeString(misconf.Title), fullDescription: html.EscapeString(misconf.Description), - helpText: fmt.Sprintf(`Misconfiguration %v\nType: %s\nSeverity: %v\nCheck: %v\nMessage: %v\nLink: [%v](%v)\n%s`, + helpText: fmt.Sprintf("Misconfiguration %v\nType: %s\nSeverity: %v\nCheck: %v\nMessage: %v\nLink: [%v](%v)\n%s", misconf.ID, misconf.Type, misconf.Severity, misconf.Title, misconf.Message, misconf.ID, misconf.PrimaryURL, misconf.Description), - helpMarkdown: fmt.Sprintf(`**Misconfiguration %v**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|%v|%v|%v|%s|[%v](%v)|\n\n%v`, + helpMarkdown: fmt.Sprintf("**Misconfiguration %v**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|%v|%v|%v|%s|[%v](%v)|\n\n%v", misconf.ID, misconf.Type, misconf.Severity, misconf.Title, misconf.Message, misconf.ID, misconf.PrimaryURL, misconf.Description), - message: fmt.Sprintf(`Artifact: %v\nType: %v\nVulnerability %v\nSeverity: %v\nMessage: %v\nLink: [%v](%v)`, + message: fmt.Sprintf("Artifact: %v\nType: %v\nVulnerability %v\nSeverity: %v\nMessage: %v\nLink: [%v](%v)", res.Target, res.Type, misconf.ID, misconf.Severity, misconf.Message, misconf.ID, misconf.PrimaryURL), }) } @@ -223,11 +223,11 @@ func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { resultIndex: getRuleIndex(secret.RuleID, ruleIndexes), shortDescription: html.EscapeString(secret.Title), fullDescription: html.EscapeString(secret.Match), - helpText: fmt.Sprintf(`Secret %v\nSeverity: %v\nMatch: %s`, + helpText: fmt.Sprintf("Secret %v\nSeverity: %v\nMatch: %s", secret.Title, secret.Severity, secret.Match), - helpMarkdown: fmt.Sprintf(`**Secret %v**\n| Severity | Match |\n| --- | --- |\n|%v|%v|`, + helpMarkdown: fmt.Sprintf("**Secret %v**\n| Severity | Match |\n| --- | --- |\n|%v|%v|", secret.Title, secret.Severity, secret.Match), - message: fmt.Sprintf(`Artifact: %v\nType: %v\nSecret %v\nSeverity: %v\nMatch: %v`, + message: fmt.Sprintf("Artifact: %v\nType: %v\nSecret %v\nSeverity: %v\nMatch: %v", res.Target, res.Type, secret.Title, secret.Severity, secret.Match), }) } @@ -245,11 +245,11 @@ func (sw *SarifWriter) Write(ctx context.Context, report types.Report) error { resultIndex: getRuleIndex(id, ruleIndexes), shortDescription: desc, fullDescription: desc, - helpText: fmt.Sprintf(`License %s\nClassification: %s\nPkgName: %s\nPath: %s`, + helpText: fmt.Sprintf("License %s\nClassification: %s\nPkgName: %s\nPath: %s", license.Name, license.Category, license.PkgName, license.FilePath), - helpMarkdown: fmt.Sprintf(`**License %s**\n| PkgName | Classification | Path |\n| --- | --- | --- |\n|%s|%s|%s|`, + helpMarkdown: fmt.Sprintf("**License %s**\n| PkgName | Classification | Path |\n| --- | --- | --- |\n|%s|%s|%s|", license.Name, license.PkgName, license.Category, license.FilePath), - message: fmt.Sprintf(`Artifact: %s\nLicense %s\nPkgName: %s\n Classification: %s\n Path: %s`, + message: fmt.Sprintf("Artifact: %s\nLicense %s\nPkgName: %s\n Classification: %s\n Path: %s", res.Target, license.Name, license.Category, license.PkgName, license.FilePath), }) } diff --git a/pkg/report/sarif_test.go b/pkg/report/sarif_test.go index 737662dcd536..d5f88d443373 100644 --- a/pkg/report/sarif_test.go +++ b/pkg/report/sarif_test.go @@ -118,8 +118,8 @@ func TestReportWriter_Sarif(t *testing.T) { "security-severity": "7.5", }, Help: &sarif.MultiformatMessageString{ - Text: lo.ToPtr("Vulnerability CVE-2020-0001\\nSeverity: HIGH\\nPackage: foo\\nFixed Version: 3.4.5\\nLink: [CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)\\nbaz"), - Markdown: lo.ToPtr("**Vulnerability CVE-2020-0001**\\n| Severity | Package | Fixed Version | Link |\\n| --- | --- | --- | --- |\\n|HIGH|foo|3.4.5|[CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)|\\n\\nbaz"), + Text: lo.ToPtr("Vulnerability CVE-2020-0001\nSeverity: HIGH\nPackage: foo\nFixed Version: 3.4.5\nLink: [CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)\nbaz"), + Markdown: lo.ToPtr("**Vulnerability CVE-2020-0001**\n| Severity | Package | Fixed Version | Link |\n| --- | --- | --- | --- |\n|HIGH|foo|3.4.5|[CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)|\n\nbaz"), }, }, }, @@ -130,7 +130,7 @@ func TestReportWriter_Sarif(t *testing.T) { RuleID: lo.ToPtr("CVE-2020-0001"), RuleIndex: lo.ToPtr[uint](0), Level: lo.ToPtr("error"), - Message: sarif.Message{Text: lo.ToPtr("Package: foo\\nInstalled Version: 1.2.3\\nVulnerability CVE-2020-0001\\nSeverity: HIGH\\nFixed Version: 3.4.5\\nLink: [CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)")}, + Message: sarif.Message{Text: lo.ToPtr("Package: foo\nInstalled Version: 1.2.3\nVulnerability CVE-2020-0001\nSeverity: HIGH\nFixed Version: 3.4.5\nLink: [CVE-2020-0001](https://avd.aquasec.com/nvd/cve-2020-0001)")}, Locations: []*sarif.Location{ { Message: &sarif.Message{Text: lo.ToPtr("library/test: foo@1.2.3")}, @@ -243,8 +243,8 @@ func TestReportWriter_Sarif(t *testing.T) { "security-severity": "8.0", }, Help: &sarif.MultiformatMessageString{ - Text: lo.ToPtr("Misconfiguration KSV001\\nType: Kubernetes Security Check\\nSeverity: HIGH\\nCheck: Image tag ':latest' used\\nMessage: Message\\nLink: [KSV001](https://avd.aquasec.com/appshield/ksv001)\\n"), - Markdown: lo.ToPtr("**Misconfiguration KSV001**\\n| Type | Severity | Check | Message | Link |\\n| --- | --- | --- | --- | --- |\\n|Kubernetes Security Check|HIGH|Image tag ':latest' used|Message|[KSV001](https://avd.aquasec.com/appshield/ksv001)|\\n\\n"), + Text: lo.ToPtr("Misconfiguration KSV001\nType: Kubernetes Security Check\nSeverity: HIGH\nCheck: Image tag ':latest' used\nMessage: Message\nLink: [KSV001](https://avd.aquasec.com/appshield/ksv001)\n"), + Markdown: lo.ToPtr("**Misconfiguration KSV001**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|Kubernetes Security Check|HIGH|Image tag ':latest' used|Message|[KSV001](https://avd.aquasec.com/appshield/ksv001)|\n\n"), }, }, { @@ -266,8 +266,8 @@ func TestReportWriter_Sarif(t *testing.T) { "security-severity": "9.5", }, Help: &sarif.MultiformatMessageString{ - Text: lo.ToPtr("Misconfiguration KSV002\\nType: Kubernetes Security Check\\nSeverity: CRITICAL\\nCheck: SYS_ADMIN capability added\\nMessage: Message\\nLink: [KSV002](https://avd.aquasec.com/appshield/ksv002)\\n"), - Markdown: lo.ToPtr("**Misconfiguration KSV002**\\n| Type | Severity | Check | Message | Link |\\n| --- | --- | --- | --- | --- |\\n|Kubernetes Security Check|CRITICAL|SYS_ADMIN capability added|Message|[KSV002](https://avd.aquasec.com/appshield/ksv002)|\\n\\n"), + Text: lo.ToPtr("Misconfiguration KSV002\nType: Kubernetes Security Check\nSeverity: CRITICAL\nCheck: SYS_ADMIN capability added\nMessage: Message\nLink: [KSV002](https://avd.aquasec.com/appshield/ksv002)\n"), + Markdown: lo.ToPtr("**Misconfiguration KSV002**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|Kubernetes Security Check|CRITICAL|SYS_ADMIN capability added|Message|[KSV002](https://avd.aquasec.com/appshield/ksv002)|\n\n"), }, }, }, @@ -278,7 +278,7 @@ func TestReportWriter_Sarif(t *testing.T) { RuleID: lo.ToPtr("KSV001"), RuleIndex: lo.ToPtr[uint](0), Level: lo.ToPtr("error"), - Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\\nType: \\nVulnerability KSV001\\nSeverity: HIGH\\nMessage: Message\\nLink: [KSV001](https://avd.aquasec.com/appshield/ksv001)")}, + Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\nType: \nVulnerability KSV001\nSeverity: HIGH\nMessage: Message\nLink: [KSV001](https://avd.aquasec.com/appshield/ksv001)")}, Locations: []*sarif.Location{ { Message: &sarif.Message{Text: lo.ToPtr("library/test")}, @@ -301,7 +301,7 @@ func TestReportWriter_Sarif(t *testing.T) { RuleID: lo.ToPtr("KSV002"), RuleIndex: lo.ToPtr[uint](1), Level: lo.ToPtr("error"), - Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\\nType: \\nVulnerability KSV002\\nSeverity: CRITICAL\\nMessage: Message\\nLink: [KSV002](https://avd.aquasec.com/appshield/ksv002)")}, + Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\nType: \nVulnerability KSV002\nSeverity: CRITICAL\nMessage: Message\nLink: [KSV002](https://avd.aquasec.com/appshield/ksv002)")}, Locations: []*sarif.Location{ { Message: &sarif.Message{Text: lo.ToPtr("library/test")}, @@ -383,8 +383,8 @@ func TestReportWriter_Sarif(t *testing.T) { "security-severity": "9.5", }, Help: &sarif.MultiformatMessageString{ - Text: lo.ToPtr("Secret AWS Secret Access Key\\nSeverity: CRITICAL\\nMatch: 'AWS_secret_KEY'=\"****************************************\""), - Markdown: lo.ToPtr("**Secret AWS Secret Access Key**\\n| Severity | Match |\\n| --- | --- |\\n|CRITICAL|'AWS_secret_KEY'=\"****************************************\"|"), + Text: lo.ToPtr("Secret AWS Secret Access Key\nSeverity: CRITICAL\nMatch: 'AWS_secret_KEY'=\"****************************************\""), + Markdown: lo.ToPtr("**Secret AWS Secret Access Key**\n| Severity | Match |\n| --- | --- |\n|CRITICAL|'AWS_secret_KEY'=\"****************************************\"|"), }, }, }, @@ -395,7 +395,7 @@ func TestReportWriter_Sarif(t *testing.T) { RuleID: lo.ToPtr("aws-secret-access-key"), RuleIndex: lo.ToPtr[uint](0), Level: lo.ToPtr("error"), - Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\\nType: \\nSecret AWS Secret Access Key\\nSeverity: CRITICAL\\nMatch: 'AWS_secret_KEY'=\"****************************************\"")}, + Message: sarif.Message{Text: lo.ToPtr("Artifact: library/test\nType: \nSecret AWS Secret Access Key\nSeverity: CRITICAL\nMatch: 'AWS_secret_KEY'=\"****************************************\"")}, Locations: []*sarif.Location{ { Message: &sarif.Message{Text: lo.ToPtr("library/test")}, @@ -464,8 +464,8 @@ func TestReportWriter_Sarif(t *testing.T) { ShortDescription: sarif.NewMultiformatMessageString("GPL-3.0 in alpine-base"), FullDescription: sarif.NewMultiformatMessageString("GPL-3.0 in alpine-base"), DefaultConfiguration: sarif.NewReportingConfiguration().WithLevel("error"), - Help: sarif.NewMultiformatMessageString("License GPL-3.0\\nClassification: restricted\\nPkgName: alpine-base\\nPath: "). - WithMarkdown("**License GPL-3.0**\\n| PkgName | Classification | Path |\\n| --- | --- | --- |\\n|alpine-base|restricted||"), + Help: sarif.NewMultiformatMessageString("License GPL-3.0\nClassification: restricted\nPkgName: alpine-base\nPath: "). + WithMarkdown("**License GPL-3.0**\n| PkgName | Classification | Path |\n| --- | --- | --- |\n|alpine-base|restricted||"), Properties: map[string]interface{}{ "tags": []interface{}{ "license", @@ -484,7 +484,7 @@ func TestReportWriter_Sarif(t *testing.T) { RuleID: lo.ToPtr("alpine-base:GPL-3.0"), RuleIndex: lo.ToPtr(uint(0)), Level: lo.ToPtr("error"), - Message: sarif.Message{Text: lo.ToPtr("Artifact: OS Packages\\nLicense GPL-3.0\\nPkgName: restricted\\n Classification: alpine-base\\n Path: ")}, + Message: sarif.Message{Text: lo.ToPtr("Artifact: OS Packages\nLicense GPL-3.0\nPkgName: restricted\n Classification: alpine-base\n Path: ")}, Locations: []*sarif.Location{ { Message: sarif.NewTextMessage(""), From 958e1f11f77076188bcdf0811bbd50be68d0a18b Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:51:30 +0600 Subject: [PATCH 077/108] fix(secret): `AWS Secret Access Key` must include only secrets with `aws` text. (#5901) --- pkg/fanal/secret/builtin-rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index ce6baa99a245..94da8a3b722a 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -78,7 +78,7 @@ const ( startSecret = `(^|\s+)` endSecret = `(\s+|$)` - aws = `(aws)?_?` + aws = `aws_?` ) // This function is exported for trivy-plugin-aqua purposes only From d0c81e23c4bf83923ac0a3218b70fc34679ddb9f Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Wed, 10 Jan 2024 10:37:19 +0400 Subject: [PATCH 078/108] feat(vex): add PURL matching for CSAF VEX (#5890) Signed-off-by: knqyf263 --- integration/testdata/conda-spdx.json.golden | 12 +- pkg/fanal/analyzer/sbom/sbom.go | 3 - pkg/fanal/analyzer/sbom/sbom_test.go | 132 +++---- pkg/fanal/applier/applier_test.go | 212 +++++------ pkg/fanal/applier/docker.go | 6 +- pkg/fanal/applier/docker_test.go | 204 +++++------ pkg/fanal/artifact/image/remote_sbom_test.go | 44 +-- pkg/fanal/artifact/sbom/sbom_test.go | 160 ++++----- .../handler/unpackaged/unpackaged_test.go | 12 +- pkg/fanal/types/artifact.go | 49 ++- pkg/fanal/types/purl.go | 78 ---- pkg/k8s/scanner/scanner.go | 6 +- pkg/k8s/scanner/scanner_test.go | 11 +- pkg/module/serialize/types_easyjson.go | 85 +---- pkg/purl/purl.go | 219 +++++++---- pkg/purl/purl_test.go | 219 ++++++++--- pkg/result/filter_test.go | 36 +- pkg/rpc/convert.go | 8 +- pkg/sbom/cyclonedx/core/cyclonedx.go | 6 +- pkg/sbom/cyclonedx/core/cyclonedx_test.go | 8 +- pkg/sbom/cyclonedx/marshal.go | 2 +- pkg/sbom/cyclonedx/marshal_test.go | 270 ++++++-------- pkg/sbom/cyclonedx/unmarshal.go | 17 +- pkg/sbom/cyclonedx/unmarshal_test.go | 339 ++++++++---------- pkg/sbom/spdx/marshal_test.go | 146 ++++---- pkg/sbom/spdx/unmarshal.go | 21 +- pkg/sbom/spdx/unmarshal_test.go | 146 ++++---- pkg/vex/csaf.go | 31 +- pkg/vex/vex_test.go | 144 ++++---- 29 files changed, 1236 insertions(+), 1390 deletions(-) delete mode 100644 pkg/fanal/types/purl.go diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index a201662a7736..be1146b285c4 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -22,7 +22,7 @@ }, { "name": "openssl", - "SPDXID": "SPDXRef-Package-38e5db7a21fc70a8", + "SPDXID": "SPDXRef-Package-20b95c21bfbf9fc4", "versionInfo": "1.1.1q", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -43,7 +43,7 @@ }, { "name": "pip", - "SPDXID": "SPDXRef-Package-f9844c873ead5dbe", + "SPDXID": "SPDXRef-Package-11a429ec3bd01d80", "versionInfo": "22.2.2", "supplier": "NOASSERTION", "downloadLocation": "NONE", @@ -110,21 +110,21 @@ }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-38e5db7a21fc70a8", + "relatedSpdxElement": "SPDXRef-Package-20b95c21bfbf9fc4", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-38e5db7a21fc70a8", + "spdxElementId": "SPDXRef-Package-20b95c21bfbf9fc4", "relatedSpdxElement": "SPDXRef-File-600e5e0110a84891", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Application-ee5ef1aa4ac89125", - "relatedSpdxElement": "SPDXRef-Package-f9844c873ead5dbe", + "relatedSpdxElement": "SPDXRef-Package-11a429ec3bd01d80", "relationshipType": "CONTAINS" }, { - "spdxElementId": "SPDXRef-Package-f9844c873ead5dbe", + "spdxElementId": "SPDXRef-Package-11a429ec3bd01d80", "relatedSpdxElement": "SPDXRef-File-7eb62e2a3edddc0a", "relationshipType": "CONTAINS" } diff --git a/pkg/fanal/analyzer/sbom/sbom.go b/pkg/fanal/analyzer/sbom/sbom.go index 51b5178c781c..efb9829a1593 100644 --- a/pkg/fanal/analyzer/sbom/sbom.go +++ b/pkg/fanal/analyzer/sbom/sbom.go @@ -88,9 +88,6 @@ func handleBitnamiImages(componentPath string, bom types.SBOM) { // If the file path is empty, the file path will be set to the component dir path. filePath := path.Join(componentPath, pkg.FilePath) bom.Applications[i].Libraries[j].FilePath = filePath - if pkg.Identifier.PURL != nil && pkg.Identifier.PURL.FilePath != "" { - bom.Applications[i].Libraries[j].Identifier.PURL.FilePath = filePath - } } } } diff --git a/pkg/fanal/analyzer/sbom/sbom_test.go b/pkg/fanal/analyzer/sbom/sbom_test.go index 4e37834d04d8..096d0ececec5 100644 --- a/pkg/fanal/analyzer/sbom/sbom_test.go +++ b/pkg/fanal/analyzer/sbom/sbom_test.go @@ -35,13 +35,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", }, }, }, @@ -50,13 +48,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent-cached-lookup-key", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", }, }, }, @@ -65,13 +61,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent-common", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-common", + Version: "1.36.0", }, }, }, @@ -80,13 +74,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "1.36.0", FilePath: "opt/bitnami/elasticsearch", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent-core", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-core", + Version: "1.36.0", }, }, }, @@ -102,16 +94,14 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Arch: "arm64", Licenses: []string{"Elastic-2.0"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "elasticsearch", - Version: "8.9.1", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "arm64", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "elasticsearch", + Version: "8.9.1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "arm64", }, }, }, @@ -137,14 +127,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Name: "co.elastic.apm:apm-agent", Version: "1.36.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent", - Version: "1.36.0", - }, - FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", }, BOMRef: "pkg:maven/co.elastic.apm/apm-agent@1.36.0", }, @@ -154,14 +141,11 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent-cached-lookup-key", - Version: "1.36.0", - }, - FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", }, BOMRef: "pkg:maven/co.elastic.apm/apm-agent-cached-lookup-key@1.36.0", }, @@ -187,12 +171,10 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "3.7.1", Licenses: []string{"MIT"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "gdal", - Version: "3.7.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "gdal", + Version: "3.7.1", }, }, }, @@ -201,12 +183,10 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "3.8.3", Licenses: []string{"LGPL-2.1-only"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "geos", - Version: "3.8.3", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "geos", + Version: "3.8.3", }, }, }, @@ -215,12 +195,10 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "15.3.0", Licenses: []string{"PostgreSQL"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "postgresql", - Version: "15.3.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "postgresql", + Version: "15.3.0", }, }, }, @@ -229,12 +207,10 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { Version: "6.3.2", Licenses: []string{"MIT"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "proj", - Version: "6.3.2", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "proj", + Version: "6.3.2", }, }, }, diff --git a/pkg/fanal/applier/applier_test.go b/pkg/fanal/applier/applier_test.go index 0994d46bfc39..8037e0bee922 100644 --- a/pkg/fanal/applier/applier_test.go +++ b/pkg/fanal/applier/applier_test.go @@ -151,17 +151,15 @@ func TestApplier_ApplyLayers(t *testing.T) { SrcName: "glibc", SrcVersion: "2.24-11+deb9u4", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "debian", - Name: "libc6", - Version: "2.24-11+deb9u4", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "debian-9.9", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "libc6", + Version: "2.24-11+deb9u4", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-9.9", }, }, }, @@ -177,17 +175,15 @@ func TestApplier_ApplyLayers(t *testing.T) { SrcName: "tzdata", SrcVersion: "2019a-0+deb9u1", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "debian", - Name: "tzdata", - Version: "2019a-0+deb9u1", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "debian-9.9", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "tzdata", + Version: "2019a-0+deb9u1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-9.9", }, }, }, @@ -211,13 +207,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "guzzlehttp", - Name: "guzzle", - Version: "6.2.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", }, }, }, @@ -229,13 +223,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "symfony", - Name: "process", - Version: "v4.2.7", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", }, }, }, @@ -353,17 +345,15 @@ func TestApplier_ApplyLayers(t *testing.T) { Name: "busybox", Version: "1.30.1-r3", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "busybox", - Version: "1.30.1-r3", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "busybox", + Version: "1.30.1-r3", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", }, }, }, @@ -377,17 +367,15 @@ func TestApplier_ApplyLayers(t *testing.T) { Name: "libcrypto1.1", Version: "1.1.1d-r2", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "libcrypto1.1", - Version: "1.1.1d-r2", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "libcrypto1.1", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", }, }, }, @@ -401,17 +389,15 @@ func TestApplier_ApplyLayers(t *testing.T) { Name: "libssl1.1", Version: "1.1.1d-r2", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "libssl1.1", - Version: "1.1.1d-r2", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "libssl1.1", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", }, }, }, @@ -425,17 +411,15 @@ func TestApplier_ApplyLayers(t *testing.T) { Name: "musl", Version: "1.1.22-r3", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.1.22-r3", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.1.22-r3", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", }, }, }, @@ -450,17 +434,15 @@ func TestApplier_ApplyLayers(t *testing.T) { Version: "1.1.1d-r2", Identifier: types.PkgIdentifier{ //PURL: "pkg:apk/alpine/openssl@1.1.1d-r2?distro=3.10.4", - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "openssl", - Version: "1.1.1d-r2", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "openssl", + Version: "1.1.1d-r2", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10.4", }, }, }, @@ -684,13 +666,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "guzzlehttp", - Name: "guzzle", - Version: "6.2.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", }, }, }, @@ -702,13 +682,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "symfony", - Name: "process", - Version: "v4.2.7", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", }, }, }, @@ -896,13 +874,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "guzzlehttp", - Name: "guzzle", - Version: "6.2.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "guzzlehttp", + Name: "guzzle", + Version: "6.2.0", }, }, }, @@ -914,13 +890,11 @@ func TestApplier_ApplyLayers(t *testing.T) { DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "symfony", - Name: "process", - Version: "v4.2.7", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "process", + Version: "v4.2.7", }, }, }, diff --git a/pkg/fanal/applier/docker.go b/pkg/fanal/applier/docker.go index 68de804c89b1..730737e8a370 100644 --- a/pkg/fanal/applier/docker.go +++ b/pkg/fanal/applier/docker.go @@ -6,6 +6,7 @@ import ( "time" "github.com/knqyf263/nested" + "github.com/package-url/packageurl-go" "github.com/samber/lo" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" @@ -249,12 +250,13 @@ func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail { return mergedLayer } -func newPURL(pkgType ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) *ftypes.PackageURL { +func newPURL(pkgType ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) *packageurl.PackageURL { p, err := purl.New(pkgType, metadata, pkg) if err != nil { log.Logger.Errorf("Failed to create PackageURL: %s", err) + return nil } - return p + return p.Unwrap() } // aggregate merges all packages installed by pip/gem/npm/jar/conda into each application diff --git a/pkg/fanal/applier/docker_test.go b/pkg/fanal/applier/docker_test.go index a8076f3bb4e5..425930b9ba2e 100644 --- a/pkg/fanal/applier/docker_test.go +++ b/pkg/fanal/applier/docker_test.go @@ -1,10 +1,10 @@ package applier_test import ( - "github.com/package-url/packageurl-go" "sort" "testing" + "github.com/package-url/packageurl-go" "github.com/stretchr/testify/assert" "github.com/aquasecurity/trivy/pkg/fanal/applier" @@ -145,17 +145,15 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.4", Release: "4.5.8", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.4-4.5.8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.4-4.5.8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10", }, }, }, @@ -170,17 +168,15 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.3", Release: "4.5.6", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "openssl", - Version: "1.2.3-4.5.6", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.10", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "openssl", + Version: "1.2.3-4.5.6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.10", }, }, }, @@ -204,13 +200,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "activesupport", - Version: "6.0.2.1", - }, - FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "activesupport", + Version: "6.0.2.1", }, }, }, @@ -223,13 +216,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "gon", - Version: "6.3.2", - }, - FilePath: "usr/local/bundle/specifications/gon-6.3.2.gemspec", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "gon", + Version: "6.3.2", }, }, }, @@ -247,12 +237,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "gemlibrary1", - Version: "1.2.3", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "gemlibrary1", + Version: "1.2.3", }, }, }, @@ -474,12 +462,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "rack", - Version: "4.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "rack", + Version: "4.0.0", }, }, }, @@ -491,12 +477,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "rails", - Version: "6.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "rails", + Version: "6.0.0", }, }, }, @@ -514,12 +498,10 @@ func TestApplyLayers(t *testing.T) { DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Name: "phplibrary1", - Version: "6.6.6", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Name: "phplibrary1", + Version: "6.6.6", }, }, }, @@ -779,17 +761,15 @@ func TestApplyLayers(t *testing.T) { Release: "4.5.7", Licenses: []string{"GPL-2"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "debian", - Name: "libc", - Version: "1.2.4-4.5.7", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "debian-8", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "libc", + Version: "1.2.4-4.5.7", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-8", }, }, }, @@ -805,17 +785,15 @@ func TestApplyLayers(t *testing.T) { Release: "4.5.6", Licenses: []string{"OpenSSL"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "debian", - Name: "openssl", - Version: "1.2.3-4.5.6", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "debian-8", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "debian", + Name: "openssl", + Version: "1.2.3-4.5.6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "debian-8", }, }, }, @@ -957,17 +935,15 @@ func TestApplyLayers(t *testing.T) { Version: "5.6.7", Release: "8", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "redhat", - Name: "bash", - Version: "5.6.7-8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "redhat-8", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "bash", + Version: "5.6.7-8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", }, }, }, @@ -986,17 +962,15 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.4", Release: "5", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "redhat", - Name: "libc", - Version: "1.2.4-5", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "redhat-8", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "libc", + Version: "1.2.4-5", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", }, }, }, @@ -1017,17 +991,15 @@ func TestApplyLayers(t *testing.T) { Version: "1.2.3", Release: "4", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "redhat", - Name: "openssl", - Version: "1.2.3-4", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "redhat-8", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "openssl", + Version: "1.2.3-4", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "redhat-8", }, }, }, diff --git a/pkg/fanal/artifact/image/remote_sbom_test.go b/pkg/fanal/artifact/image/remote_sbom_test.go index 6b21e2200233..3e445fc0b9ee 100644 --- a/pkg/fanal/artifact/image/remote_sbom_test.go +++ b/pkg/fanal/artifact/image/remote_sbom_test.go @@ -84,17 +84,15 @@ func TestArtifact_InspectRekorAttestation(t *testing.T) { Name: "musl", Version: "1.2.3-r0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.2", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.2", }, }, }, @@ -235,13 +233,11 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { Name: "github.com/opencontainers/go-digest", Version: "v1.0.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/opencontainers", - Name: "go-digest", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/opencontainers", + Name: "go-digest", + Version: "v1.0.0", }, BOMRef: "pkg:golang/github.com/opencontainers/go-digest@v1.0.0", }, @@ -250,13 +246,11 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) { Name: "golang.org/x/sync", Version: "v0.1.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "golang.org/x", - Name: "sync", - Version: "v0.1.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "sync", + Version: "v0.1.0", }, BOMRef: "pkg:golang/golang.org/x/sync@v0.1.0", }, diff --git a/pkg/fanal/artifact/sbom/sbom_test.go b/pkg/fanal/artifact/sbom/sbom_test.go index e58437141ea8..f0286d4c3198 100644 --- a/pkg/fanal/artifact/sbom/sbom_test.go +++ b/pkg/fanal/artifact/sbom/sbom_test.go @@ -50,17 +50,15 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", }, }, }, @@ -82,13 +80,11 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -101,13 +97,11 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -125,13 +119,11 @@ func TestArtifact_Inspect(t *testing.T) { DiffID: "sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1", }, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/package-url", - Name: "packageurl-go", - Version: "v0.1.1-0.20220203205134-d70459300c8a", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", }, BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, @@ -150,14 +142,11 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/maven/target/child-project-1.0.jar", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.codehaus.mojo", - Name: "child-project", - Version: "1.0", - }, - FilePath: "app/maven/target/child-project-1.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", }, BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, @@ -177,13 +166,10 @@ func TestArtifact_Inspect(t *testing.T) { }, FilePath: "app/app/package.json", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "bootstrap", - Version: "5.0.2", - }, - FilePath: "app/app/package.json", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", }, BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, @@ -226,17 +212,15 @@ func TestArtifact_Inspect(t *testing.T) { SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", }, }, }, @@ -258,13 +242,11 @@ func TestArtifact_Inspect(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -277,13 +259,11 @@ func TestArtifact_Inspect(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -301,13 +281,11 @@ func TestArtifact_Inspect(t *testing.T) { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/package-url", - Name: "packageurl-go", - Version: "v0.1.1-0.20220203205134-d70459300c8a", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", }, BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, @@ -325,14 +303,11 @@ func TestArtifact_Inspect(t *testing.T) { Name: "org.codehaus.mojo:child-project", Version: "1.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.codehaus.mojo", - Name: "child-project", - Version: "1.0", - }, - FilePath: "app/maven/target/child-project-1.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", }, BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, @@ -351,13 +326,10 @@ func TestArtifact_Inspect(t *testing.T) { Name: "bootstrap", Version: "5.0.2", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "bootstrap", - Version: "5.0.2", - }, - FilePath: "app/app/package.json", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", }, BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, diff --git a/pkg/fanal/handler/unpackaged/unpackaged_test.go b/pkg/fanal/handler/unpackaged/unpackaged_test.go index 40c3cff54fdd..a37748101144 100644 --- a/pkg/fanal/handler/unpackaged/unpackaged_test.go +++ b/pkg/fanal/handler/unpackaged/unpackaged_test.go @@ -46,13 +46,11 @@ func Test_unpackagedHook_Handle(t *testing.T) { Name: "github.com/spf13/cobra", Version: "1.5.0", Identifier: types.PkgIdentifier{ - PURL: &types.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/spf13", - Name: "cobra", - Version: "1.5.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/spf13", + Name: "cobra", + Version: "1.5.0", }, BOMRef: "pkg:golang/github.com/spf13/cobra@1.5.0", }, diff --git a/pkg/fanal/types/artifact.go b/pkg/fanal/types/artifact.go index b715cb7eeb77..2d8e491fc72c 100644 --- a/pkg/fanal/types/artifact.go +++ b/pkg/fanal/types/artifact.go @@ -1,9 +1,11 @@ package types import ( + "encoding/json" "time" v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/package-url/packageurl-go" "github.com/samber/lo" "github.com/aquasecurity/trivy/pkg/digest" @@ -102,8 +104,51 @@ type Package struct { // PkgIdentifier represents a software identifiers in one of more of the supported formats. type PkgIdentifier struct { - PURL *PackageURL `json:",omitempty"` - BOMRef string `json:",omitempty"` // For CycloneDX + PURL *packageurl.PackageURL `json:"-"` + BOMRef string `json:",omitempty"` // For CycloneDX +} + +// MarshalJSON customizes the JSON encoding of PkgIdentifier. +func (id *PkgIdentifier) MarshalJSON() ([]byte, error) { + var p string + if id.PURL != nil { + p = id.PURL.String() + } + + type Alias PkgIdentifier + return json.Marshal(&struct { + PURL string `json:",omitempty"` + *Alias + }{ + PURL: p, + Alias: (*Alias)(id), + }) +} + +// UnmarshalJSON customizes the JSON decoding of PkgIdentifier. +func (id *PkgIdentifier) UnmarshalJSON(data []byte) error { + type Alias PkgIdentifier + aux := &struct { + PURL string `json:",omitempty"` + *Alias + }{ + Alias: (*Alias)(id), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + if aux.PURL != "" { + p, err := packageurl.FromString(aux.PURL) + if err != nil { + return err + } else if len(p.Qualifiers) == 0 { + p.Qualifiers = nil + } + id.PURL = &p + } + + return nil } func (id *PkgIdentifier) Empty() bool { diff --git a/pkg/fanal/types/purl.go b/pkg/fanal/types/purl.go deleted file mode 100644 index 53ad1cbdc0ec..000000000000 --- a/pkg/fanal/types/purl.go +++ /dev/null @@ -1,78 +0,0 @@ -package types - -import ( - "encoding/json" - - "github.com/package-url/packageurl-go" - "golang.org/x/xerrors" -) - -type PackageURL struct { - packageurl.PackageURL - FilePath string -} - -func (p *PackageURL) BOMRef() string { - // 'bom-ref' must be unique within BOM, but PURLs may conflict - // when the same packages are installed in an artifact. - // In that case, we prefer to make PURLs unique by adding file paths, - // rather than using UUIDs, even if it is not PURL technically. - // ref. https://cyclonedx.org/use-cases/#dependency-graph - purl := p.PackageURL // so that it will not override the qualifiers below - if p.FilePath != "" { - purl.Qualifiers = append(purl.Qualifiers, - packageurl.Qualifier{ - Key: "file_path", - Value: p.FilePath, - }, - ) - } - return purl.String() -} - -func (p *PackageURL) MarshalJSON() ([]byte, error) { - if p == nil { - return nil, nil - } - return json.Marshal(p.String()) -} - -func (p *PackageURL) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - purl, err := NewPackageURL(s) - if err != nil { - return xerrors.Errorf("failed to parse purl(%s): %w", string(b), err) - } - *p = *purl - return nil -} - -func NewPackageURL(s string) (*PackageURL, error) { - p, err := packageurl.FromString(s) - if err != nil { - return nil, xerrors.Errorf("failed to parse purl(%s): %w", s, err) - } - - // Take out and delete the file path from qualifiers - var filePath string - for i, q := range p.Qualifiers { - if q.Key != "file_path" { - continue - } - filePath = q.Value - p.Qualifiers = append(p.Qualifiers[:i], p.Qualifiers[i+1:]...) - break - } - - if len(p.Qualifiers) == 0 { - p.Qualifiers = nil - } - - return &PackageURL{ - PackageURL: p, - FilePath: filePath, - }, nil -} diff --git a/pkg/k8s/scanner/scanner.go b/pkg/k8s/scanner/scanner.go index bbc7913ae745..ca08f8a86bd1 100644 --- a/pkg/k8s/scanner/scanner.go +++ b/pkg/k8s/scanner/scanner.go @@ -577,7 +577,7 @@ func nodeComponent(nf bom.NodeInfo) *core.Component { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: *packageurl.NewPackageURL(golang, "", runtimeName, runtimeVersion, packageurl.Qualifiers{}, ""), }, }, @@ -601,7 +601,7 @@ func toProperties(props map[string]string, namespace string) []core.Property { return properties } -func generatePURL(name, ver, nodeName string) *ftypes.PackageURL { +func generatePURL(name, ver, nodeName string) *purl.PackageURL { var namespace string // Identify k8s distribution. An empty namespace means upstream. @@ -611,7 +611,7 @@ func generatePURL(name, ver, nodeName string) *ftypes.PackageURL { namespace = "" } - return &ftypes.PackageURL{ + return &purl.PackageURL{ PackageURL: *packageurl.NewPackageURL(purl.TypeK8s, namespace, name, ver, nil, ""), } } diff --git a/pkg/k8s/scanner/scanner_test.go b/pkg/k8s/scanner/scanner_test.go index 5f70facd3cf6..ec6d78f73c05 100644 --- a/pkg/k8s/scanner/scanner_test.go +++ b/pkg/k8s/scanner/scanner_test.go @@ -2,7 +2,6 @@ package scanner import ( "context" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "sort" "testing" @@ -98,7 +97,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/kubernetes", @@ -110,7 +109,7 @@ func TestScanner_Scan(t *testing.T) { Type: cdx.ComponentTypeApplication, Name: "k8s.io/apiserver", Version: "1.21.1", - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: purl.TypeK8s, Name: "k8s.io/apiserver", @@ -123,7 +122,7 @@ func TestScanner_Scan(t *testing.T) { Type: cdx.ComponentTypeContainer, Name: "k8s.gcr.io/kube-apiserver", Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f", - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "oci", Name: "kube-apiserver", @@ -234,7 +233,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "k8s", Name: "k8s.io/kubelet", @@ -258,7 +257,7 @@ func TestScanner_Scan(t *testing.T) { Namespace: k8sCoreComponentNamespace, }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "github.com/containerd/containerd", diff --git a/pkg/module/serialize/types_easyjson.go b/pkg/module/serialize/types_easyjson.go index 3ccb7e194271..cd2826c716ea 100644 --- a/pkg/module/serialize/types_easyjson.go +++ b/pkg/module/serialize/types_easyjson.go @@ -1617,7 +1617,9 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgTypes(in *jlexer.Lexer, case "PkgPath": out.PkgPath = string(in.String()) case "PkgIdentifier": - easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, &out.PkgIdentifier) + if data := in.Raw(); in.Ok() { + in.AddError((out.PkgIdentifier).UnmarshalJSON(data)) + } case "InstalledVersion": out.InstalledVersion = string(in.String()) case "FixedVersion": @@ -1843,7 +1845,7 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgTypes(out *jwriter.Write } else { out.RawString(prefix) } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, in.PkgIdentifier) + out.Raw((in.PkgIdentifier).MarshalJSON()) } if in.InstalledVersion != "" { const prefix string = ",\"InstalledVersion\":" @@ -2215,71 +2217,6 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyDbPkgTypes(out *jwriter.Wri } out.RawByte('}') } -func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.Lexer, out *types1.PkgIdentifier) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "PURL": - if in.IsNull() { - in.Skip() - out.PURL = nil - } else { - if out.PURL == nil { - out.PURL = new(types1.PackageURL) - } - if data := in.Raw(); in.Ok() { - in.AddError((*out.PURL).UnmarshalJSON(data)) - } - } - case "BOMRef": - out.BOMRef = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter.Writer, in types1.PkgIdentifier) { - out.RawByte('{') - first := true - _ = first - if in.PURL != nil { - const prefix string = ",\"PURL\":" - first = false - out.RawString(prefix[1:]) - out.Raw((*in.PURL).MarshalJSON()) - } - if in.BOMRef != "" { - const prefix string = ",\"BOMRef\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.BOMRef)) - } - out.RawByte('}') -} func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Lexer, out *types1.Package) { isTopLevel := in.IsStart() if in.IsNull() { @@ -2304,7 +2241,9 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le case "Name": out.Name = string(in.String()) case "Identifier": - easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, &out.Identifier) + if data := in.Raw(); in.Ok() { + in.AddError((out.Identifier).UnmarshalJSON(data)) + } case "Version": out.Version = string(in.String()) case "Release": @@ -2358,7 +2297,7 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes(in *jlexer.Le if out.BuildInfo == nil { out.BuildInfo = new(types1.BuildInfo) } - easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes10(in, out.BuildInfo) + easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in, out.BuildInfo) } case "Indirect": out.Indirect = bool(in.Bool()) @@ -2475,7 +2414,7 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } else { out.RawString(prefix) } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, in.Identifier) + out.Raw((in.Identifier).MarshalJSON()) } if in.Version != "" { const prefix string = ",\"Version\":" @@ -2614,7 +2553,7 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } else { out.RawString(prefix) } - easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes10(out, *in.BuildInfo) + easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out, *in.BuildInfo) } if in.Indirect { const prefix string = ",\"Indirect\":" @@ -2715,7 +2654,7 @@ func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes(out *jwriter. } out.RawByte('}') } -func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes10(in *jlexer.Lexer, out *types1.BuildInfo) { +func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes9(in *jlexer.Lexer, out *types1.BuildInfo) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -2771,7 +2710,7 @@ func easyjson6601e8cdDecodeGithubComAquasecurityTrivyPkgFanalTypes10(in *jlexer. in.Consumed() } } -func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes10(out *jwriter.Writer, in types1.BuildInfo) { +func easyjson6601e8cdEncodeGithubComAquasecurityTrivyPkgFanalTypes9(out *jwriter.Writer, in types1.BuildInfo) { out.RawByte('{') first := true _ = first diff --git a/pkg/purl/purl.go b/pkg/purl/purl.go index c63c4fbb849f..bd62ce57cef8 100644 --- a/pkg/purl/purl.go +++ b/pkg/purl/purl.go @@ -43,13 +43,135 @@ const ( TypeUnknown = "unknown" ) -func FromString(s string) (*ftypes.PackageURL, error) { - return ftypes.NewPackageURL(s) +type PackageURL struct { + packageurl.PackageURL + FilePath string +} + +func FromString(s string) (*PackageURL, error) { + p, err := packageurl.FromString(s) + if err != nil { + return nil, xerrors.Errorf("failed to parse purl(%s): %w", s, err) + } + + // Take out and delete the file path from qualifiers + var filePath string + for i, q := range p.Qualifiers { + if q.Key != "file_path" { + continue + } + filePath = q.Value + p.Qualifiers = append(p.Qualifiers[:i], p.Qualifiers[i+1:]...) + break + } + + if len(p.Qualifiers) == 0 { + p.Qualifiers = nil + } + + return &PackageURL{ + PackageURL: p, + FilePath: filePath, + }, nil +} + +// nolint: gocyclo +func New(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (*PackageURL, error) { + qualifiers := parseQualifier(pkg) + pkg.Epoch = 0 // we moved Epoch to qualifiers so we don't need it in version + + ptype := purlType(t) + name := pkg.Name + ver := utils.FormatVersion(pkg) + namespace := "" + subpath := "" + + switch ptype { + case packageurl.TypeRPM: + ns, qs := parseRPM(metadata.OS, pkg.Modularitylabel) + namespace = string(ns) + qualifiers = append(qualifiers, qs...) + case packageurl.TypeDebian: + qualifiers = append(qualifiers, parseDeb(metadata.OS)...) + if metadata.OS != nil { + namespace = string(metadata.OS.Family) + } + case packageurl.TypeApk: + var qs packageurl.Qualifiers + name, namespace, qs = parseApk(name, metadata.OS) + qualifiers = append(qualifiers, qs...) + case packageurl.TypeMaven, string(ftypes.Gradle): // TODO: replace with packageurl.TypeGradle once they add it. + namespace, name = parseMaven(name) + case packageurl.TypePyPi: + name = parsePyPI(name) + case packageurl.TypeComposer: + namespace, name = parseComposer(name) + case packageurl.TypeGolang: + namespace, name = parseGolang(name) + if name == "" { + return nil, nil + } + case packageurl.TypeNPM: + namespace, name = parseNpm(name) + case packageurl.TypeSwift: + namespace, name = parseSwift(name) + case packageurl.TypeCocoapods: + name, subpath = parseCocoapods(name) + case packageurl.TypeOCI: + purl, err := parseOCI(metadata) + if err != nil { + return nil, err + } else if purl.Type == "" { + return nil, nil + } + return &PackageURL{PackageURL: purl}, nil + } + + return &PackageURL{ + PackageURL: *packageurl.NewPackageURL(ptype, namespace, name, ver, qualifiers, subpath), + FilePath: pkg.FilePath, + }, nil +} + +// WithPath wraps packageurl.PackageURL with the given file path +func WithPath(purl *packageurl.PackageURL, filePath string) *PackageURL { + if purl == nil { + return nil + } + return &PackageURL{ + PackageURL: *purl, + FilePath: filePath, + } +} + +func (p *PackageURL) BOMRef() string { + // 'bom-ref' must be unique within BOM, but PURLs may conflict + // when the same packages are installed in an artifact. + // In that case, we prefer to make PURLs unique by adding file paths, + // rather than using UUIDs, even if it is not PURL technically. + // ref. https://cyclonedx.org/use-cases/#dependency-graph + purl := p.PackageURL // so that it will not override the qualifiers below + if p.FilePath != "" { + purl.Qualifiers = append(purl.Qualifiers, + packageurl.Qualifier{ + Key: "file_path", + Value: p.FilePath, + }, + ) + } + return purl.String() +} + +func (p *PackageURL) Unwrap() *packageurl.PackageURL { + if p == nil { + return nil + } + return &p.PackageURL } // LangType returns an application type in Trivy // nolint: gocyclo -func LangType(p *ftypes.PackageURL) ftypes.LangType { +func (p *PackageURL) LangType() ftypes.LangType { switch p.Type { case packageurl.TypeComposer: return ftypes.Composer @@ -102,13 +224,13 @@ func LangType(p *ftypes.PackageURL) ftypes.LangType { } } -func Class(p *ftypes.PackageURL) types.ResultClass { +func (p *PackageURL) Class() types.ResultClass { switch p.Type { case packageurl.TypeApk, packageurl.TypeDebian, packageurl.TypeRPM: // OS packages return types.ClassOSPkg default: - if LangType(p) == TypeUnknown { + if p.LangType() == TypeUnknown { return types.ClassUnknown } // Language-specific packages @@ -116,10 +238,13 @@ func Class(p *ftypes.PackageURL) types.ResultClass { } } -func ToPackage(p *ftypes.PackageURL) *ftypes.Package { +func (p *PackageURL) Package() *ftypes.Package { pkg := &ftypes.Package{ Name: p.Name, Version: p.Version, + Identifier: ftypes.PkgIdentifier{ + PURL: p.Unwrap(), + }, } for _, q := range p.Qualifiers { switch q.Key { @@ -151,11 +276,10 @@ func ToPackage(p *ftypes.PackageURL) *ftypes.Package { // Return packages without namespace. // OS packages are not supposed to have namespace. - if p.Namespace == "" || Class(p) == types.ClassOSPkg { + if p.Namespace == "" || p.Class() == types.ClassOSPkg { return pkg } - // TODO: replace with packageurl.TypeGradle once they add it. if p.Type == packageurl.TypeMaven || p.Type == packageurl.TypeGradle { // Maven and Gradle packages separate ":" // e.g. org.springframework:spring-core @@ -167,63 +291,34 @@ func ToPackage(p *ftypes.PackageURL) *ftypes.Package { return pkg } -// nolint: gocyclo -func New(t ftypes.TargetType, metadata types.Metadata, pkg ftypes.Package) (*ftypes.PackageURL, error) { - qualifiers := parseQualifier(pkg) - pkg.Epoch = 0 // we moved Epoch to qualifiers so we don't need it in version - - ptype := purlType(t) - name := pkg.Name - ver := utils.FormatVersion(pkg) - namespace := "" - subpath := "" +// Match returns true if the given PURL "target" satisfies the constraint PURL "p". +// - If the constraint does not have a version, it will match any version in the target. +// - If the constraint has qualifiers, the target must have the same set of qualifiers to match. +func (p *PackageURL) Match(target *packageurl.PackageURL) bool { + if target == nil { + return false + } + switch { + case p.Type != target.Type: + return false + case p.Namespace != target.Namespace: + return false + case p.Name != target.Name: + return false + case p.Version != "" && p.Version != target.Version: + return false + case p.Subpath != "" && p.Subpath != target.Subpath: + return false + } - switch ptype { - case packageurl.TypeRPM: - ns, qs := parseRPM(metadata.OS, pkg.Modularitylabel) - namespace = string(ns) - qualifiers = append(qualifiers, qs...) - case packageurl.TypeDebian: - qualifiers = append(qualifiers, parseDeb(metadata.OS)...) - if metadata.OS != nil { - namespace = string(metadata.OS.Family) + // All qualifiers in the constraint must be in the target to match + q := target.Qualifiers.Map() + for k, v1 := range p.Qualifiers.Map() { + if v2, ok := q[k]; !ok || v1 != v2 { + return false } - case packageurl.TypeApk: - var qs packageurl.Qualifiers - name, namespace, qs = parseApk(name, metadata.OS) - qualifiers = append(qualifiers, qs...) - case packageurl.TypeMaven, string(ftypes.Gradle): // TODO: replace with packageurl.TypeGradle once they add it. - namespace, name = parseMaven(name) - case packageurl.TypePyPi: - name = parsePyPI(name) - case packageurl.TypeComposer: - namespace, name = parseComposer(name) - case packageurl.TypeGolang: - namespace, name = parseGolang(name) - if name == "" { - return nil, nil - } - case packageurl.TypeNPM: - namespace, name = parseNpm(name) - case packageurl.TypeSwift: - namespace, name = parseSwift(name) - case packageurl.TypeCocoapods: - name, subpath = parseCocoapods(name) - case packageurl.TypeOCI: - purl, err := parseOCI(metadata) - if err != nil { - return nil, err - } - if purl.Type == "" { - return nil, nil - } - return &ftypes.PackageURL{PackageURL: purl}, nil } - - return &ftypes.PackageURL{ - PackageURL: *packageurl.NewPackageURL(ptype, namespace, name, ver, qualifiers, subpath), - FilePath: pkg.FilePath, - }, nil + return true } // ref. https://github.com/package-url/purl-spec/blob/a748c36ad415c8aeffe2b8a4a5d8a50d16d6d85f/PURL-TYPES.rst#oci diff --git a/pkg/purl/purl_test.go b/pkg/purl/purl_test.go index 16c32cdf056c..876911ca521a 100644 --- a/pkg/purl/purl_test.go +++ b/pkg/purl/purl_test.go @@ -20,7 +20,7 @@ func TestNewPackageURL(t *testing.T) { typ ftypes.TargetType pkg ftypes.Package metadata types.Metadata - want *ftypes.PackageURL + want *purl.PackageURL wantErr string }{ { @@ -30,7 +30,7 @@ func TestNewPackageURL(t *testing.T) { Name: "org.springframework:spring-core", Version: "5.3.14", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -46,7 +46,7 @@ func TestNewPackageURL(t *testing.T) { Name: "org.springframework:spring-core", Version: "5.3.14", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -62,7 +62,7 @@ func TestNewPackageURL(t *testing.T) { Name: "@xtuc/ieee754", Version: "1.2.0", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Namespace: "@xtuc", @@ -78,7 +78,7 @@ func TestNewPackageURL(t *testing.T) { Name: "lodash", Version: "4.17.21", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "lodash", @@ -93,7 +93,7 @@ func TestNewPackageURL(t *testing.T) { Name: "@xtuc/ieee754", Version: "1.2.0", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Namespace: "@xtuc", @@ -109,7 +109,7 @@ func TestNewPackageURL(t *testing.T) { Name: "lodash", Version: "4.17.21", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "lodash", @@ -124,7 +124,7 @@ func TestNewPackageURL(t *testing.T) { Name: "Django_test", Version: "1.2.0", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypePyPi, Name: "django-test", @@ -139,7 +139,7 @@ func TestNewPackageURL(t *testing.T) { Name: "absl-py", Version: "0.4.1", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeConda, Name: "absl-py", @@ -154,7 +154,7 @@ func TestNewPackageURL(t *testing.T) { Name: "symfony/contracts", Version: "v1.0.2", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeComposer, Namespace: "symfony", @@ -170,7 +170,7 @@ func TestNewPackageURL(t *testing.T) { Name: "github.com/go-sql-driver/Mysql", Version: "v1.5.0", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/go-sql-driver", @@ -202,7 +202,7 @@ func TestNewPackageURL(t *testing.T) { }, }, }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeHex, Name: "bunt", @@ -217,7 +217,7 @@ func TestNewPackageURL(t *testing.T) { Name: "http", Version: "0.13.2", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypePub, Name: "http", @@ -233,7 +233,7 @@ func TestNewPackageURL(t *testing.T) { Name: "github.com/apple/swift-atomics", Version: "1.1.0", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeSwift, Namespace: "github.com/apple", @@ -250,7 +250,7 @@ func TestNewPackageURL(t *testing.T) { Name: "GoogleUtilities/NSData+zlib", Version: "7.5.2", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCocoapods, Name: "GoogleUtilities", @@ -267,7 +267,7 @@ func TestNewPackageURL(t *testing.T) { Name: "abomination", Version: "0.7.3", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCargo, Name: "abomination", @@ -283,7 +283,7 @@ func TestNewPackageURL(t *testing.T) { Name: "Newtonsoft.Json", Version: "9.0.1", }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNuget, Name: "Newtonsoft.Json", @@ -313,7 +313,7 @@ func TestNewPackageURL(t *testing.T) { Name: "8", }, }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -351,7 +351,7 @@ func TestNewPackageURL(t *testing.T) { Architecture: "amd64", }, }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeOCI, Namespace: "", @@ -399,7 +399,7 @@ func TestNewPackageURL(t *testing.T) { Architecture: "amd64", }, }, - want: &ftypes.PackageURL{ + want: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeOCI, Namespace: "", @@ -451,13 +451,13 @@ func TestFromString(t *testing.T) { testCases := []struct { name string purl string - want ftypes.PackageURL + want purl.PackageURL wantErr string }{ { name: "happy path for maven", purl: "pkg:maven/org.springframework/spring-core@5.0.4.RELEASE", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -470,7 +470,7 @@ func TestFromString(t *testing.T) { { name: "happy path for npm", purl: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "bootstrap", @@ -482,7 +482,7 @@ func TestFromString(t *testing.T) { { name: "happy path for coocapods", purl: "pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCocoapods, Name: "GoogleUtilities", @@ -494,7 +494,7 @@ func TestFromString(t *testing.T) { { name: "happy path for hex", purl: "pkg:hex/plug@1.14.0", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeHex, Name: "plug", @@ -505,7 +505,7 @@ func TestFromString(t *testing.T) { { name: "happy path for dart", purl: "pkg:pub/http@0.13.2", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypePub, Name: "http", @@ -516,7 +516,7 @@ func TestFromString(t *testing.T) { { name: "happy path for apk", purl: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?distro=3.14.2&epoch=1", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: string(analyzer.TypeApk), Namespace: "alpine", @@ -538,7 +538,7 @@ func TestFromString(t *testing.T) { { name: "happy path for rpm", purl: "pkg:rpm/redhat/containers-common@0.1.14", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -550,7 +550,7 @@ func TestFromString(t *testing.T) { { name: "happy path for conda", purl: "pkg:conda/absl-py@0.4.1", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeConda, Name: "absl-py", @@ -561,7 +561,7 @@ func TestFromString(t *testing.T) { { name: "bad rpm", purl: "pkg:rpm/redhat/a--@1.0.0", - want: ftypes.PackageURL{ + want: purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -585,15 +585,15 @@ func TestFromString(t *testing.T) { } } -func TestToPackage(t *testing.T) { +func TestPackageURL_Package(t *testing.T) { tests := []struct { name string - pkgURL *ftypes.PackageURL + pkgURL *purl.PackageURL wantPkg *ftypes.Package }{ { name: "rpm + Qualifiers", - pkgURL: &ftypes.PackageURL{ + pkgURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -626,26 +626,60 @@ func TestToPackage(t *testing.T) { Arch: "x86_64", Epoch: 1, Modularitylabel: "nodejs:10:8020020200707141642:6a468ee4", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "nodejs-full-i18n", + Version: "10.21.0-3.module_el8.2.0+391+8da3adc6", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "x86_64", + }, + { + Key: "epoch", + Value: "1", + }, + { + Key: "modularitylabel", + Value: "nodejs:10:8020020200707141642:6a468ee4", + }, + { + Key: "distro", + Value: "redhat-8", + }, + }, + }, + }, }, }, { name: "composer with namespace", - pkgURL: &ftypes.PackageURL{ + pkgURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeComposer, Namespace: "symfony", Name: "contracts", - Version: "v1.0.2", + Version: "1.0.2", }, }, wantPkg: &ftypes.Package{ Name: "symfony/contracts", - Version: "v1.0.2", + Version: "1.0.2", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "symfony", + Name: "contracts", + Version: "1.0.2", + }, + }, }, }, { name: "maven with namespace", - pkgURL: &ftypes.PackageURL{ + pkgURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -656,11 +690,19 @@ func TestToPackage(t *testing.T) { wantPkg: &ftypes.Package{ Name: "org.springframework:spring-core", Version: "5.0.4.RELEASE", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-core", + Version: "5.0.4.RELEASE", + }, + }, }, }, { name: "cocoapods with subpath", - pkgURL: &ftypes.PackageURL{ + pkgURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeCocoapods, Version: "4.2.0", @@ -671,11 +713,19 @@ func TestToPackage(t *testing.T) { wantPkg: &ftypes.Package{ Name: "AppCenter/Analytics", Version: "4.2.0", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeCocoapods, + Version: "4.2.0", + Name: "AppCenter", + Subpath: "Analytics", + }, + }, }, }, { name: "wrong epoch", - pkgURL: &ftypes.PackageURL{ + pkgURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "redhat", @@ -693,19 +743,33 @@ func TestToPackage(t *testing.T) { Name: "acl", Version: "2.2.53", Release: "1.el8", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "redhat", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "epoch", + Value: "wrong", + }, + }, + }, + }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := purl.ToPackage(tt.pkgURL) + got := tt.pkgURL.Package() assert.Equal(t, tt.wantPkg, got) }) } } -func TestLangType(t *testing.T) { +func TestPackageURL_LangType(t *testing.T) { tests := []struct { name string purl packageurl.PackageURL @@ -743,8 +807,77 @@ func TestLangType(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - p := &ftypes.PackageURL{PackageURL: tt.purl} - assert.Equalf(t, tt.want, purl.LangType(p), "LangType()") + p := &purl.PackageURL{PackageURL: tt.purl} + assert.Equalf(t, tt.want, p.LangType(), "LangType()") + }) + } +} + +func TestPackageURL_Match(t *testing.T) { + tests := []struct { + name string + constraint string + target string + want bool + }{ + { + name: "same purl", + constraint: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + target: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + want: true, + }, + { + name: "different type", + constraint: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + target: "pkg:maven/github.com/aquasecurity/trivy@0.49.0", + want: false, + }, + { + name: "different namespace", + constraint: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + target: "pkg:golang/github.com/aquasecurity2/trivy@0.49.0", + want: false, + }, + { + name: "different name", + constraint: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + target: "pkg:golang/github.com/aquasecurity/tracee@0.49.0", + want: false, + }, + { + name: "different version", + constraint: "pkg:golang/github.com/aquasecurity/trivy@0.49.0", + target: "pkg:golang/github.com/aquasecurity/trivy@0.49.1", + want: false, + }, + { + name: "version wildcard", + constraint: "pkg:golang/github.com/aquasecurity/trivy", + target: "pkg:golang/github.com/aquasecurity/trivy@0.50.0", + want: true, + }, + { + name: "different qualifier", + constraint: "pkg:bitnami/wordpress@6.2.0?arch=arm64&distro=debian-12", + target: "pkg:bitnami/wordpress@6.2.0?arch=arm64&distro=debian-13", + want: false, + }, + { + name: "target more qualifiers", + constraint: "pkg:bitnami/wordpress@6.2.0?arch=arm64", + target: "pkg:bitnami/wordpress@6.2.0?arch=arm64&distro=debian-13", + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c, err := purl.FromString(tt.constraint) + require.NoError(t, err) + + p, err := purl.FromString(tt.target) + require.NoError(t, err) + + assert.Equalf(t, tt.want, c.Match(p.Unwrap()), "Match()") }) } } diff --git a/pkg/result/filter_test.go b/pkg/result/filter_test.go index db9770d886d1..4edd86348c9b 100644 --- a/pkg/result/filter_test.go +++ b/pkg/result/filter_test.go @@ -154,13 +154,11 @@ func TestFilter(t *testing.T) { VulnerabilityID: "CVE-2019-0001", PkgName: "foo", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/aquasecurity", - Name: "foo", - Version: "1.2.3", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "foo", + Version: "1.2.3", }, }, InstalledVersion: "1.2.3", @@ -173,13 +171,11 @@ func TestFilter(t *testing.T) { VulnerabilityID: "CVE-2019-0001", PkgName: "bar", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/aquasecurity", - Name: "bar", - Version: "4.5.6", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "bar", + Version: "4.5.6", }, }, InstalledVersion: "4.5.6", @@ -209,13 +205,11 @@ func TestFilter(t *testing.T) { VulnerabilityID: "CVE-2019-0001", PkgName: "bar", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/aquasecurity", - Name: "bar", - Version: "4.5.6", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/aquasecurity", + Name: "bar", + Version: "4.5.6", }, }, InstalledVersion: "4.5.6", diff --git a/pkg/rpc/convert.go b/pkg/rpc/convert.go index a8a04d0dcbd6..7e2a09f2c7da 100644 --- a/pkg/rpc/convert.go +++ b/pkg/rpc/convert.go @@ -3,6 +3,7 @@ package rpc import ( "time" + "github.com/package-url/packageurl-go" "github.com/samber/lo" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" @@ -11,7 +12,6 @@ import ( "github.com/aquasecurity/trivy/pkg/digest" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" - "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/rpc/cache" "github.com/aquasecurity/trivy/rpc/common" @@ -82,7 +82,7 @@ func ConvertToRPCPkgIdentifier(pkg ftypes.PkgIdentifier) *common.PkgIdentifier { var p string if pkg.PURL != nil { - p = pkg.PURL.BOMRef() // Use BOMRef() instead of String() so that we won't lose file_path + p = pkg.PURL.String() } return &common.PkgIdentifier{ Purl: p, @@ -227,11 +227,11 @@ func ConvertFromRPCPkgIdentifier(pkg *common.PkgIdentifier) ftypes.PkgIdentifier } if pkg.Purl != "" { - pu, err := purl.FromString(pkg.Purl) + pu, err := packageurl.FromString(pkg.Purl) if err != nil { log.Logger.Error("Failed to parse PURL (%s): %s", pkg.Purl, err) } - pkgID.PURL = pu + pkgID.PURL = &pu } return pkgID diff --git a/pkg/sbom/cyclonedx/core/cyclonedx.go b/pkg/sbom/cyclonedx/core/cyclonedx.go index 2c5945b35416..7477a559262c 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx.go @@ -15,8 +15,8 @@ import ( "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/digest" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -39,7 +39,7 @@ type Component struct { Name string Group string Version string - PackageURL *ftypes.PackageURL + PackageURL *purl.PackageURL Licenses []string Hashes []digest.Digest Supplier string @@ -232,7 +232,7 @@ func (c *CycloneDX) Vulnerabilities(uniq map[string]*cdx.Vulnerability) *[]cdx.V return &vulns } -func (c *CycloneDX) PackageURL(p *ftypes.PackageURL) string { +func (c *CycloneDX) PackageURL(p *purl.PackageURL) string { if p == nil { return "" } diff --git a/pkg/sbom/cyclonedx/core/cyclonedx_test.go b/pkg/sbom/cyclonedx/core/cyclonedx_test.go index d3b37308140f..60ad12864520 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx_test.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx_test.go @@ -2,6 +2,7 @@ package core_test import ( "context" + "github.com/aquasecurity/trivy/pkg/purl" "testing" "time" @@ -11,7 +12,6 @@ import ( "github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/digest" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/sbom/cyclonedx/core" "github.com/aquasecurity/trivy/pkg/uuid" ) @@ -43,7 +43,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Type: cdx.ComponentTypeContainer, Name: "k8s.gcr.io/kube-apiserver", Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f", - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "oci", Name: "kube-apiserver", @@ -138,7 +138,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Value: "golang", }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "kubelet", @@ -157,7 +157,7 @@ func TestMarshaler_CoreComponent(t *testing.T) { Value: "golang", }, }, - PackageURL: &ftypes.PackageURL{ + PackageURL: &purl.PackageURL{ PackageURL: packageurl.PackageURL{ Type: "golang", Name: "containerd", diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index 16cb37c2d2fc..59564dddd6f8 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -378,7 +378,7 @@ func pkgComponent(pkg Package) (*core.Component, error) { Name: name, Group: group, Version: version, - PackageURL: pkg.Identifier.PURL, + PackageURL: purl.WithPath(pkg.Identifier.PURL, pkg.FilePath), Supplier: pkg.Maintainer, Licenses: pkg.Licenses, Hashes: lo.Ternary(pkg.Digest == "", nil, []digest.Digest{pkg.Digest}), diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 8169baf040bb..5a3022c91b0c 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -63,21 +63,19 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 0, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "binutils", - Version: "2.30-93.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "binutils", + Version: "2.30-93.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", }, }, }, @@ -145,12 +143,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", }, }, Indirect: false, @@ -160,12 +156,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actioncontroller", Version: "7.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actioncontroller", - Version: "7.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncontroller", + Version: "7.0.0", }, }, Indirect: false, @@ -185,12 +179,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", }, }, }, @@ -206,12 +198,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "Newtonsoft.Json", Version: "9.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNuget, - Name: "Newtonsoft.Json", - Version: "9.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNuget, + Name: "Newtonsoft.Json", + Version: "9.0.1", }, }, }, @@ -226,13 +216,11 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "golang.org/x/crypto", Version: "v0.0.0-20210421170649-83a5a9bb288b", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "golang.org/x", - Name: "crypto", - Version: "v0.0.0-20210421170649-83a5a9bb288b", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "crypto", + Version: "v0.0.0-20210421170649-83a5a9bb288b", }, }, }, @@ -667,25 +655,23 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 1, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "acl", - Version: "2.2.53-1.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, - { - Key: "epoch", - Value: "1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + { + Key: "epoch", + Value: "1", }, }, }, @@ -709,21 +695,19 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 0, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "glibc", - Version: "2.28-151.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "glibc", + Version: "2.28-151.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", }, }, }, @@ -748,13 +732,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, - FilePath: "tools/project-john/specifications/actionpack.gemspec", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", }, }, Layer: ftypes.Layer{ @@ -767,13 +748,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, - FilePath: "tools/project-doe/specifications/actionpack.gemspec", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, Layer: ftypes.Layer{ @@ -789,12 +767,10 @@ func TestMarshaler_Marshal(t *testing.T) { PkgName: "actionpack", PkgPath: "tools/project-john/specifications/actionpack.gemspec", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", }, }, InstalledVersion: "7.0.0", @@ -841,12 +817,10 @@ func TestMarshaler_Marshal(t *testing.T) { PkgName: "actionpack", PkgPath: "tools/project-doe/specifications/actionpack.gemspec", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, InstalledVersion: "7.0.1", @@ -1221,12 +1195,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actioncable", Version: "6.1.4.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actioncable", - Version: "6.1.4.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncable", + Version: "6.1.4.1", }, }, }, @@ -1241,14 +1213,11 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "org.springframework:spring-web", Version: "5.3.22", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework", - Name: "spring-web", - Version: "5.3.22", - }, - FilePath: "spring-web-5.3.22.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-web", + Version: "5.3.22", }, }, FilePath: "spring-web-5.3.22.jar", @@ -1375,14 +1344,11 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "org.apache.nifi:nifi-dbcp-base", Version: "1.20.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.apache.nifi", - Name: "nifi-dbcp-base", - Version: "1.20.0", - }, - FilePath: "nifi-dbcp-base-1.20.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-dbcp-base", + Version: "1.20.0", }, }, FilePath: "nifi-dbcp-base-1.20.0.jar", @@ -1391,14 +1357,11 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "org.apache.nifi:nifi-hikari-dbcp-service", Version: "1.20.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.apache.nifi", - Name: "nifi-hikari-dbcp-service", - Version: "1.20.0", - }, - FilePath: "nifi-hikari-dbcp-service-1.20.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-hikari-dbcp-service", + Version: "1.20.0", }, }, FilePath: "nifi-hikari-dbcp-service-1.20.0.jar", @@ -1410,13 +1373,11 @@ func TestMarshaler_Marshal(t *testing.T) { PkgName: "org.apache.nifi:nifi-dbcp-base", PkgPath: "nifi-dbcp-base-1.20.0.jar", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.apache.nifi", - Name: "nifi-dbcp-base", - Version: "1.20.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-dbcp-base", + Version: "1.20.0", }, }, InstalledVersion: "1.20.0", @@ -1462,13 +1423,11 @@ func TestMarshaler_Marshal(t *testing.T) { PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", PkgPath: "nifi-hikari-dbcp-service-1.20.0.jar", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.apache.nifi", - Name: "nifi-hikari-dbcp-service", - Version: "1.20.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.nifi", + Name: "nifi-hikari-dbcp-service", + Version: "1.20.0", }, }, InstalledVersion: "1.20.0", @@ -1680,13 +1639,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "ruby-typeprof", Version: "0.20.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "ruby-typeprof", - Version: "0.20.1", - }, - FilePath: "usr/local/lib/ruby/gems/3.1.0/gems/typeprof-0.21.1/vscode/package.json", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "ruby-typeprof", + Version: "0.20.1", }, }, Licenses: []string{"MIT"}, diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index 77babfda26aa..96fa09364640 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -202,7 +202,7 @@ func parsePkgs(components []cdx.Component, seen map[string]struct{}) ([]ftypes.P } // Skip unsupported package types - if purl.Class(pkgURL) == types.ClassUnknown { + if pkgURL.Class() == types.ClassUnknown { continue } pkgs = append(pkgs, *pkg) @@ -290,11 +290,11 @@ func aggregatePkgs(libs []cdx.Component) ([]ftypes.PackageInfo, []ftypes.Applica return nil, nil, xerrors.Errorf("failed to parse the component: %w", err) } - switch purl.Class(pkgURL) { + switch pkgURL.Class() { case types.ClassOSPkg: osPkgMap[pkgURL.Type] = append(osPkgMap[pkgURL.Type], *pkg) case types.ClassLangPkg: - langType := purl.LangType(pkgURL) + langType := pkgURL.LangType() langPkgMap[langType] = append(langPkgMap[langType], *pkg) } } @@ -337,7 +337,7 @@ func toApplication(component cdx.Component) *ftypes.Application { } } -func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, error) { +func toPackage(component cdx.Component) (*purl.PackageURL, *ftypes.Package, error) { if component.PackageURL == "" { log.Logger.Warnf("Skip the component (BOM-Ref: %s) as the PURL is empty", component.BOMRef) return nil, nil, ErrPURLEmpty @@ -347,7 +347,7 @@ func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, er return nil, nil, xerrors.Errorf("failed to parse purl: %w", err) } - pkg := purl.ToPackage(p) + pkg := p.Package() // Trivy's marshall loses case-sensitivity in PURL used in SBOM for packages (Go, Npm, PyPI), // so we have to use an original package name pkg.Name = packageName(p.Type, pkg.Name, component) @@ -382,12 +382,9 @@ func toPackage(component cdx.Component) (*ftypes.PackageURL, *ftypes.Package, er if pkg.FilePath != "" { p.FilePath = pkg.FilePath } - pkg.Identifier = ftypes.PkgIdentifier{ - PURL: p, - BOMRef: component.BOMRef, - } + pkg.Identifier.BOMRef = component.BOMRef - if purl.Class(p) == types.ClassOSPkg { + if p.Class() == types.ClassOSPkg { fillSrcPkg(pkg) } diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index a61bbf8d0d30..f62677a9ac70 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -40,17 +40,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", }, }, }, @@ -72,13 +70,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -91,13 +87,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -115,13 +109,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/package-url", - Name: "packageurl-go", - Version: "v0.1.1-0.20220203205134-d70459300c8a", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", }, BOMRef: "pkg:golang/github.com/package-url/packageurl-go@v0.1.1-0.20220203205134-d70459300c8a", }, @@ -138,13 +130,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "com.example:example", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.example", - Name: "example", - Version: "0.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.example", + Name: "example", + Version: "0.0.1", }, BOMRef: "pkg:maven/com.example/example@0.0.1", }, @@ -161,14 +151,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "org.codehaus.mojo:child-project", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.codehaus.mojo", - Name: "child-project", - Version: "1.0", - }, - FilePath: "app/maven/target/child-project-1.0.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", }, BOMRef: "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", }, @@ -188,13 +175,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "bootstrap", Version: "5.0.2", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "bootstrap", - Version: "5.0.2", - }, - FilePath: "app/app/package.json", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", }, BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, @@ -230,12 +214,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "docker", Version: "24.0.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Name: "docker", - Version: "24.0.4", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Name: "docker", + Version: "24.0.4", }, BOMRef: "pkg:golang/docker@24.0.4", }, @@ -253,12 +235,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/apiserver", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/apiserver", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/apiserver", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fapiserver@1.27.4", }, @@ -267,12 +247,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/controller-manager", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/controller-manager", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/controller-manager", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fcontroller-manager@1.27.4", }, @@ -281,12 +259,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/kube-proxy", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/kube-proxy", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kube-proxy", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fkube-proxy@1.27.4", }, @@ -295,12 +271,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/kube-scheduler", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/kube-scheduler", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kube-scheduler", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fkube-scheduler@1.27.4", }, @@ -309,12 +283,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/kubelet", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/kubelet", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kubelet", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fkubelet@1.27.4", }, @@ -323,12 +295,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "k8s.io/kubernetes", Version: "1.27.4", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: purl.TypeK8s, - Name: "k8s.io/kubernetes", - Version: "1.27.4", - }, + PURL: &packageurl.PackageURL{ + Type: purl.TypeK8s, + Name: "k8s.io/kubernetes", + Version: "1.27.4", }, BOMRef: "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", }, @@ -362,17 +332,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { "GFDL-1.3", }, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "ubuntu", - Name: "libc6", - Version: "2.35-0ubuntu3.1", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "ubuntu-22.04", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "ubuntu", + Name: "libc6", + Version: "2.35-0ubuntu3.1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "ubuntu-22.04", }, }, }, @@ -393,21 +361,19 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcRelease: "1", SrcEpoch: 1, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeDebian, - Namespace: "ubuntu", - Name: "libcrypt1", - Version: "4.4.27-1", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "ubuntu-22.04", - }, - { - Key: "epoch", - Value: "1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeDebian, + Namespace: "ubuntu", + Name: "libcrypt1", + Version: "4.4.27-1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "ubuntu-22.04", + }, + { + Key: "epoch", + Value: "1", }, }, }, @@ -441,17 +407,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", }, }, }, @@ -470,13 +434,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -487,13 +449,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -516,13 +476,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -545,13 +503,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -561,13 +517,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -590,13 +544,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/core", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "core", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "core", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/core@1.13.1", }, @@ -605,13 +557,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, BOMRef: "pkg:composer/pear/log@1.13.1", }, @@ -621,13 +571,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, BOMRef: "pkg:composer/pear/pear_exception@v1.0.0", }, @@ -649,14 +597,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "org.springframework:spring-web", Version: "5.3.22", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework", - Name: "spring-web", - Version: "5.3.22", - }, - FilePath: "spring-web-5.3.22.jar", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework", + Name: "spring-web", + Version: "5.3.22", }, BOMRef: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", }, diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index abd356d6ec7e..616108886264 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -62,21 +62,19 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 0, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "binutils", - Version: "2.30-93.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "binutils", + Version: "2.30-93.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", }, }, }, @@ -101,12 +99,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, }, @@ -114,12 +110,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actioncontroller", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actioncontroller", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncontroller", + Version: "7.0.1", }, }, }, @@ -134,12 +128,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, }, @@ -351,25 +343,23 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 1, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "acl", - Version: "2.2.53-1.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, - { - Key: "epoch", - Value: "1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "acl", + Version: "2.2.53-1.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + { + Key: "epoch", + Value: "1", }, }, }, @@ -393,12 +383,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, Layer: ftypes.Layer{ @@ -411,12 +399,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", }, }, Layer: ftypes.Layer{ @@ -634,12 +620,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actioncable", Version: "6.1.4.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actioncable", - Version: "6.1.4.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actioncable", + Version: "6.1.4.1", }, }, }, @@ -736,12 +720,10 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "ruby-typeprof", Version: "0.20.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "ruby-typeprof", - Version: "0.20.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "ruby-typeprof", + Version: "0.20.1", }, }, Licenses: []string{"MIT"}, @@ -976,13 +958,11 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "golang.org/x/crypto", Version: "v0.0.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "golang.org/x", - Name: "crypto", - Version: "v0.0.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "golang.org/x", + Name: "crypto", + Version: "v0.0.1", }, }, }, diff --git a/pkg/sbom/spdx/unmarshal.go b/pkg/sbom/spdx/unmarshal.go index 5ce4237ac20a..1723476a323d 100644 --- a/pkg/sbom/spdx/unmarshal.go +++ b/pkg/sbom/spdx/unmarshal.go @@ -177,12 +177,12 @@ func (s *SPDX) parsePackages(pkgs map[common.ElementID]*spdx.Package) error { } else if err != nil { return xerrors.Errorf("failed to parse package: %w", err) } - switch purl.Class(pkgURL) { + switch pkgURL.Class() { case types.ClassOSPkg: osPkgs = append(osPkgs, *pkg) case types.ClassLangPkg: // Language-specific packages - pkgType := purl.LangType(pkgURL) + pkgType := pkgURL.LangType() app, ok := apps[pkgType] if !ok { app.Type = pkgType @@ -246,12 +246,13 @@ func parseOS(pkg spdx.Package) ftypes.OS { } } -func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes.Package, *ftypes.PackageURL, error) { - pkg, pkgURL, err := parseExternalReferences(spdxPkg.PackageExternalReferences) +func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes.Package, *purl.PackageURL, error) { + pkgURL, err := parseExternalReferences(spdxPkg.PackageExternalReferences) if err != nil { return nil, nil, xerrors.Errorf("external references error: %w", err) } + pkg := pkgURL.Package() if spdxPkg.PackageLicenseDeclared != "NONE" { pkg.Licenses = strings.Split(spdxPkg.PackageLicenseDeclared, ",") } @@ -278,7 +279,7 @@ func parsePkg(spdxPkg spdx.Package, packageFilePaths map[string]string) (*ftypes return pkg, pkgURL, nil } -func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Package, *ftypes.PackageURL, error) { +func parseExternalReferences(refs []*spdx.PackageExternalReference) (*purl.PackageURL, error) { for _, ref := range refs { // Extract the package information from PURL if ref.RefType != RefTypePurl || ref.Category != CategoryPackageManager { @@ -287,15 +288,11 @@ func parseExternalReferences(refs []*spdx.PackageExternalReference) (*ftypes.Pac packageURL, err := purl.FromString(ref.Locator) if err != nil { - return nil, nil, xerrors.Errorf("failed to parse purl from string: %w", err) + return nil, xerrors.Errorf("failed to parse purl from string: %w", err) } - pkg := purl.ToPackage(packageURL) - pkg.Identifier = ftypes.PkgIdentifier{ - PURL: packageURL, - } - return pkg, packageURL, nil + return packageURL, nil } - return nil, nil, errUnknownPackageFormat + return nil, errUnknownPackageFormat } func lookupAttributionTexts(attributionTexts []string, key string) string { diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index dfa09a0c86fa..2d6ee258c378 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -40,17 +40,15 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { SrcVersion: "1.2.3-r0", Licenses: []string{"MIT"}, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeApk, - Namespace: "alpine", - Name: "musl", - Version: "1.2.3-r0", - Qualifiers: packageurl.Qualifiers{ - { - Key: "distro", - Value: "3.16.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeApk, + Namespace: "alpine", + Name: "musl", + Version: "1.2.3-r0", + Qualifiers: packageurl.Qualifiers{ + { + Key: "distro", + Value: "3.16.0", }, }, }, @@ -71,13 +69,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, }, Layer: ftypes.Layer{ @@ -89,13 +85,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, }, Layer: ftypes.Layer{ @@ -112,13 +106,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "github.com/package-url/packageurl-go", Version: "v0.1.1-0.20220203205134-d70459300c8a", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeGolang, - Namespace: "github.com/package-url", - Name: "packageurl-go", - Version: "v0.1.1-0.20220203205134-d70459300c8a", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGolang, + Namespace: "github.com/package-url", + Name: "packageurl-go", + Version: "v0.1.1-0.20220203205134-d70459300c8a", }, }, Layer: ftypes.Layer{ @@ -133,13 +125,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { { Name: "org.codehaus.mojo:child-project", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.codehaus.mojo", - Name: "child-project", - Version: "1.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.codehaus.mojo", + Name: "child-project", + Version: "1.0", }, }, Version: "1.0", @@ -156,12 +146,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "bootstrap", Version: "5.0.2", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "bootstrap", - Version: "5.0.2", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "bootstrap", + Version: "5.0.2", }, }, Licenses: []string{"MIT"}, @@ -188,12 +176,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "21.1.1", Licenses: []string{"ISC"}, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "yargs-parser", - Version: "21.1.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "yargs-parser", + Version: "21.1.1", }, }, FilePath: "node_modules/yargs-parser/package.json", @@ -217,12 +203,10 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Version: "21.1.1", Licenses: []string{"ISC"}, Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "yargs-parser", - Version: "21.1.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Name: "yargs-parser", + Version: "21.1.1", }, }, FilePath: "node_modules/yargs-parser/package.json", @@ -245,13 +229,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/log", Version: "1.13.1", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "log", - Version: "1.13.1", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "log", + Version: "1.13.1", }, }, }, @@ -260,13 +242,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "pear/pear_exception", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeComposer, - Namespace: "pear", - Name: "pear_exception", - Version: "v1.0.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeComposer, + Namespace: "pear", + Name: "pear_exception", + Version: "v1.0.0", }, }, }, @@ -288,13 +268,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "co.elastic.apm:apm-agent", Version: "1.36.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent", + Version: "1.36.0", }, }, }, @@ -303,13 +281,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { Name: "co.elastic.apm:apm-agent-cached-lookup-key", Version: "1.36.0", Identifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "co.elastic.apm", - Name: "apm-agent-cached-lookup-key", - Version: "1.36.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "co.elastic.apm", + Name: "apm-agent-cached-lookup-key", + Version: "1.36.0", }, }, }, diff --git a/pkg/vex/csaf.go b/pkg/vex/csaf.go index efed27b83f22..87684064b9d4 100644 --- a/pkg/vex/csaf.go +++ b/pkg/vex/csaf.go @@ -2,12 +2,12 @@ package vex import ( csaf "github.com/csaf-poc/csaf_distribution/v3/csaf" + "github.com/package-url/packageurl-go" "github.com/samber/lo" "go.uber.org/zap" - "golang.org/x/exp/slices" - ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" + "github.com/aquasecurity/trivy/pkg/purl" "github.com/aquasecurity/trivy/pkg/types" ) @@ -36,16 +36,16 @@ func (v *CSAF) Filter(vulns []types.DetectedVulnerability) []types.DetectedVulne }) } -func (v *CSAF) affected(vuln *csaf.Vulnerability, purl *ftypes.PackageURL) bool { - if purl == nil || vuln.ProductStatus == nil { +func (v *CSAF) affected(vuln *csaf.Vulnerability, pkgURL *packageurl.PackageURL) bool { + if pkgURL == nil || vuln.ProductStatus == nil { return true } var status Status switch { - case v.matchPURL(purl, vuln.ProductStatus.KnownNotAffected): + case v.matchPURL(vuln.ProductStatus.KnownNotAffected, pkgURL): status = StatusNotAffected - case v.matchPURL(purl, vuln.ProductStatus.Fixed): + case v.matchPURL(vuln.ProductStatus.Fixed, pkgURL): status = StatusFixed } @@ -60,17 +60,24 @@ func (v *CSAF) affected(vuln *csaf.Vulnerability, purl *ftypes.PackageURL) bool } // matchPURL returns true if the given PackageURL is found in the ProductTree. -func (v *CSAF) matchPURL(purl *ftypes.PackageURL, products *csaf.Products) bool { +func (v *CSAF) matchPURL(products *csaf.Products, pkgURL *packageurl.PackageURL) bool { for _, product := range lo.FromPtr(products) { helpers := v.advisory.ProductTree.CollectProductIdentificationHelpers(lo.FromPtr(product)) - purls := lo.FilterMap(helpers, func(helper *csaf.ProductIdentificationHelper, _ int) (string, bool) { + purls := lo.FilterMap(helpers, func(helper *csaf.ProductIdentificationHelper, _ int) (*purl.PackageURL, bool) { if helper == nil || helper.PURL == nil { - return "", false + return nil, false } - return string(*helper.PURL), true + p, err := purl.FromString(string(*helper.PURL)) + if err != nil { + v.logger.Errorw("Invalid PURL", zap.String("purl", string(*helper.PURL)), zap.Error(err)) + return nil, false + } + return p, true }) - if slices.Contains(purls, purl.String()) { - return true + for _, p := range purls { + if p.Match(pkgURL) { + return true + } } } diff --git a/pkg/vex/vex_test.go b/pkg/vex/vex_test.go index 1feb37a7c41d..004a0d14d842 100644 --- a/pkg/vex/vex_test.go +++ b/pkg/vex/vex_test.go @@ -47,13 +47,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "spring-boot", InstalledVersion: "2.6.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework.boot", - Name: "spring-boot", - Version: "2.6.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", }, }, }, @@ -73,13 +71,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "spring-boot", InstalledVersion: "2.6.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework.boot", - Name: "spring-boot", - Version: "2.6.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", }, }, }, @@ -88,13 +84,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "spring-boot", InstalledVersion: "2.6.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework.boot", - Name: "spring-boot", - Version: "2.6.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", }, }, }, @@ -106,13 +100,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "spring-boot", InstalledVersion: "2.6.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework.boot", - Name: "spring-boot", - Version: "2.6.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", }, }, }, @@ -136,13 +128,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "jackson-databind", InstalledVersion: "2.8.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.fasterxml.jackson.core", - Name: "jackson-databind", - Version: "2.8.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", }, }, }, @@ -151,13 +141,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "jackson-databind", InstalledVersion: "2.8.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.fasterxml.jackson.core", - Name: "jackson-databind", - Version: "2.8.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", }, }, }, @@ -169,13 +157,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "jackson-databind", InstalledVersion: "2.8.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.fasterxml.jackson.core", - Name: "jackson-databind", - Version: "2.8.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", }, }, }, @@ -199,13 +185,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "jackson-databind", InstalledVersion: "2.8.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.fasterxml.jackson.core", - Name: "jackson-databind", - Version: "2.8.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", }, }, }, @@ -217,13 +201,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "jackson-databind", InstalledVersion: "2.8.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "com.fasterxml.jackson.core", - Name: "jackson-databind", - Version: "2.8.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.8.0", }, }, }, @@ -241,13 +223,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "spring-boot", InstalledVersion: "2.6.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.springframework.boot", - Name: "spring-boot", - Version: "2.6.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.springframework.boot", + Name: "spring-boot", + Version: "2.6.0", }, }, }, @@ -267,13 +247,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "def", InstalledVersion: "1.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.example.company", - Name: "def", - Version: "1.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.example.company", + Name: "def", + Version: "1.0", }, }, }, @@ -285,13 +263,11 @@ func TestVEX_Filter(t *testing.T) { PkgName: "def", InstalledVersion: "1.0", PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &ftypes.PackageURL{ - PackageURL: packageurl.PackageURL{ - Type: packageurl.TypeMaven, - Namespace: "org.example.company", - Name: "def", - Version: "1.0", - }, + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.example.company", + Name: "def", + Version: "1.0", }, }, }, From 37e7e3eabf9b788d1f7549d96067d807895a121f Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:22:50 +0600 Subject: [PATCH 079/108] fix(java): check if a version exists when determining GAV by file name for `jar` files (#5630) --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/javadb/client.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index cb5fd7b3fccf..c97a83d631f0 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 - github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf + github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 @@ -26,7 +26,7 @@ require ( github.com/aquasecurity/trivy-aws v0.5.0 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-iac v0.7.1 - github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 + github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.24.1 diff --git a/go.sum b/go.sum index e87fee70e846..94a7ef40244b 100644 --- a/go.sum +++ b/go.sum @@ -328,8 +328,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 h1:mjQvKTiKYXWGxHU5pw37q1n6deky0KcJq5JJwtuVrF4= github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08/go.mod h1:NBF6hvbQSc4s/WCHdKV5sNNxLl258M2OiIFoUfgEn/k= -github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf h1:kweQrNMfarPfjZGI1537GtuujhpzhsuT/MvmW2FwaBE= -github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= +github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd h1:bhSbfJyZg4okPlAfIQ8pKsj8BCvs9LZErdkqUcpvD04= +github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8= @@ -355,8 +355,8 @@ github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTU github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkvmyd5Lsg= github.com/aquasecurity/trivy-iac v0.7.1/go.mod h1:SK5XaVwGh5M17QV81139BSPXNlm3bIGp+YmAYs7slRw= -github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728 h1:0eS+V7SXHgqoT99tV1mtMW6HL4HdoB9qGLMCb1fZp8A= -github.com/aquasecurity/trivy-java-db v0.0.0-20230209231723-7cddb1406728/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= +github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= +github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 h1:OTJMSbvKQYxbQ2NQ8Nht2NSL1bL36YfBCrlsGGxHPlI= github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091/go.mod h1:Yh+tmpPtbqVWYONrAuapImHfD1ghZgnZHLlMBA6Ukfg= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= diff --git a/pkg/javadb/client.go b/pkg/javadb/client.go index e1b67b81f781..7b206b6fc9e9 100644 --- a/pkg/javadb/client.go +++ b/pkg/javadb/client.go @@ -142,8 +142,8 @@ func (d *DB) SearchBySHA1(sha1 string) (jar.Properties, error) { }, nil } -func (d *DB) SearchByArtifactID(artifactID string) (string, error) { - indexes, err := d.driver.SelectIndexesByArtifactIDAndFileType(artifactID, types.JarType) +func (d *DB) SearchByArtifactID(artifactID, version string) (string, error) { + indexes, err := d.driver.SelectIndexesByArtifactIDAndFileType(artifactID, version, types.JarType) if err != nil { return "", xerrors.Errorf("select error: %w", err) } else if len(indexes) == 0 { From 7895657c89905a5447ca79c71382518907946d16 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:39:52 +0600 Subject: [PATCH 080/108] fix(java): don't remove excluded deps from upper pom's (#5838) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c97a83d631f0..90e4b2dca8c5 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 - github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd + github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 diff --git a/go.sum b/go.sum index 94a7ef40244b..d4abb3388dec 100644 --- a/go.sum +++ b/go.sum @@ -328,8 +328,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 h1:mjQvKTiKYXWGxHU5pw37q1n6deky0KcJq5JJwtuVrF4= github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08/go.mod h1:NBF6hvbQSc4s/WCHdKV5sNNxLl258M2OiIFoUfgEn/k= -github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd h1:bhSbfJyZg4okPlAfIQ8pKsj8BCvs9LZErdkqUcpvD04= -github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas= +github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 h1:jdymGFJpArgx1ZZW7yqgCV8Tt+sEZ4jKxjQufPYRSXE= +github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562/go.mod h1:B+gSaiuXV258CtyfBwFvG87+GE/FOh6W4N+LMuQxvVA= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8= From 4d2e785ff2d861e140694b08411219d1169ce29f Mon Sep 17 00:00:00 2001 From: mfreeman451 Date: Thu, 11 Jan 2024 01:25:44 -0600 Subject: [PATCH 081/108] =?UTF-8?q?docs:=20=E2=9C=A8=20Updated=20ecosystem?= =?UTF-8?q?=20docs=20with=20reference=20to=20new=20community=20app=20(#591?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ecosystem/miscellaneous.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/ecosystem/miscellaneous.md b/docs/ecosystem/miscellaneous.md index ba37e65160e5..cc8d9668e783 100644 --- a/docs/ecosystem/miscellaneous.md +++ b/docs/ecosystem/miscellaneous.md @@ -14,3 +14,8 @@ DefectDojo can parse Trivy JSON reports. The parser supports deduplication and a A Trivy plugin that scans and outputs the results to an interactive html file. 👉 Get it at: + +## Trivy-Streamlit (Community) +Trivy-Streamlit is a Streamlit application that allows you to quickly parse the results from a Trivy JSON report. + +👉 Get it at: From c8c55fe21e4622c62a7dbf199075053723be1009 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:30:40 +0400 Subject: [PATCH 082/108] chore(deps): bump github.com/aws/aws-sdk-go-v2/feature/s3/manager from 1.11.90 to 1.15.11 (#5885) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simar --- go.mod | 94 ++++++++++++------------- go.sum | 215 ++++++++++++++++++++++++++------------------------------- 2 files changed, 143 insertions(+), 166 deletions(-) diff --git a/go.mod b/go.mod index 90e4b2dca8c5..209f03ee435f 100644 --- a/go.mod +++ b/go.mod @@ -23,19 +23,19 @@ require ( github.com/aquasecurity/table v1.8.0 github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da github.com/aquasecurity/tml v0.6.1 - github.com/aquasecurity/trivy-aws v0.5.0 + github.com/aquasecurity/trivy-aws v0.7.0 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-iac v0.7.1 github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.24.1 - github.com/aws/aws-sdk-go-v2/config v1.25.11 - github.com/aws/aws-sdk-go-v2/credentials v1.16.9 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 - github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 - github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 + github.com/aws/aws-sdk-go-v2/config v1.26.3 + github.com/aws/aws-sdk-go-v2/credentials v1.16.14 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.142.0 + github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6 + github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cenkalti/backoff v2.2.1+incompatible @@ -159,51 +159,51 @@ require ( github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go v1.48.4 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect - github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 // indirect - github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0 // indirect - github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.14.5 // indirect - github.com/aws/aws-sdk-go-v2/service/athena v1.31.6 // indirect - github.com/aws/aws-sdk-go-v2/service/cloudfront v1.28.5 // indirect - github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.29.1 // indirect - github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.27.7 // indirect - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.23.5 // indirect - github.com/aws/aws-sdk-go-v2/service/codebuild v1.22.0 // indirect - github.com/aws/aws-sdk-go-v2/service/docdb v1.23.5 // indirect - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.26.7 // indirect + github.com/aws/aws-sdk-go-v2/service/apigateway v1.21.6 // indirect + github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/service/athena v1.37.3 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.5 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.35.6 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.32.2 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/codebuild v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6 // indirect + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 // indirect github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1 // indirect - github.com/aws/aws-sdk-go-v2/service/efs v1.21.6 // indirect - github.com/aws/aws-sdk-go-v2/service/eks v1.29.5 // indirect - github.com/aws/aws-sdk-go-v2/service/elasticache v1.29.3 // indirect - github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.21.3 // indirect - github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.20.6 // indirect - github.com/aws/aws-sdk-go-v2/service/emr v1.28.7 // indirect - github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ecs v1.35.6 // indirect + github.com/aws/aws-sdk-go-v2/service/efs v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/eks v1.37.0 // indirect + github.com/aws/aws-sdk-go-v2/service/elasticache v1.34.6 // indirect + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.26.6 // indirect + github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.25.0 // indirect + github.com/aws/aws-sdk-go-v2/service/emr v1.36.0 // indirect + github.com/aws/aws-sdk-go-v2/service/iam v1.28.7 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.8.11 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 // indirect - github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 // indirect - github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.5 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.24.5 // indirect - github.com/aws/aws-sdk-go-v2/service/lambda v1.39.5 // indirect - github.com/aws/aws-sdk-go-v2/service/mq v1.16.5 // indirect - github.com/aws/aws-sdk-go-v2/service/neptune v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/rds v1.54.0 // indirect - github.com/aws/aws-sdk-go-v2/service/redshift v1.29.5 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.21.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sns v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 // indirect - github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect + github.com/aws/aws-sdk-go-v2/service/kafka v1.28.5 // indirect + github.com/aws/aws-sdk-go-v2/service/kinesis v1.24.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect + github.com/aws/aws-sdk-go-v2/service/lambda v1.49.6 // indirect + github.com/aws/aws-sdk-go-v2/service/mq v1.20.6 // indirect + github.com/aws/aws-sdk-go-v2/service/neptune v1.28.1 // indirect + github.com/aws/aws-sdk-go-v2/service/rds v1.66.1 // indirect + github.com/aws/aws-sdk-go-v2/service/redshift v1.39.7 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sns v1.26.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sqs v1.29.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect + github.com/aws/aws-sdk-go-v2/service/workspaces v1.35.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect diff --git a/go.sum b/go.sum index d4abb3388dec..b023a067265e 100644 --- a/go.sum +++ b/go.sum @@ -332,8 +332,8 @@ github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 h1:jdym github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562/go.mod h1:B+gSaiuXV258CtyfBwFvG87+GE/FOh6W4N+LMuQxvVA= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= -github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8= -github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060/go.mod h1:QAMVTITMGE8AY3qkAIhYCNuQV2tTxzdmt7ZOP0SZwZs= +github.com/aquasecurity/go-mock-aws v0.0.0-20240109054747-49e4b5da33cb h1:dNxUB2bSbiLGNYcXkbBKrrfuY96+dXhA9FahEFZ4THQ= +github.com/aquasecurity/go-mock-aws v0.0.0-20240109054747-49e4b5da33cb/go.mod h1:iytBd25FZt3N6g+vGnNPO7BfgkV7HCEfIHyg8K/ldUw= github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 h1:eveqE9ivrt30CJ7dOajOfBavhZ4zPqHcZe/4tKp0alc= github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798/go.mod h1:hxbJZtKlO4P8sZ9nztizR6XLoE33O+BkPmuYQ4ACyz0= github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 h1:vmXNl+HDfqqXgr0uY1UgK1GAhps8nbAAtqHNBcgyf+4= @@ -349,8 +349,8 @@ github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da h1:pj/adfN github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da/go.mod h1:852lbQLpK2nCwlR4ZLYIccxYCfoQao6q9Nl6tjz54v8= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= -github.com/aquasecurity/trivy-aws v0.5.0 h1:6RJrw+QHeVn2MH7bI7bsVIiqRyhDCPvdEqkNn54Ui4I= -github.com/aquasecurity/trivy-aws v0.5.0/go.mod h1:dPx0xRElmFrVXBxeYqEAl5NejJ2kHb51ybFPzBMxWow= +github.com/aquasecurity/trivy-aws v0.7.0 h1:Ax3NcYghfdtPXVPsrHswSdkL6q9fL5kwuEgui+I5hLQ= +github.com/aquasecurity/trivy-aws v0.7.0/go.mod h1:ax3XNWIwKrypBXMzV7OKe5Qsz19OGb6WlACg0WCpzxw= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkvmyd5Lsg= @@ -378,138 +378,115 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.48.4 h1:HS2L7ynVhkcRrQRro9CLJZ/xLRb4UOzDEfPzgevZwXM= github.com/aws/aws-sdk-go v1.48.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4= -github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= -github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 h1:Sc82v7tDQ/vdU1WtuSyzZ1I7y/68j//HJ6uozND1IDs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= -github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= -github.com/aws/aws-sdk-go-v2/config v1.25.11 h1:RWzp7jhPRliIcACefGkKp03L0Yofmd2p8M25kbiyvno= -github.com/aws/aws-sdk-go-v2/config v1.25.11/go.mod h1:BVUs0chMdygHsQtvaMyEOpW2GIW+ubrxJLgIz/JU29s= -github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= -github.com/aws/aws-sdk-go-v2/credentials v1.16.9 h1:LQo3MUIOzod9JdUK+wxmSdgzLVYUbII3jXn3S/HJZU0= -github.com/aws/aws-sdk-go-v2/credentials v1.16.9/go.mod h1:R7mDuIJoCjH6TxGUc/cylE7Lp/o0bhKVoxdBThsjqCM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 h1:FZVFahMyZle6WcogZCOxo6D/lkDA2lqKIn4/ueUmVXw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9/go.mod h1:kjq7REMIkxdtcEC9/4BVXjOsNY5isz6jQbEgk6osRTU= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90 h1:mtJRt80k1oGw7QQPluAx8AZ6u16MyCA2di/lMhagZ7I= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.90/go.mod h1:lYwZTkeMQWPvNU+u7oYArdNhQ8EKiSGU76jVv0w2GH4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= +github.com/aws/aws-sdk-go-v2/config v1.26.3 h1:dKuc2jdp10y13dEEvPqWxqLoc0vF3Z9FC45MvuQSxOA= +github.com/aws/aws-sdk-go-v2/config v1.26.3/go.mod h1:Bxgi+DeeswYofcYO0XyGClwlrq3DZEXli0kLf4hkGA0= +github.com/aws/aws-sdk-go-v2/credentials v1.16.14 h1:mMDTwwYO9A0/JbOCOG7EOZHtYM+o7OfGWfu0toa23VE= +github.com/aws/aws-sdk-go-v2/credentials v1.16.14/go.mod h1:cniAUh3ErQPHtCQGPT5ouvSAQ0od8caTO9OOuufZOAE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 h1:I6lAa3wBWfCz/cKkOpAcumsETRkFAl70sWi8ItcMEsM= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11/go.mod h1:be1NIO30kJA23ORBLqPo1LttEM6tPNSEcjkd1eKzNW0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49Kk6+82spO3Tu5gSeQXRsxo56ePPQAvFiA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42/go.mod h1:oDfgXoBBmj+kXnqxDDnIDnC56QBosglKp8ftRCTxR+0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36/go.mod h1:rwr4WnmFi3RJO0M4dxbJtgi9BPLMpVBMX1nUte5ha9U= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 h1:wmGLw2i8ZTlHLw7a9ULGfQbuccw8uIiNr6sol5bFzc8= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6/go.mod h1:Q0Hq2X/NuL7z8b1Dww8rmOFl+jzusKEcyvkKspwdpyc= -github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1 h1:3fWAJsw4dLG4eYKHL9lygUWbE0lD+/gkqQC1zmmdAig= -github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.21.1/go.mod h1:thg9BfQH96QsZg9BMe30WS2av72ZAo7/lTfvUJqjK4s= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0 h1:rByriM7T0xvKy7eDiNUhFyVgnGupZ7DIifReKDzfk5E= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0/go.mod h1:OJmEdRP/gDTqY71Cc/eJ/anpvvGHNgf62FyNuah3X48= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.14.5 h1:pLmOgMUiwXOi3oKx2J3feVb9JGVgwJ78RYnOV9UR0BM= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.14.5/go.mod h1:4eIs6K6ag6ymoUMOFfjm9dmP9KbuKgC7K5eIqlIBsbY= -github.com/aws/aws-sdk-go-v2/service/athena v1.31.6 h1:EFaTu1rBt+KQglDeYRpP1PHot/6xlYzvouxm2aRmrG8= -github.com/aws/aws-sdk-go-v2/service/athena v1.31.6/go.mod h1:DHafyhR8x70ANJZ2RkJx8oeJsfEBqaGwZ591vlihVFQ= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.28.5 h1:Skw91L/Y1HkdYhCbdM0eiWOjrHKnpB/VNBHpg8e/8qo= -github.com/aws/aws-sdk-go-v2/service/cloudfront v1.28.5/go.mod h1:s+OI3YtisOCVORf07RWL2xjwrWgeYwvScNp7ZA2YGwI= -github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.29.1 h1:+aOn02ynxbYNcKynX+WrSCfeV9tHA/fNcEiTuGrUw9c= -github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.29.1/go.mod h1:0+M+TMNyLPNzvLwJz1Y+RSZO2VTvcSivlHf6hwYJj68= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.27.7 h1:qULF+ElcvjjSEO1+z5x+TmKE9d4yTej7PfpJQPVvexY= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.27.7/go.mod h1:1HKxVrj5wsKy/wb2v07vzTSd+YPV1sDsWxferwPK7PA= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.23.5 h1:/rXnxd9VGnTc5fLuSFKkWCy+kDP6CxXAIMvfJQEfx8U= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.23.5/go.mod h1:5v2ZNXCSwG73rx0k3sCuB1Ju8sbEbG0iUlxCA7D8sV8= -github.com/aws/aws-sdk-go-v2/service/codebuild v1.22.0 h1:S/R9Wt8ICyPFV9B3f2DhcBPPSr1gIbFd4iR6E/kkyos= -github.com/aws/aws-sdk-go-v2/service/codebuild v1.22.0/go.mod h1:a0ghZ8nA7qvVSQ69JRKUxIMqVFgXp7pEF8sGYx1ibO0= -github.com/aws/aws-sdk-go-v2/service/docdb v1.23.5 h1:UcFHE3wNm7hOsVolGFJyKGNiv+vzk4DiP3kgmG/2V7k= -github.com/aws/aws-sdk-go-v2/service/docdb v1.23.5/go.mod h1:2koFrNxz/jYwXiaAVw37p37KveilCeL+jKoeoecCMjk= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.5 h1:EeNQ3bDA6hlx3vifHf7LT/l9dh9w7D2XgCdaD11TRU4= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.5/go.mod h1:X3ThW5RPV19hi7bnQ0RMAiBjZbzxj4rZlj+qdctbMWY= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 h1:5oE2WzJE56/mVveuDZPJESKlg/00AaS2pY2QZcnxg4M= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10/go.mod h1:FHbKWQtRBYUz4vO5WBWjzMD2by126ny5y/1EoaWoLfI= +github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.26.7 h1:rLdKcienXrk+JFX1+DZg160ebG8lIF2nFvnEZL7dnII= +github.com/aws/aws-sdk-go-v2/service/accessanalyzer v1.26.7/go.mod h1:cwqaWBOZXu8pqEE1ZC4Sw2ycZLjwKrRP5tOAJFgCbYc= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.21.6 h1:ePPaOVn92r5n8Neecdpy93hDmR0PBH6H6b7VQCE5vKE= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.21.6/go.mod h1:P/zwE9uiC6eK/kL3CS60lxTTVC2zAvaS4iW31io41V4= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.18.6 h1:bCdxKjM8DpkNJXnOLVx+Hnav0eM4yJK8kof56VvIjMc= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.18.6/go.mod h1:zQ6tOYz7oGI7MbLRDBXfo63puDoTroVcVNXWfmRDA1E= +github.com/aws/aws-sdk-go-v2/service/athena v1.37.3 h1:qNLkDi/rOaauOuh33a4MNZjyfxvwIgC5qsDiHPvjDk0= +github.com/aws/aws-sdk-go-v2/service/athena v1.37.3/go.mod h1:MlpC6swcjh1Il80u6XoeY2BTHIZRZWvoXOfaq3rfh8I= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.5 h1:synDXYpTr5FA80g8twNr49Dd7iAKnxerp93l/kNm/cQ= +github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.5/go.mod h1:Dil6nVeCPyPc1gF5EeCrVUTtXexn80MpfqhgSp/Zb64= +github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.35.6 h1:Yc+avPLGARzp4A9Oi9VRxvlcGqI+0MYIg4tPSupKv2U= +github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.35.6/go.mod h1:zrqdG1b+4AGoTwTMVFzvzY7ARB3GPo4gKRuK8WPEo8w= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.32.2 h1:vQfCIHSDouEvbE4EuDrlCGKcrtABEqF3cMt61nGEV4g= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.32.2/go.mod h1:3ToKMEhVj+Q+HzZ8Hqin6LdAKtsi3zVXVNUPpQMd+Xk= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.1 h1:ZMgx58Tqyr8kTSR9zLzX+W933ujDYleOtFedvn0xHg8= +github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.1/go.mod h1:4Oeb7n2r/ApBIHphQkprve380p/RpPWBotumd44EDGg= +github.com/aws/aws-sdk-go-v2/service/codebuild v1.26.5 h1:EPnlDd4V2EXywlOPAw/pMUW4PHUgSulKm4zXFU6bixE= +github.com/aws/aws-sdk-go-v2/service/codebuild v1.26.5/go.mod h1:G2JUWf01sbb5/A8qGcM4dqy4nbl4y4IGWmaCDWAvA2Y= +github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6 h1:OBNxHKQMlsQplVc+4CeNLTsknaUnMTMnMdsvUr1yqhA= +github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6/go.mod h1:8d1RpdlgxFU6VO2aWru1ckR0Vsm4EgqCZgOamw5OHpw= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 h1:XKO0BswTDeZMLDBd/b5pCEZGttNXrzRUVtFvp2Ak/Vo= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8/go.mod h1:N5tqZcYMM0N1PN7UQYJNWuGyO886OfnMhf/3MAbqMcI= github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 h1:iUgGXA8fg41B4Of0F+BS766SRQ7c8rr5jtka8RgaocQ= github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1/go.mod h1:9n0SC5yHomD8IjsR37+/txpdfNdpGSgV1RzmsTHrbWg= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0 h1:ZozGfw2s79TxoqisrkALGCpXokhMkfZRQxPkd8+MK+Y= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.134.0/go.mod h1:xYJZQIo/YZxEbeBxUYRQJTCJ924EuKtDfrhVx76yzOE= -github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1 h1:zqXEIhuR7RcHob2gxB/Xf1X4XuMS0vapn7xr+wCPrpg= -github.com/aws/aws-sdk-go-v2/service/ecr v1.24.1/go.mod h1:+rWYJfms9p+D/wUN599tx3FtWvxoXCP25b8Porlrxcc= -github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1 h1:bOS7hAfvd8+glVAG88WnvRITe5N1vopGFHh10ORe/BI= -github.com/aws/aws-sdk-go-v2/service/ecs v1.30.1/go.mod h1:cxbA26Kf4UlTb40f5FON22ZPNMyEVmMS82KUJZC1E1w= -github.com/aws/aws-sdk-go-v2/service/efs v1.21.6 h1:Hk/hIxTQ2OcLqG/rThJSwawnXwNftGUyYMNq3Dmrl0E= -github.com/aws/aws-sdk-go-v2/service/efs v1.21.6/go.mod h1:cws4IYv3vkLS4pZzStRQH6AcBISp5JlI+dgBA/seDbA= -github.com/aws/aws-sdk-go-v2/service/eks v1.29.5 h1:6eSpTHOsDixcFIvPdiAAVdyCru3k2jIVRPdIQfGzfc8= -github.com/aws/aws-sdk-go-v2/service/eks v1.29.5/go.mod h1:TwqefcyPlF31NTF+fH34tJ2VwMMR6c74IbiiUgA6kVY= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.29.3 h1:VT1Yq9MPp/sQhrfeHkC0SQf8mKGrb0epAYTExGipChg= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.29.3/go.mod h1:WTAOgZesN8YgaTo0aNJPB4ufoN/QpxAHeC2HRxKay+M= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.21.3 h1:CAWMcMnRYCBaeMnycTwZs+0BcuepIMfyP3F0r1VfgPc= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.21.3/go.mod h1:CbJHS0jJJNd2dZOakkG5TBbT8OHz+T0UBzR1ClIdezI= -github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.20.6 h1:5n5h2hr9zdB9RdbO0vaWKur97g7153I1/RmrwZC9IcA= -github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.20.6/go.mod h1:L9XcF8QdOpGUDPccs9VZPlNhrpfPEKFDl/vb3C+iZbs= -github.com/aws/aws-sdk-go-v2/service/emr v1.28.7 h1:rwQcpb3VcILVKL2G/ZAbfgSa0+dD3zw8zmSdrI2vbc0= -github.com/aws/aws-sdk-go-v2/service/emr v1.28.7/go.mod h1:NjDlvuvjuHi3uh3r4mXnSvn0UHQACj7i5y8zwIyHs6w= -github.com/aws/aws-sdk-go-v2/service/iam v1.22.5 h1:qGv+oW4uV1T3kbE9uSYEfdZbo38OqxgRxxfStfDr4BU= -github.com/aws/aws-sdk-go-v2/service/iam v1.22.5/go.mod h1:8lyPrjQczmx72ac9s82zTjf9xLqs7uuFMG9TVEZ07XU= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15/go.mod h1:26SQUPcTNgV1Tapwdt4a1rOsYRsnBsJHLMPoxK2b0d8= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.142.0 h1:VrFC1uEZjX4ghkm/et8ATVGb1mT75Iv8aPKPjUE+F8A= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.142.0/go.mod h1:qjhtI9zjpUHRc6khtrIM9fb48+ii6+UikL3/b+MKYn0= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6 h1:cT7h+GWP2k0hJSsPmppKgxl4C9R6gCC5/oF4oHnmpK4= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6/go.mod h1:AOHmGMoPtSY9Zm2zBuwUJQBisIvYAZeA1n7b6f4e880= +github.com/aws/aws-sdk-go-v2/service/ecs v1.35.6 h1:Sc2mLjyA1R8z2l705AN7Wr7QOlnUxVnGPJeDIVyUSrs= +github.com/aws/aws-sdk-go-v2/service/ecs v1.35.6/go.mod h1:LzHcyOEvaLjbc5e+fP/KmPWBr+h/Ef+EHvnf1Pzo368= +github.com/aws/aws-sdk-go-v2/service/efs v1.26.5 h1:N1ezZV2yy7NV2w/bA4s4I/+0n2xpL4DzlmroEg5qFsg= +github.com/aws/aws-sdk-go-v2/service/efs v1.26.5/go.mod h1:PJHqaboMcF/eLy1F/Y9hyls4CQGP5+T5f0iRq6CPXu4= +github.com/aws/aws-sdk-go-v2/service/eks v1.37.0 h1:tCIkZ/ZdJMGZ1MOwdcioYhOUkkD4F58KFvQTgR3ZIlc= +github.com/aws/aws-sdk-go-v2/service/eks v1.37.0/go.mod h1:L1uv3UgQlAkdM9v0gpec7nnfUiQkCnGMjBE7MJArfWQ= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.34.6 h1:Y/5eE9Sc+OBID9pZ4EVFzyQviv1d1RbqB17HRur9ySg= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.34.6/go.mod h1:iPx2i26hgUULkNh1Jk4QzYzzQKd2nXl/rD9Fm5hQ2uk= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.26.6 h1:twI2uRmpbm0KBog3Ay61IqOtNp6+QxKfSA78zftME/o= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.26.6/go.mod h1:Tpt4kC8x1HfYuh2rG/6yXZrxjABETERrUl9IdA/IS98= +github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.25.0 h1:LPEsYRsC6r3edPHO8KlZJNW0xxyfLHMXJ466MdHuBbQ= +github.com/aws/aws-sdk-go-v2/service/elasticsearchservice v1.25.0/go.mod h1:CAXUsQvYQVzsXO36npqK3aUlxx2xMSM1Dun3O9jnaEE= +github.com/aws/aws-sdk-go-v2/service/emr v1.36.0 h1:FdeZ7AYOvyL09KH250Ncz4LF4SB1Vo9l7KZzn/LIrgQ= +github.com/aws/aws-sdk-go-v2/service/emr v1.36.0/go.mod h1:Drh6y2qLaw/wnDKTIcdqM2m358MIRXsZ2Bj2tjhVLq0= +github.com/aws/aws-sdk-go-v2/service/iam v1.28.7 h1:FKPRDYZOO0Eur19vWUL1B40Op0j89KQj3kARjrszMK8= +github.com/aws/aws-sdk-go-v2/service/iam v1.28.7/go.mod h1:YzMYyQ7S4twfYzLjwP24G1RAxypozVZeNaG1r2jxRms= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 h1:skaFGzv+3kA+v2BPKhuekeb1Hbb105+44r8ASC+q5SE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38/go.mod h1:epIZoRSSbRIwLPJU5F+OldHhwZPBdpDeQkRdCeY3+00= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35 h1:UKjpIDLVF90RfV88XurdduMoTxPqtGHZMIDYZQM7RO4= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.35/go.mod h1:B3dUg0V6eJesUTi+m27NUkj7n8hdDKYUpxj8f4+TqaQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 h1:L0ai8WICYHozIKK+OtPzVJBugL7culcuM4E4JOpIEm8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10/go.mod h1:byqfyxJBshFk0fF9YmK0M0ugIO8OWjzH2T3bPG4eGuA= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.8.11 h1:e9AVb17H4x5FTE5KWIP5M1Du+9M86pS+Hw0lBUdN8EY= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.8.11/go.mod h1:B90ZQJa36xo0ph9HsoteI1+r8owgQH/U1QNfqZQkj1Q= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 h1:9ulSU5ClouoPIYhDQdg9tpl83d5Yb91PXTKK+17q+ow= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6/go.mod h1:lnc2taBsR9nTlz9meD+lhFZZ9EWY712QHrRflWpTcOA= -github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6 h1:DyJVI9uQB+mO4IuKEE4AloqOvo9XFg7olhZkwWZJ7wc= -github.com/aws/aws-sdk-go-v2/service/kafka v1.22.6/go.mod h1:uXijjFwDzFVyGUwtXqqEPV/SxxLPrh0LqJxe64Csr7E= -github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.5 h1:naSZmQiFjoTLxNjfDy/KgEnWdG3odkR6gIEgTx21YOM= -github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.5/go.mod h1:0h3hOcyFXyjvI3wGt8C8vk2+II9XxHwFM7zH2KvLHmA= -github.com/aws/aws-sdk-go-v2/service/kms v1.24.5 h1:VNEw+EdYDUdkICYAVQ6n9WoAq8ZuZr7dXKjyaOw94/Q= -github.com/aws/aws-sdk-go-v2/service/kms v1.24.5/go.mod h1:NZEhPgq+vvmM6L9w+xl78Vf7YxqUcpVULqFdrUhHg8I= -github.com/aws/aws-sdk-go-v2/service/lambda v1.39.5 h1:uMvxJFS92hNW6BRX0Ou+5zb9DskgrJQHZ+5yT8FXK5Y= -github.com/aws/aws-sdk-go-v2/service/lambda v1.39.5/go.mod h1:ByLHcf0zbHpyLTOy1iPVRPJWmAUPCiJv5k81dt52ID8= -github.com/aws/aws-sdk-go-v2/service/mq v1.16.5 h1:xlziZnBjo10pGC+Uol5j8JNSzQksYOgHzAmF5sKnE/s= -github.com/aws/aws-sdk-go-v2/service/mq v1.16.5/go.mod h1:kxETQ9R0dWsvWyL+5Vp/pNsEYejv76B+RvHr3S0jjhI= -github.com/aws/aws-sdk-go-v2/service/neptune v1.21.5 h1:qPTVGmBtdPGmXVZ914ZthB2UmIBw9UGMOw6OaSuv8QE= -github.com/aws/aws-sdk-go-v2/service/neptune v1.21.5/go.mod h1:uH/l4gGqbqoS1FQ/gmkt5TNM3LAeu+H20/tcuhU6j80= -github.com/aws/aws-sdk-go-v2/service/rds v1.54.0 h1:FmExQnV6PXPAwP2DT3nXlWyKtCJ30gCEQIu4MUOuESo= -github.com/aws/aws-sdk-go-v2/service/rds v1.54.0/go.mod h1:UNv1vk1fU1NJefzteykVpVLA88w4WxB05g3vp2kQhYM= -github.com/aws/aws-sdk-go-v2/service/redshift v1.29.5 h1:ufl4QI+6Vuxg6E8UOFVy+CeCtXS+gBMb00oTh2qSPco= -github.com/aws/aws-sdk-go-v2/service/redshift v1.29.5/go.mod h1:U8V+thdAH44/2weiprIA0JyDWa2XBov58TtdjCTTpc8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 h1:Ll5/YVCOzRB+gxPqs2uD0R7/MyATC0w85626glSKmp4= -github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2/go.mod h1:Zjfqt7KhQK+PO1bbOsFNzKgaq7TcxzmEoDWN8lM0qzQ= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.21.3 h1:H6ZipEknzu7RkJW3w2PP75zd8XOdR35AEY5D57YrJtA= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.21.3/go.mod h1:5W2cYXDPabUmwULErlC92ffLhtTuyv4ai+5HhdbhfNo= -github.com/aws/aws-sdk-go-v2/service/sns v1.21.5 h1:KI6xffjUcP3KgpJEtKefQL8B7AXFqyAXkVw8SyvT/o8= -github.com/aws/aws-sdk-go-v2/service/sns v1.21.5/go.mod h1:eEjNDG7Y1BH7Ci9qKVH2L02se84z5GPCqXKcqEUpnXg= -github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5 h1:RyDpTOMEJO6ycxw1vU/6s0KLFaH3M0z/z9gXHSndPTk= -github.com/aws/aws-sdk-go-v2/service/sqs v1.24.5/go.mod h1:RZBu4jmYz3Nikzpu/VuVvRnTEJ5a+kf36WT2fcl5Q+Q= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 h1:xJPydhNm0Hiqct5TVKEuHG7weC0+sOs4MUnd7A5n5F4= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.2/go.mod h1:zxk6y1X2KXThESWMS5CrKRvISD8mbIMab6nZrCGxDG0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 h1:8dU9zqA77C5egbU6yd4hFLaiIdPv3rU+6cp7sz5FjCU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2/go.mod h1:7Lt5mjQ8x5rVdKqg+sKKDeuwoszDJIIPmkd8BVsEdS0= -github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 h1:KOxnQeWy5sXyS37fdKEvAsGHOr9fa/qvwxfJurR/BzE= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI= +github.com/aws/aws-sdk-go-v2/service/kafka v1.28.5 h1:yCkyZDGahaCaAkdpVx8Te05t6eW2FarBLunVC8S23nU= +github.com/aws/aws-sdk-go-v2/service/kafka v1.28.5/go.mod h1:/KmX+vXMPJGAB56reo95tnsXa6QPNx6qli4L1AmYb7E= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.24.6 h1:FO/aIHk86VePDUh/3Q/A5pnvu45miO1GZB8rIq2BUlA= +github.com/aws/aws-sdk-go-v2/service/kinesis v1.24.6/go.mod h1:Sj7qc+P/GOGOPMDn8+B7Cs+WPq1Gk+R6CXRXVhZtWcA= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/lambda v1.49.6 h1:w8lI9zlVwRTL9f4KB9fRThddhRivv+EQQzv2nU8JDQo= +github.com/aws/aws-sdk-go-v2/service/lambda v1.49.6/go.mod h1:0V5z1X/8NA9eQ5cZSz5ZaHU8xA/hId2ZAlsHeO7Jrdk= +github.com/aws/aws-sdk-go-v2/service/mq v1.20.6 h1:n86T5yw0kS6a5nbpkEpDzLPCBXXb35lx3iDkmQWlizA= +github.com/aws/aws-sdk-go-v2/service/mq v1.20.6/go.mod h1:phfKOOpMQhlBv2KE8gF17P82zLcSedA9b7fMSGTLBdQ= +github.com/aws/aws-sdk-go-v2/service/neptune v1.28.1 h1:e+DGEARs5GfHuzDwztENiomdLa0sjs55ub27juoFdt0= +github.com/aws/aws-sdk-go-v2/service/neptune v1.28.1/go.mod h1:jHUFaho5cVpplTDO6bctuLbvnm8F+Xd27RGIJvVTlYI= +github.com/aws/aws-sdk-go-v2/service/rds v1.66.1 h1:TafjIpDW/+l7s+f3EIONaFsNvNfwVH21NkWYrE0hbEE= +github.com/aws/aws-sdk-go-v2/service/rds v1.66.1/go.mod h1:MYzRMSdY70kcS8AFg0aHmk/xj6VAe0UfaCCoLrBWPow= +github.com/aws/aws-sdk-go-v2/service/redshift v1.39.7 h1:k4WaqQ7LHSGrSftCRXTRLv7WaozXu+fZ1jdisQSR2eU= +github.com/aws/aws-sdk-go-v2/service/redshift v1.39.7/go.mod h1:8hU0Ax6q6QA+jrMcWTE0A4YH594MQoWP3EzGO3GH5Dw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 h1:PJTdBMsyvra6FtED7JZtDpQrIAflYDHFoZAu/sKYkwU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 h1:dPCRgAL4WD9tSMaDglRNGOiAtSTjkwNiUW5GDpWFfHA= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0/go.mod h1:4Ae1NCLK6ghmjzd45Tc33GgCKhUWD2ORAlULtMO1Cbs= +github.com/aws/aws-sdk-go-v2/service/sns v1.26.6 h1:w2YwF8889ardGU3Y0qZbJ4Zzh+Q/QqKZ4kwkK7JFvnI= +github.com/aws/aws-sdk-go-v2/service/sns v1.26.6/go.mod h1:IrcbquqMupzndZ20BXxDxjM7XenTRhbwBOetk4+Z5oc= +github.com/aws/aws-sdk-go-v2/service/sqs v1.29.6 h1:UdbDTllc7cmusTTMy1dcTrYKRl4utDEsmKh9ZjvhJCc= +github.com/aws/aws-sdk-go-v2/service/sqs v1.29.6/go.mod h1:mCUv04gd/7g+/HNzDB4X6dzJuygji0ckvB3Lg/TdG5Y= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 h1:Yf2MIo9x+0tyv76GljxzqA3WtC5mw7NmazD2chwjxE4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= -github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1 h1:+gN/oR6jT53ggl+jd/7wO4A7u9r1GLCpMiRiatD79WQ= -github.com/aws/aws-sdk-go-v2/service/workspaces v1.31.1/go.mod h1:56TIMTOeThR8Ep+O82yxpTuGzCOzZuo3XmsJXxukgUo= +github.com/aws/aws-sdk-go-v2/service/workspaces v1.35.6 h1:RrpjQ5xJN/AW0PCO7EGhhVsKq7BeNqkx5+h6p3QOeTU= +github.com/aws/aws-sdk-go-v2/service/workspaces v1.35.6/go.mod h1:vkYsJdF9sZl/o1eoK8tSSjzAT+R87QjswOGSTZfyO0Y= github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= From ae134a9b3884c5fedaad1400863374e2c8c6897e Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:00:33 +0600 Subject: [PATCH 083/108] fix(secret): find aws secrets ending with a comma or dot (#5921) --- pkg/fanal/secret/builtin-rules.go | 2 +- pkg/fanal/secret/scanner_test.go | 8 ++++---- pkg/fanal/secret/testdata/aws-secrets.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index 94da8a3b722a..e93640fcebea 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -76,7 +76,7 @@ const ( quote = `["']?` connect = `\s*(:|=>|=)?\s*` startSecret = `(^|\s+)` - endSecret = `(\s+|$)` + endSecret = `[.,]?(\s+|$)` aws = `aws_?` ) diff --git a/pkg/fanal/secret/scanner_test.go b/pkg/fanal/secret/scanner_test.go index 7f11c6731ac5..c6567cc28b2d 100644 --- a/pkg/fanal/secret/scanner_test.go +++ b/pkg/fanal/secret/scanner_test.go @@ -429,7 +429,7 @@ func TestSecretScanner(t *testing.T) { Severity: "CRITICAL", StartLine: 5, EndLine: 5, - Match: `aws_sec_key "****************************************"`, + Match: ` "created_by": "ENV aws_sec_key "****************************************",`, Code: types.Code{ Lines: []types.Line{ { @@ -444,8 +444,8 @@ func TestSecretScanner(t *testing.T) { }, { Number: 5, - Content: "aws_sec_key \"****************************************\"", - Highlighted: "aws_sec_key \"****************************************\"", + Content: " \"created_by\": \"ENV aws_sec_key \"****************************************\",", + Highlighted: " \"created_by\": \"ENV aws_sec_key \"****************************************\",", IsCause: true, FirstCause: true, LastCause: true, @@ -662,7 +662,7 @@ func TestSecretScanner(t *testing.T) { inputFilePath: filepath.Join("testdata", "aws-secrets.txt"), want: types.Secret{ FilePath: filepath.Join("testdata", "aws-secrets.txt"), - Findings: []types.SecretFinding{wantFinding5, wantFinding9, wantFinding10}, + Findings: []types.SecretFinding{wantFinding5, wantFinding10, wantFinding9}, }, }, { diff --git a/pkg/fanal/secret/testdata/aws-secrets.txt b/pkg/fanal/secret/testdata/aws-secrets.txt index 7739ce9bfb79..737708284303 100644 --- a/pkg/fanal/secret/testdata/aws-secrets.txt +++ b/pkg/fanal/secret/testdata/aws-secrets.txt @@ -2,4 +2,4 @@ AWS_ACCESS_KEY_ID=AKIA0123456789ABCDEF "aws_account_ID":'1234-5678-9123' AWS_example=AKIAIOSFODNN7EXAMPLE -aws_sec_key "KEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYK" \ No newline at end of file + "created_by": "ENV aws_sec_key "KEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYKEYK", \ No newline at end of file From a2b654945a78a4db31274798c30c0201cbe05052 Mon Sep 17 00:00:00 2001 From: Laurent Commarieu Date: Fri, 12 Jan 2024 05:36:55 +0100 Subject: [PATCH 084/108] docs(misconf): multiple ignores in comment (#5926) --- docs/docs/configuration/filtering.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/docs/configuration/filtering.md b/docs/docs/configuration/filtering.md index 2ca0c2d1adf3..1f40d160c9cb 100644 --- a/docs/docs/configuration/filtering.md +++ b/docs/docs/configuration/filtering.md @@ -496,7 +496,7 @@ Some configuration file formats (e.g. Terraform) support inline comments. In cases where trivy can detect comments of a specific format immediately adjacent to resource definitions, it is possible to filter/ignore findings from a single point of resource definition (in contrast to `.trivyignore`, which has a directory-wide scope on all of the files scanned). -The format for these comments is `trivy:ignore:` immediately following the format-specific line-comment token. +The format for these comments is `trivy:ignore:` immediately following the format-specific line-comment token. You can add multiple ignores on the same comment line. For example, to filter a Vulnerability ID "AVD-GCP-0051" in a Terraform HCL file: @@ -508,4 +508,14 @@ resource "google_container_cluster" "one_off_test" { } ``` +For example, to filter vulnerabilities "AVD-GCP-0051" and "AVD-GCP-0053" in a Terraform HCL file: + +```terraform +#trivy:ignore:AVD-GCP-0051 trivy:ignore:AVD-GCP-0053 +resource "google_container_cluster" "one_off_test" { + name = var.cluster_name + location = var.region +} +``` + [^1]: license name is used as id for `.trivyignore.yaml` files From b1b4734f55da82426cb9b8fd4605184a342e6989 Mon Sep 17 00:00:00 2001 From: Fatih Tokus Date: Mon, 15 Jan 2024 06:13:27 +0000 Subject: [PATCH 085/108] docs: Fix documentation of ecosystem (#5940) --- docs/ecosystem/{miscellaneous.md => reporting.md} | 2 +- mkdocs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/ecosystem/{miscellaneous.md => reporting.md} (98%) diff --git a/docs/ecosystem/miscellaneous.md b/docs/ecosystem/reporting.md similarity index 98% rename from docs/ecosystem/miscellaneous.md rename to docs/ecosystem/reporting.md index cc8d9668e783..847205a00c34 100644 --- a/docs/ecosystem/miscellaneous.md +++ b/docs/ecosystem/reporting.md @@ -1,4 +1,4 @@ -# Miscellaneous +# Reporting ## SonarQube (Community) A Trivy plugin that converts JSON report to SonarQube [generic issues format](https://docs.sonarqube.org/9.6/analyzing-source-code/importing-external-issues/generic-issue-import-format/). diff --git a/mkdocs.yml b/mkdocs.yml index 59ad99752b37..4e7bf1ee633a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -176,7 +176,7 @@ nav: - CI/CD: ecosystem/cicd.md - IDE and Dev tools: ecosystem/ide.md - Production and Clouds: ecosystem/prod.md - - Security Management: ecosystem/security.md + - Reporting: ecosystem/reporting.md - Contributing: - How to contribute: - Issues: community/contribute/issue.md From a3fac90b473aeafc3f8011ea6e7315f3ce18c56e Mon Sep 17 00:00:00 2001 From: chenk Date: Mon, 15 Jan 2024 08:14:57 +0200 Subject: [PATCH 086/108] fix: ignore no init containers (#5939) Signed-off-by: chenk --- go.mod | 26 ++++++++++++++------------ go.sum | 59 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index 209f03ee435f..85040a2f00ba 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-iac v0.7.1 github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 - github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 + github.com/aquasecurity/trivy-kubernetes v0.6.1 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.24.1 github.com/aws/aws-sdk-go-v2/config v1.26.3 @@ -112,8 +112,8 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.28.4 - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 + k8s.io/api v0.29.0 + k8s.io/utils v0.0.0-20231127182322-b307cd553661 modernc.org/sqlite v1.28.0 ) @@ -158,7 +158,7 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.48.4 // indirect + github.com/aws/aws-sdk-go v1.49.16 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect @@ -234,7 +234,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect @@ -275,6 +275,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/mux v1.8.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -328,6 +329,7 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/runc v1.1.5 // indirect @@ -398,14 +400,14 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect helm.sh/helm/v3 v3.13.0 // indirect k8s.io/apiextensions-apiserver v0.28.2 // indirect - k8s.io/apimachinery v0.28.4 // indirect + k8s.io/apimachinery v0.29.0 // indirect k8s.io/apiserver v0.28.2 // indirect - k8s.io/cli-runtime v0.28.4 // indirect - k8s.io/client-go v0.28.4 // indirect - k8s.io/component-base v0.28.3 // indirect + k8s.io/cli-runtime v0.29.0 // indirect + k8s.io/client-go v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect - k8s.io/kubectl v0.28.3 // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/kubectl v0.29.0 // indirect lukechampine.com/uint128 v1.2.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect @@ -419,7 +421,7 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index b023a067265e..32284820c213 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkv github.com/aquasecurity/trivy-iac v0.7.1/go.mod h1:SK5XaVwGh5M17QV81139BSPXNlm3bIGp+YmAYs7slRw= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= -github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091 h1:OTJMSbvKQYxbQ2NQ8Nht2NSL1bL36YfBCrlsGGxHPlI= -github.com/aquasecurity/trivy-kubernetes v0.5.9-0.20231203080602-50a069120091/go.mod h1:Yh+tmpPtbqVWYONrAuapImHfD1ghZgnZHLlMBA6Ukfg= +github.com/aquasecurity/trivy-kubernetes v0.6.1 h1:Mj6wP3YhmDxqSbS0o8XrLgXMvoLAkf+CDBhRSIdhbIg= +github.com/aquasecurity/trivy-kubernetes v0.6.1/go.mod h1:9CxcIVIE6wvQWvxx4MIKf6nY1w+zAFIvutl8ikoXSgo= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842/go.mod h1:BmEeSFgmBjo3avCli71736sy0veGcSUzGATupp1MCgA= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -375,8 +375,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.48.4 h1:HS2L7ynVhkcRrQRro9CLJZ/xLRb4UOzDEfPzgevZwXM= -github.com/aws/aws-sdk-go v1.48.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.49.16 h1:KAQwhLg296hfffRdh+itA9p7Nx/3cXS/qOa3uF9ssig= +github.com/aws/aws-sdk-go v1.49.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4= github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= @@ -762,8 +762,8 @@ github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcej github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= -github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -1111,6 +1111,8 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -1412,6 +1414,7 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1432,15 +1435,15 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= -github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/open-policy-agent/opa v0.60.0 h1:ZPoPt4yeNs5UXCpd/P/btpSyR8CR0wfhVoh9BOwgJNs= github.com/open-policy-agent/opa v0.60.0/go.mod h1:aD5IK6AiLNYBjNXn7E02++yC8l4Z+bRDvgM6Ss0bBzA= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -2533,32 +2536,32 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= -k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= +k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= +k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= -k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= +k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= +k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI= k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E= -k8s.io/cli-runtime v0.28.4 h1:IW3aqSNFXiGDllJF4KVYM90YX4cXPGxuCxCVqCD8X+Q= -k8s.io/cli-runtime v0.28.4/go.mod h1:MLGRB7LWTIYyYR3d/DOgtUC8ihsAPA3P8K8FDNIqJ0k= +k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= +k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= -k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= +k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= +k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= -k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= +k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= +k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -2569,14 +2572,14 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/kubectl v0.28.3 h1:H1Peu1O3EbN9zHkJCcvhiJ4NUj6lb88sGPO5wrWIM6k= -k8s.io/kubectl v0.28.3/go.mod h1:RDAudrth/2wQ3Sg46fbKKl4/g+XImzvbsSRZdP2RiyE= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI= +k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= +k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= @@ -2620,8 +2623,8 @@ sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From c75143f5e82b3cd5c66c94241e51423bce26b936 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:57:46 +0600 Subject: [PATCH 087/108] fix(sbom): use `group` field for pom.xml and nodejs files for CycloneDX reports (#5922) --- .../testdata/pom-cyclonedx.json.golden | 6 +- pkg/sbom/cyclonedx/marshal.go | 8 ++- pkg/sbom/cyclonedx/marshal_test.go | 64 +++++++++++++++++++ pkg/sbom/cyclonedx/testdata/happy/bom.json | 7 +- pkg/sbom/cyclonedx/unmarshal.go | 15 ++++- pkg/sbom/cyclonedx/unmarshal_test.go | 11 ++-- 6 files changed, 96 insertions(+), 15 deletions(-) diff --git a/integration/testdata/pom-cyclonedx.json.golden b/integration/testdata/pom-cyclonedx.json.golden index ac245de144ce..a77c75eb1f65 100644 --- a/integration/testdata/pom-cyclonedx.json.golden +++ b/integration/testdata/pom-cyclonedx.json.golden @@ -44,7 +44,8 @@ { "bom-ref": "pkg:maven/com.example/log4shell@1.0-SNAPSHOT", "type": "library", - "name": "com.example:log4shell", + "group": "com.example", + "name": "log4shell", "version": "1.0-SNAPSHOT", "purl": "pkg:maven/com.example/log4shell@1.0-SNAPSHOT", "properties": [ @@ -61,7 +62,8 @@ { "bom-ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1", "type": "library", - "name": "com.fasterxml.jackson.core:jackson-databind", + "group": "com.fasterxml.jackson.core", + "name": "jackson-databind", "version": "2.9.1", "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1", "properties": [ diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index 59564dddd6f8..287b4fee40cc 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -7,6 +7,7 @@ import ( "strings" cdx "github.com/CycloneDX/cyclonedx-go" + "github.com/package-url/packageurl-go" "github.com/samber/lo" "golang.org/x/xerrors" @@ -323,8 +324,11 @@ func pkgComponent(pkg Package) (*core.Component, error) { // e.g. local Go packages if pu := pkg.Identifier.PURL; pu != nil { version = pu.Version - // use `group` field for GroupID and `name` for ArtifactID for jar files - if pkg.Type == ftypes.Jar { + // Use `group` field for GroupID and `name` for ArtifactID for java files + // https://github.com/aquasecurity/trivy/issues/4675 + // Use `group` field for npm scopes + // https://github.com/aquasecurity/trivy/issues/5908 + if pu.Type == packageurl.TypeMaven || pu.Type == packageurl.TypeNPM { name = pu.Name group = pu.Namespace } diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 5a3022c91b0c..9d1f2d33aab0 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -1224,6 +1224,26 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, }, + { + Target: "yarn.lock", + Class: types.ClassLangPkg, + Type: ftypes.Yarn, + Packages: []ftypes.Package{ + { + ID: "@babel/helper-string-parser@7.23.4", + Name: "@babel/helper-string-parser", + Version: "7.23.4", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeNPM, + Namespace: "@babel", + Name: "helper-string-parser", + Version: "7.23.4", + }, + }, + }, + }, + }, }, }, want: &cdx.BOM{ @@ -1270,6 +1290,21 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, }, + { + BOMRef: "3ff14136-e09f-4df9-80ea-000000000004", + Type: cdx.ComponentTypeApplication, + Name: "yarn.lock", + Properties: &[]cdx.Property{ + { + Name: "aquasecurity:trivy:Class", + Value: "lang-pkgs", + }, + { + Name: "aquasecurity:trivy:Type", + Value: "yarn", + }, + }, + }, { BOMRef: "pkg:gem/actioncable@6.1.4.1", Type: "library", @@ -1301,6 +1336,24 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, }, + { + BOMRef: "pkg:npm/%40babel/helper-string-parser@7.23.4", + Type: "library", + Name: "helper-string-parser", + Group: "@babel", + Version: "7.23.4", + PackageURL: "pkg:npm/%40babel/helper-string-parser@7.23.4", + Properties: &[]cdx.Property{ + { + Name: "aquasecurity:trivy:PkgID", + Value: "@babel/helper-string-parser@7.23.4", + }, + { + Name: "aquasecurity:trivy:PkgType", + Value: "yarn", + }, + }, + }, }, Vulnerabilities: &[]cdx.Vulnerability{}, Dependencies: &[]cdx.Dependency{ @@ -1308,6 +1361,7 @@ func TestMarshaler_Marshal(t *testing.T) { Ref: "3ff14136-e09f-4df9-80ea-000000000002", Dependencies: &[]string{ "3ff14136-e09f-4df9-80ea-000000000003", + "3ff14136-e09f-4df9-80ea-000000000004", "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", }, }, @@ -1317,6 +1371,12 @@ func TestMarshaler_Marshal(t *testing.T) { "pkg:gem/actioncable@6.1.4.1", }, }, + { + Ref: "3ff14136-e09f-4df9-80ea-000000000004", + Dependencies: &[]string{ + "pkg:npm/%40babel/helper-string-parser@7.23.4", + }, + }, { Ref: "pkg:gem/actioncable@6.1.4.1", Dependencies: lo.ToPtr([]string{}), @@ -1325,6 +1385,10 @@ func TestMarshaler_Marshal(t *testing.T) { Ref: "pkg:maven/org.springframework/spring-web@5.3.22?file_path=spring-web-5.3.22.jar", Dependencies: lo.ToPtr([]string{}), }, + { + Ref: "pkg:npm/%40babel/helper-string-parser@7.23.4", + Dependencies: lo.ToPtr([]string{}), + }, }, }, }, diff --git a/pkg/sbom/cyclonedx/testdata/happy/bom.json b/pkg/sbom/cyclonedx/testdata/happy/bom.json index 924daef7f405..ada1488b8cbc 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/bom.json @@ -121,8 +121,9 @@ ] }, { - "bom-ref": "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", + "bom-ref": "pkg:npm/@example/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", "type": "library", + "group": "@example", "name": "bootstrap", "version": "5.0.2", "licenses": [ @@ -132,7 +133,7 @@ } } ], - "purl": "pkg:npm/bootstrap@5.0.2", + "purl": "pkg:npm/@example/bootstrap@5.0.2", "properties": [ { "name": "aquasecurity:trivy:FilePath", @@ -265,7 +266,7 @@ "60e9f57b-d4a6-4f71-ad14-0893ac609182", "pkg:maven/org.codehaus.mojo/child-project@1.0?file_path=app%2Fmaven%2Ftarget%2Fchild-project-1.0.jar", "pkg:maven/com.example/example@0.0.1", - "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", + "pkg:npm/@example/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", "100925ff-7c0a-470f-a725-8fb973b40e7b", "1a111e6b-a682-470e-8b0e-aaa49d93cd39" ] diff --git a/pkg/sbom/cyclonedx/unmarshal.go b/pkg/sbom/cyclonedx/unmarshal.go index 96fa09364640..921c3455d121 100644 --- a/pkg/sbom/cyclonedx/unmarshal.go +++ b/pkg/sbom/cyclonedx/unmarshal.go @@ -419,10 +419,11 @@ func toTrivyCdxComponent(component cdx.Component) ftypes.Component { } func packageName(typ, pkgNameFromPurl string, component cdx.Component) string { - if typ == packageurl.TypeMaven { - // Jar uses `Group` field for `GroupID` + if typ == packageurl.TypeMaven || typ == packageurl.TypeNPM { + // Maven uses `Group` field for `GroupID` + // Npm uses `Group` field for `Scope` if component.Group != "" { - return fmt.Sprintf("%s:%s", component.Group, component.Name) + return fmt.Sprintf("%s%s%s", component.Group, packageNameSeparator(typ), component.Name) } else { // use name derived from purl if `Group` doesn't exist return pkgNameFromPurl @@ -431,6 +432,14 @@ func packageName(typ, pkgNameFromPurl string, component cdx.Component) string { return component.Name } +// packageNameSeparator selects separator to join `group` and `name` fields of the component +func packageNameSeparator(typ string) string { + if typ == packageurl.TypeMaven { + return ":" + } + return "/" +} + // parsePackageLicenses checks all supported license fields and returns a list of licenses. // https://cyclonedx.org/docs/1.5/json/#components_items_licenses func parsePackageLicenses(l *cdx.Licenses) []string { diff --git a/pkg/sbom/cyclonedx/unmarshal_test.go b/pkg/sbom/cyclonedx/unmarshal_test.go index f62677a9ac70..61b24082343e 100644 --- a/pkg/sbom/cyclonedx/unmarshal_test.go +++ b/pkg/sbom/cyclonedx/unmarshal_test.go @@ -172,15 +172,16 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { FilePath: "", Libraries: ftypes.Packages{ { - Name: "bootstrap", + Name: "@example/bootstrap", Version: "5.0.2", Identifier: ftypes.PkgIdentifier{ PURL: &packageurl.PackageURL{ - Type: packageurl.TypeNPM, - Name: "bootstrap", - Version: "5.0.2", + Type: packageurl.TypeNPM, + Namespace: "@example", + Name: "bootstrap", + Version: "5.0.2", }, - BOMRef: "pkg:npm/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", + BOMRef: "pkg:npm/@example/bootstrap@5.0.2?file_path=app%2Fapp%2Fpackage.json", }, Licenses: []string{"MIT"}, Layer: ftypes.Layer{ From f90d4ee436e89fa3806e436bf7549053f4d51b27 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:11:12 +0600 Subject: [PATCH 088/108] fix(nodejs): find licenses for packages with slash (#5836) --- pkg/fanal/analyzer/language/nodejs/npm/npm.go | 10 ++-- .../analyzer/language/nodejs/npm/npm_test.go | 56 ++++++++++++------- .../node_modules/@babel/parser/package.json | 46 +++++++++++++++ .../npm/testdata/happy/package-lock.json | 5 ++ 4 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json diff --git a/pkg/fanal/analyzer/language/nodejs/npm/npm.go b/pkg/fanal/analyzer/language/nodejs/npm/npm.go index b827a37f83ff..8f70bd5c25a4 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/npm.go +++ b/pkg/fanal/analyzer/language/nodejs/npm/npm.go @@ -8,7 +8,6 @@ import ( "os" "path" "path/filepath" - "strings" "golang.org/x/xerrors" @@ -87,13 +86,14 @@ func (a npmLibraryAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAn func (a npmLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool { fileName := filepath.Base(filePath) + // Don't save package-lock.json from the `node_modules` directory to avoid duplication and mistakes. if fileName == types.NpmPkgLock && !xpath.Contains(filePath, "node_modules") { return true } - // The file path to package.json - */node_modules//package.json - // The path is slashed in analyzers. - dirs := strings.Split(path.Dir(filePath), "/") - if len(dirs) > 1 && dirs[len(dirs)-2] == "node_modules" && fileName == types.NpmPkg { + + // Save package.json files only from the `node_modules` directory. + // Required to search for licenses. + if fileName == types.NpmPkg && xpath.Contains(filePath, "node_modules") { return true } return false diff --git a/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go b/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go index ec03e751778f..7635e0266729 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go +++ b/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go @@ -34,6 +34,19 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Type: types.Npm, FilePath: "package-lock.json", Libraries: types.Packages{ + { + ID: "@babel/parser@7.23.6", + Name: "@babel/parser", + Version: "7.23.6", + Indirect: true, + Licenses: []string{"MIT"}, + Locations: []types.Location{ + { + StartLine: 6, + EndLine: 10, + }, + }, + }, { ID: "ansi-colors@3.2.3", Name: "ansi-colors", @@ -42,8 +55,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Indirect: true, Locations: []types.Location{ { - StartLine: 6, - EndLine: 11, + StartLine: 11, + EndLine: 16, }, }, }, @@ -54,8 +67,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Indirect: true, Locations: []types.Location{ { - StartLine: 12, - EndLine: 16, + StartLine: 17, + EndLine: 21, }, }, }, @@ -68,8 +81,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 17, - EndLine: 39, + StartLine: 22, + EndLine: 44, }, }, }, @@ -82,12 +95,12 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 25, - EndLine: 32, + StartLine: 30, + EndLine: 37, }, { - StartLine: 48, - EndLine: 55, + StartLine: 53, + EndLine: 60, }, }, }, @@ -100,8 +113,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 40, - EndLine: 62, + StartLine: 45, + EndLine: 67, }, }, }, @@ -113,12 +126,12 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 33, - EndLine: 37, + StartLine: 38, + EndLine: 42, }, { - StartLine: 56, - EndLine: 60, + StartLine: 61, + EndLine: 65, }, }, }, @@ -130,8 +143,8 @@ func Test_npmLibraryAnalyzer_Analyze(t *testing.T) { Licenses: []string{"MIT"}, Locations: []types.Location{ { - StartLine: 63, - EndLine: 67, + StartLine: 68, + EndLine: 72, }, }, }, @@ -206,9 +219,14 @@ func Test_nodePkgLibraryAnalyzer_Required(t *testing.T) { filePath: "npm/node_modules/ms/package.json", want: true, }, + { + name: "package.json with `/` in name", + filePath: "npm/node_modules/@babel/parser/package.json", + want: true, + }, { name: "sad path", - filePath: "npm/node_modules/package.json", + filePath: "npm/package.json", want: false, }, { diff --git a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json new file mode 100644 index 000000000000..5dc69d812815 --- /dev/null +++ b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/node_modules/@babel/parser/package.json @@ -0,0 +1,46 @@ +{ + "name": "@babel/parser", + "version": "7.23.6", + "description": "A JavaScript parser", + "author": "The Babel Team (https://babel.dev/team)", + "homepage": "https://babel.dev/docs/en/next/babel-parser", + "bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "keywords": [ + "babel", + "javascript", + "parser", + "tc39", + "ecmascript", + "@babel/parser" + ], + "repository": { + "type": "git", + "url": "https://github.com/babel/babel.git", + "directory": "packages/babel-parser" + }, + "main": "./lib/index.js", + "types": "./typings/babel-parser.d.ts", + "files": [ + "bin", + "lib", + "typings/babel-parser.d.ts", + "index.cjs" + ], + "engines": { + "node": ">=6.0.0" + }, + "devDependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/helper-check-duplicate-nodes": "^7.22.5", + "@babel/helper-fixtures": "^7.23.4", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "charcodes": "^0.2.0" + }, + "bin": "./bin/babel-parser.js", + "type": "commonjs" +} \ No newline at end of file diff --git a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json index 6d43d12c7888..60c78b708d60 100644 --- a/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json +++ b/pkg/fanal/analyzer/language/nodejs/npm/testdata/happy/package-lock.json @@ -3,6 +3,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==" + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", From ffe2ca7cb56ab99f7572ffb530525328d4ae3c60 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Mon, 15 Jan 2024 16:32:24 +0600 Subject: [PATCH 089/108] chore(deps): bump go-ebs-file (#5934) --- go.mod | 4 ++-- go.sum | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 85040a2f00ba..3bd773ef3b8e 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/magefile/mage v1.15.0 github.com/mailru/easyjson v0.7.7 github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac - github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43 + github.com/masahiro331/go-ebs-file v0.0.0-20240112135404-d5fbb1d46323 github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4 github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 github.com/masahiro331/go-vmdk-parser v0.0.0-20221225061455-612096e4bbbd @@ -176,7 +176,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/codebuild v1.26.5 // indirect github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6 // indirect github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 // indirect - github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ebs v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/ecs v1.35.6 // indirect github.com/aws/aws-sdk-go-v2/service/efs v1.26.5 // indirect github.com/aws/aws-sdk-go-v2/service/eks v1.37.0 // indirect diff --git a/go.sum b/go.sum index 32284820c213..5d3ca8a02d0c 100644 --- a/go.sum +++ b/go.sum @@ -377,7 +377,6 @@ github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.49.16 h1:KAQwhLg296hfffRdh+itA9p7Nx/3cXS/qOa3uF9ssig= github.com/aws/aws-sdk-go v1.49.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4= github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= @@ -390,10 +389,8 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tC github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 h1:I6lAa3wBWfCz/cKkOpAcumsETRkFAl70sWi8ItcMEsM= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11/go.mod h1:be1NIO30kJA23ORBLqPo1LttEM6tPNSEcjkd1eKzNW0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49Kk6+82spO3Tu5gSeQXRsxo56ePPQAvFiA= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= @@ -422,8 +419,8 @@ github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6 h1:OBNxHKQMlsQplVc+4CeNLTskna github.com/aws/aws-sdk-go-v2/service/docdb v1.29.6/go.mod h1:8d1RpdlgxFU6VO2aWru1ckR0Vsm4EgqCZgOamw5OHpw= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8 h1:XKO0BswTDeZMLDBd/b5pCEZGttNXrzRUVtFvp2Ak/Vo= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.8/go.mod h1:N5tqZcYMM0N1PN7UQYJNWuGyO886OfnMhf/3MAbqMcI= -github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1 h1:iUgGXA8fg41B4Of0F+BS766SRQ7c8rr5jtka8RgaocQ= -github.com/aws/aws-sdk-go-v2/service/ebs v1.18.1/go.mod h1:9n0SC5yHomD8IjsR37+/txpdfNdpGSgV1RzmsTHrbWg= +github.com/aws/aws-sdk-go-v2/service/ebs v1.21.7 h1:CRzzXjmgx9p362yO39D6hbZULdMI23gaKqSxijJCXHM= +github.com/aws/aws-sdk-go-v2/service/ebs v1.21.7/go.mod h1:wnsHqpi3RgDwklS5SPHUgjcUUpontGPKJ+GJYOdV7pY= github.com/aws/aws-sdk-go-v2/service/ec2 v1.142.0 h1:VrFC1uEZjX4ghkm/et8ATVGb1mT75Iv8aPKPjUE+F8A= github.com/aws/aws-sdk-go-v2/service/ec2 v1.142.0/go.mod h1:qjhtI9zjpUHRc6khtrIM9fb48+ii6+UikL3/b+MKYn0= github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6 h1:cT7h+GWP2k0hJSsPmppKgxl4C9R6gCC5/oF4oHnmpK4= @@ -486,7 +483,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGz github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= github.com/aws/aws-sdk-go-v2/service/workspaces v1.35.6 h1:RrpjQ5xJN/AW0PCO7EGhhVsKq7BeNqkx5+h6p3QOeTU= github.com/aws/aws-sdk-go-v2/service/workspaces v1.35.6/go.mod h1:vkYsJdF9sZl/o1eoK8tSSjzAT+R87QjswOGSTZfyO0Y= -github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -1303,8 +1299,8 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac h1:QyRucnGOLHJag1eB9CtuZwZk+/LpvTSYr5mnFLLFlgA= github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac/go.mod h1:J7Vb0sf0JzOhT0uHTeCqO6dqP/ELVcQvQ6yQ/56ZRGw= -github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43 h1:umYrurEClKuDjU29DKNNPmnWJNt4mnR0fWLOpWsDg0M= -github.com/masahiro331/go-ebs-file v0.0.0-20230228042409-005c81d4ae43/go.mod h1:5NOkqebMwu8UiOTSjwqam1Ykdr7fci52TVE2xDQnIiM= +github.com/masahiro331/go-ebs-file v0.0.0-20240112135404-d5fbb1d46323 h1:uQubA711SeYStvStohMLrdvRTTohdPHrEPFzerLcY9I= +github.com/masahiro331/go-ebs-file v0.0.0-20240112135404-d5fbb1d46323/go.mod h1:OdtzwqTtu49Gh5RFkNEU1SbcihIuVTtUipwHflqxckE= github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4 h1:uHO44vOunB0oEtk+r8ifBbFOD0mr6+fmoyFNCgLE66k= github.com/masahiro331/go-ext4-filesystem v0.0.0-20231208112839-4339555a0cd4/go.mod h1:3XMMY1M486mWGTD13WPItg6FsgflQR72ZMAkd+gsyoQ= github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 h1:AevUBW4cc99rAF8q8vmddIP8qd/0J5s/UyltGbp66dg= From 2c9d7c6b50e01358169089ae5010ef1d84f104bb Mon Sep 17 00:00:00 2001 From: Bishwa Thapa <15176360+thapabishwa@users.noreply.github.com> Date: Tue, 16 Jan 2024 00:53:52 +0545 Subject: [PATCH 090/108] feat: allow end-users to adjust K8S client QPS and burst (#5910) --- .../configuration/cli/trivy_kubernetes.md | 2 ++ pkg/flag/kubernetes_flags.go | 20 +++++++++++++++++++ pkg/k8s/commands/run.go | 2 ++ 3 files changed, 24 insertions(+) diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 9599ca493d84..3e2c7297e34d 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -28,6 +28,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: ``` -A, --all-namespaces fetch resources from all cluster namespaces + --burst int specify the maximum burst for throttle (default 10) --cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs") --cache-ttl duration cache TTL when using redis as cache backend --clear-cache clear image caches without scanning @@ -72,6 +73,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. --policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0") --policy-namespaces strings Rego namespaces + --qps float specify the maximum QPS to the master from this client (default 5) --redis-ca string redis ca file location, if using redis as cache backend --redis-cert string redis certificate file location, if using redis as cache backend --redis-key string redis key file location, if using redis as cache backend diff --git a/pkg/flag/kubernetes_flags.go b/pkg/flag/kubernetes_flags.go index 5ba74c7de919..e1405b501d37 100644 --- a/pkg/flag/kubernetes_flags.go +++ b/pkg/flag/kubernetes_flags.go @@ -88,6 +88,18 @@ var ( Default: "ghcr.io/aquasecurity/node-collector:0.0.9", Usage: "indicate the image reference for the node-collector scan job", } + QPS = Flag{ + Name: "qps", + ConfigName: "kubernetes.qps", + Default: 5.0, + Usage: "specify the maximum QPS to the master from this client", + } + Burst = Flag{ + Name: "burst", + ConfigName: "kubernetes.burst", + Default: 10, + Usage: "specify the maximum burst for throttle", + } ) type K8sFlagGroup struct { @@ -102,6 +114,8 @@ type K8sFlagGroup struct { NodeCollectorNamespace *Flag ExcludeOwned *Flag ExcludeNodes *Flag + QPS *Flag + Burst *Flag } type K8sOptions struct { @@ -116,6 +130,8 @@ type K8sOptions struct { NodeCollectorNamespace string ExcludeOwned bool ExcludeNodes map[string]string + QPS float32 + Burst int } func NewK8sFlagGroup() *K8sFlagGroup { @@ -131,6 +147,8 @@ func NewK8sFlagGroup() *K8sFlagGroup { ExcludeOwned: &ExcludeOwned, ExcludeNodes: &ExcludeNodes, NodeCollectorImageRef: &NodeCollectorImageRef, + QPS: &QPS, + Burst: &Burst, } } @@ -151,6 +169,8 @@ func (f *K8sFlagGroup) Flags() []*Flag { f.ExcludeOwned, f.ExcludeNodes, f.NodeCollectorImageRef, + f.QPS, + f.Burst, } } diff --git a/pkg/k8s/commands/run.go b/pkg/k8s/commands/run.go index 61ea4860db61..e9e3510f6bce 100644 --- a/pkg/k8s/commands/run.go +++ b/pkg/k8s/commands/run.go @@ -30,6 +30,8 @@ func Run(ctx context.Context, args []string, opts flag.Options) error { cluster, err := k8s.GetCluster( k8s.WithContext(opts.K8sOptions.ClusterContext), k8s.WithKubeConfig(opts.K8sOptions.KubeConfig), + k8s.WithBurst(opts.K8sOptions.Burst), + k8s.WithQPS(opts.K8sOptions.QPS), ) if err != nil { return xerrors.Errorf("failed getting k8s cluster: %w", err) From 260aa281f4616b3b4b711dbad6f5d1979e5d6488 Mon Sep 17 00:00:00 2001 From: Devin Trejo Date: Tue, 16 Jan 2024 02:59:08 -0500 Subject: [PATCH 091/108] fix(alpine): Add EOL support for alpine 3.19. (#5938) Signed-off-by: Devin Trejo --- docs/docs/coverage/os/index.md | 4 ++-- pkg/detector/ospkg/alpine/alpine.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/docs/coverage/os/index.md b/docs/docs/coverage/os/index.md index 55e303c48521..e04a452fc4d3 100644 --- a/docs/docs/coverage/os/index.md +++ b/docs/docs/coverage/os/index.md @@ -11,7 +11,7 @@ Trivy supports operating systems for | OS | Supported Versions | Package Managers | |-----------------------------------------------|-------------------------------------|------------------| -| [Alpine Linux](alpine.md) | 2.2 - 2.7, 3.0 - 3.18, edge | apk | +| [Alpine Linux](alpine.md) | 2.2 - 2.7, 3.0 - 3.19, edge | apk | | [Wolfi Linux](wolfi.md) | (n/a) | apk | | [Chainguard](chainguard.md) | (n/a) | apk | | [Red Hat Enterprise Linux](rhel.md) | 6, 7, 8 | dnf/yum/rpm | @@ -42,4 +42,4 @@ Each page gives more details. [sbom]: ../../supply-chain/sbom.md [vuln]: ../../scanner/vulnerability.md -[license]: ../../scanner/license.md \ No newline at end of file +[license]: ../../scanner/license.md diff --git a/pkg/detector/ospkg/alpine/alpine.go b/pkg/detector/ospkg/alpine/alpine.go index 4602df844727..4be5cf128431 100644 --- a/pkg/detector/ospkg/alpine/alpine.go +++ b/pkg/detector/ospkg/alpine/alpine.go @@ -46,6 +46,7 @@ var ( "3.16": time.Date(2024, 5, 23, 23, 59, 59, 0, time.UTC), "3.17": time.Date(2024, 11, 22, 23, 59, 59, 0, time.UTC), "3.18": time.Date(2025, 5, 9, 23, 59, 59, 0, time.UTC), + "3.19": time.Date(2025, 11, 1, 23, 59, 59, 0, time.UTC), "edge": time.Date(9999, 1, 1, 0, 0, 0, 0, time.UTC), } ) From fbc1a83f3258ee6d5cf2327e2c5fb627438df81e Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:57:41 +0600 Subject: [PATCH 092/108] fix(amazon): save system files for pkgs containing `amzn` in src (#5951) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- pkg/fanal/analyzer/pkg/rpm/rpm.go | 13 ++++-- pkg/fanal/analyzer/pkg/rpm/rpm_test.go | 56 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/pkg/fanal/analyzer/pkg/rpm/rpm.go b/pkg/fanal/analyzer/pkg/rpm/rpm.go index 1efd91c0e8e1..f3a52286e578 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpm.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpm.go @@ -133,7 +133,7 @@ func (a rpmPkgAnalyzer) listPkgs(db RPMDB) (types.Packages, []string, error) { // Check if the package is vendor-provided. // If the package is not provided by vendor, the installed files should not be skipped. var files []string - if packageProvidedByVendor(pkg.Vendor) { + if packageProvidedByVendor(pkg) { files, err = pkg.InstalledFileNames() if err != nil { return nil, nil, xerrors.Errorf("unable to get installed files: %w", err) @@ -235,12 +235,19 @@ func splitFileName(filename string) (name, ver, rel string, err error) { return name, ver, rel, nil } -func packageProvidedByVendor(pkgVendor string) bool { +func packageProvidedByVendor(pkg *rpmdb.PackageInfo) bool { + if pkg.Vendor == "" { + // Official Amazon packages may not contain `Vendor` field: + // https://github.com/aquasecurity/trivy/issues/5887 + return strings.Contains(pkg.Release, "amzn") + } + for _, vendor := range osVendors { - if strings.HasPrefix(pkgVendor, vendor) { + if strings.HasPrefix(pkg.Vendor, vendor) { return true } } + return false } diff --git a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go index 7e99cc601d61..2ef2a0b46219 100644 --- a/pkg/fanal/analyzer/pkg/rpm/rpm_test.go +++ b/pkg/fanal/analyzer/pkg/rpm/rpm_test.go @@ -165,6 +165,62 @@ func Test_rpmPkgAnalyzer_listPkgs(t *testing.T) { "/lib64/libm-2.27.so", }, }, + { + name: "Amazon official package without `Vendor` field", + mock: mock{ + packages: []*rpmdb.PackageInfo{ + { + Name: "curl-minimal", + Version: "8.3.0", + Release: "1.amzn2023.0.2", + Arch: "aarch64", + SourceRpm: "curl-8.3.0-1.amzn2023.0.2.src.rpm", + DirNames: []string{ + "/usr/bin/", + "/usr/lib/", + "/usr/lib/.build-id/", + "/usr/lib/.build-id/aa/", + "/usr/share/man/man1/", + }, + DirIndexes: []int32{0, 1, 2, 3, 4}, + BaseNames: []string{ + "curl", + ".build-id", + "aa", + "d987ea9bc1c73706d12c7a143ee792117851ff", + "curl.1.gz", + }, + Vendor: "", + }, + }, + }, + wantPkgs: types.Packages{ + { + ID: "curl-minimal@8.3.0-1.amzn2023.0.2.aarch64", + Name: "curl-minimal", + Version: "8.3.0", + Release: "1.amzn2023.0.2", + Arch: "aarch64", + SrcName: "curl", + SrcVersion: "8.3.0", + SrcRelease: "1.amzn2023.0.2", + InstalledFiles: []string{ + "/usr/bin/curl", + "/usr/lib/.build-id", + "/usr/lib/.build-id/aa", + "/usr/lib/.build-id/aa/d987ea9bc1c73706d12c7a143ee792117851ff", + "/usr/share/man/man1/curl.1.gz", + }, + }, + }, + wantFiles: []string{ + "/usr/bin/curl", + "/usr/lib/.build-id", + "/usr/lib/.build-id/aa", + "/usr/lib/.build-id/aa/d987ea9bc1c73706d12c7a143ee792117851ff", + "/usr/share/man/man1/curl.1.gz", + }, + }, { name: "invalid source rpm", mock: mock{ From 7cad04bdf114cca382241afcb40a142783a7ade2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:00:37 +0400 Subject: [PATCH 093/108] chore(deps): bump aquaproj/aqua-installer from 2.1.2 to 2.2.0 (#5693) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/auto-update-labels.yaml | 2 +- .github/workflows/test.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/auto-update-labels.yaml b/.github/workflows/auto-update-labels.yaml index 26307a3f50c5..6dab8481873b 100644 --- a/.github/workflows/auto-update-labels.yaml +++ b/.github/workflows/auto-update-labels.yaml @@ -20,7 +20,7 @@ jobs: go-version-file: go.mod - name: Install aqua tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index a6401facaa68..802fe53f0814 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,7 +47,7 @@ jobs: if: ${{ failure() && steps.lint.conclusion == 'failure' }} - name: Install tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 aqua_opts: "" @@ -77,7 +77,7 @@ jobs: go-version-file: go.mod - name: Install tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 @@ -106,7 +106,7 @@ jobs: go-version-file: go.mod - name: Install tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 @@ -126,7 +126,7 @@ jobs: go-version-file: go.mod - name: Install tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 @@ -156,7 +156,7 @@ jobs: with: go-version-file: go.mod - name: Install tools - uses: aquaproj/aqua-installer@v2.1.2 + uses: aquaproj/aqua-installer@v2.2.0 with: aqua_version: v1.25.0 - name: Run vm integration tests From 2212d14432935eda2efd9878eaecff1e8eb4071f Mon Sep 17 00:00:00 2001 From: chenk Date: Fri, 19 Jan 2024 10:27:35 +0200 Subject: [PATCH 094/108] fix: handle non-parsable images names (#5965) Signed-off-by: chenk --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 3bd773ef3b8e..1c6a606b3e3d 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d github.com/aquasecurity/trivy-iac v0.7.1 github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 - github.com/aquasecurity/trivy-kubernetes v0.6.1 + github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1 github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 github.com/aws/aws-sdk-go-v2 v1.24.1 github.com/aws/aws-sdk-go-v2/config v1.26.3 @@ -158,7 +158,7 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.49.16 // indirect + github.com/aws/aws-sdk-go v1.49.21 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect @@ -245,7 +245,7 @@ require ( github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.4 // indirect @@ -405,7 +405,7 @@ require ( k8s.io/cli-runtime v0.29.0 // indirect k8s.io/client-go v0.29.0 // indirect k8s.io/component-base v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/klog/v2 v2.120.0 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect k8s.io/kubectl v0.29.0 // indirect lukechampine.com/uint128 v1.2.0 // indirect diff --git a/go.sum b/go.sum index 5d3ca8a02d0c..9a434ee315e5 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkv github.com/aquasecurity/trivy-iac v0.7.1/go.mod h1:SK5XaVwGh5M17QV81139BSPXNlm3bIGp+YmAYs7slRw= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= -github.com/aquasecurity/trivy-kubernetes v0.6.1 h1:Mj6wP3YhmDxqSbS0o8XrLgXMvoLAkf+CDBhRSIdhbIg= -github.com/aquasecurity/trivy-kubernetes v0.6.1/go.mod h1:9CxcIVIE6wvQWvxx4MIKf6nY1w+zAFIvutl8ikoXSgo= +github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1 h1:/LsIHMQJ4SOxZeib/bvLP7S3YDTXJVIsQyS4kIIP0GQ= +github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1/go.mod h1:v6B8SO2ep718ccGbbjhpzMn6p27IijS+dMb+MeYz3jQ= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842/go.mod h1:BmEeSFgmBjo3avCli71736sy0veGcSUzGATupp1MCgA= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -375,8 +375,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.49.16 h1:KAQwhLg296hfffRdh+itA9p7Nx/3cXS/qOa3uF9ssig= -github.com/aws/aws-sdk-go v1.49.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.49.21 h1:Rl8KW6HqkwzhATwvXhyr7vD4JFUMi7oXGAw9SrxxIFY= +github.com/aws/aws-sdk-go v1.49.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= @@ -831,8 +831,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= @@ -2565,8 +2565,8 @@ k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +k8s.io/klog/v2 v2.120.0 h1:z+q5mfovBj1fKFxiRzsa2DsJLPIVMk/KFL81LMOfK+8= +k8s.io/klog/v2 v2.120.0/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= From a96f66f176e512ffb029f2d421e2d77b805eb6ee Mon Sep 17 00:00:00 2001 From: Anais Urlichs <33576047+AnaisUrlichs@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:28:46 +0000 Subject: [PATCH 095/108] docs: update command to scan go binary (#5969) Signed-off-by: AnaisUrlichs --- docs/docs/coverage/language/golang.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/coverage/language/golang.md b/docs/docs/coverage/language/golang.md index 31796bf531f8..54bebfdc4185 100644 --- a/docs/docs/coverage/language/golang.md +++ b/docs/docs/coverage/language/golang.md @@ -68,7 +68,7 @@ If there is a Go binary in your container image, Trivy automatically finds and s Also, you can scan your local binaries. ``` -$ trivy fs ./your_binary +$ trivy rootfs ./your_binary ``` !!! note From 91a2547d15db5abc45501734cfad7b70660d9380 Mon Sep 17 00:00:00 2001 From: Anais Urlichs <33576047+AnaisUrlichs@users.noreply.github.com> Date: Mon, 22 Jan 2024 07:44:16 +0000 Subject: [PATCH 096/108] docs: update cosign tutorial and commands, update kyverno policy (#5929) Signed-off-by: AnaisUrlichs Co-authored-by: saso --- docs/docs/supply-chain/attestation/vuln.md | 7 +- docs/tutorials/kubernetes/kyverno.md | 63 ++++------ docs/tutorials/signing/vuln-attestation.md | 135 +++++++++++++++++++-- 3 files changed, 150 insertions(+), 55 deletions(-) diff --git a/docs/docs/supply-chain/attestation/vuln.md b/docs/docs/supply-chain/attestation/vuln.md index c17164f0f30b..b1484387266a 100644 --- a/docs/docs/supply-chain/attestation/vuln.md +++ b/docs/docs/supply-chain/attestation/vuln.md @@ -179,13 +179,14 @@ You can use Cosign to sign without keys by authenticating with an OpenID Connect ``` $ trivy image --format cosign-vuln -o vuln.json -$ COSIGN_EXPERIMENTAL=1 cosign attest --type vuln --predicate vuln.json +$ cosign attest --type vuln --predicate vuln.json ``` +This will provide a certificate in the output section. -You can verify attestations. +You can verify attestations: ``` -$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type vuln +$ cosign verify-attestation --certificate=path-to-the-certificate --type vuln --certificate-identity Email-used-to-sign --certificate-oidc-issuer='the-issuer-used' ``` [vuln-attest-spec]: https://github.com/sigstore/cosign/blob/95b74db89941e8ec85e768f639efd4d948db06cd/specs/COSIGN_VULN_ATTESTATION_SPEC.md \ No newline at end of file diff --git a/docs/tutorials/kubernetes/kyverno.md b/docs/tutorials/kubernetes/kyverno.md index 4dc9633212a2..f2e9d12006a7 100644 --- a/docs/tutorials/kubernetes/kyverno.md +++ b/docs/tutorials/kubernetes/kyverno.md @@ -7,8 +7,9 @@ This tutorial details - Verify the container image has an attestation with Kyverno ### Prerequisites -1. [Attestation of the vulnerability scan uploaded][vuln-attestation] -2. A running Kubernetes cluster that kubectl is connected to +1. A running Kubernetes cluster that kubectl is connected to +2. A Container image signed with Cosign and an attestation generated for a Trivy Vulnerability scan. + [Follow this tutorial for more information.][vuln-attestation] ### Kyverno Policy to check attestation @@ -24,11 +25,12 @@ kind: ClusterPolicy metadata: name: check-vulnerabilities spec: - validationFailureAction: enforce - webhookTimeoutSeconds: 10 + validationFailureAction: Enforce + background: false + webhookTimeoutSeconds: 30 failurePolicy: Fail rules: - - name: not-older-than-one-week + - name: checking-vulnerability-scan-not-older-than-one-hour match: any: - resources: @@ -36,14 +38,23 @@ spec: - Pod verifyImages: - imageReferences: - - "CONTAINER-REGISTRY/*:*" + - "*" attestations: - - predicateType: cosign.sigstore.dev/attestation/vuln/v1 + - type: https://cosign.sigstore.dev/attestation/vuln/v1 conditions: - all: - - key: "{{ time_since('','{{metadata.scanFinishedOn}}','') }}" + - key: "{{ time_since('','{{ metadata.scanFinishedOn }}', '') }}" operator: LessThanOrEquals - value: "168h" + value: "1h" + attestors: + - count: 1 + entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + abc + xyz + -----END PUBLIC KEY----- ``` {% endraw %} @@ -57,38 +68,12 @@ Next, apply the above policy: kubectl apply -f vuln-attestation.yaml ``` -To ensure that the policy worked, we can deploye an example deployment file with our container image: +To ensure that the policy worked, we can deploy an example Kubernetes Pod with our container image: -deployment.yaml ``` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cns-website - namespace: app -spec: - replicas: 2 - selector: - matchLabels: - run: cns-website - template: - metadata: - labels: - run: cns-website - spec: - containers: - - name: cns-website - image: docker.io/anaisurlichs/cns-website:0.0.6 - ports: - - containerPort: 80 - imagePullPolicy: Always - resources: - limits: - memory: 512Mi - cpu: 200m - securityContext: - allowPrivilegeEscalation: false +kubectl run app-signed --image= docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd  ``` +Note that the image is based on the [signing tutorial.][vuln-attestation] Once we apply the deployment, it should pass since our attestation is available: ``` @@ -98,7 +83,7 @@ deployment.apps/cns-website created However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with `docker.io/anaisurlichs/cns-website:0.0.5` and applying the deployment: ``` -kubectl apply -f deployment-two.yaml +kubectl run app-unsigned --image=docker.io/anaisurlichs/cns-website:0.1.1  Resource: "apps/v1, Resource=deployments", GroupVersionKind: "apps/v1, Kind=Deployment" Name: "cns-website", Namespace: "app" diff --git a/docs/tutorials/signing/vuln-attestation.md b/docs/tutorials/signing/vuln-attestation.md index f0721c9d3223..2e4b487306c6 100644 --- a/docs/tutorials/signing/vuln-attestation.md +++ b/docs/tutorials/signing/vuln-attestation.md @@ -1,36 +1,145 @@ # Vulnerability Scan Record Attestation -This tutorial details +This tutorial details how to -- Scan your container image for vulnerabilities -- Generate an attestation with Cosign +- Scan container images for vulnerabilities +- Generate an attestation, using Cosign, with and without generating a separate key pair #### Prerequisites -1. Trivy CLI installed -2. Cosign installed +1. [Trivy CLI](../../getting-started/installation.md) installed +2. [Cosign CLI](https://docs.sigstore.dev/system_config/installation/) installed +3. Ensure that you have access to a container image in a remote container registry that you own/within your account. In this tutorial, we will use DockerHub. -#### Scan Container Image for vulnerabilities +## Scan Container Image for vulnerabilities Scan your container image for vulnerabilities and save the scan result to a scan.json file: ``` -trivy image --ignore-unfixed --format json --output scan.json anaisurlichs/cns-website:0.0.6 +trivy image --ignore-unfixed --format cosign-vuln --output scan.json DockerHubID/imagename:imagetag ``` -* --ignore-unfixed: Ensures that only the vulnerabilities are displayed that have a already a fix available -* --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal. +For example: +``` +trivy image --ignore-unfixed --format cosign-vuln --output scan.json anaisurlichs/signed-example:0.1 +``` -Note: Replace the container image with the container image that you would like to scan. +* `--ignore-unfixed`: Ensures only the vulnerabilities, which have a already a fix available, are displayed +* `--output scan.json`: The scan output is saved to a scan.json file instead of being displayed in the terminal. + +Note: Replace the container image with the container image that you want to scan. + +## Option 1: Signing and Generating an attestation without new key pair + +#### Signing + +Sign the container image: +``` +cosign sign DockerHubID/imagename@imageSHA +``` + +The `imageSHA` can be obtained through the following docker command: +``` +docker image ls --digests +``` +The SHA will be displayed next to the image name and tag. + +Note that it is better practice to sign the image SHA rather than the tag as the SHA will remain the same for the particular image that we have signed. + +For example: +``` +cosign sign docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd +``` -#### Attestation of the vulnerability scan with Cosign +#### Attestation -The following command generates an attestation for the vulnerability scan and uploads it to our container image: +The following command generates an attestation for the vulnerability scan and uploads it to the container image used: ``` -cosign attest --replace --predicate scan.json --type vuln anaisurlichs/cns-website:0.0.6 +cosign attest --predicate scan.json --type vuln docker.io/DockerHubID/imagename:imageSHA +``` + +For example: +``` +cosign attest --predicate scan.json --type vuln docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd ``` Note: Replace the container image with the container image that you would like to scan. +Next, Sigstore will ask you to verify with an account -- Microsoft, GitHub, or Google. + +Once done, the user will be provided with a certificate in the terminal where they ran the command. Example certificate: +``` +-----BEGIN CERTIFICATE----- +MIIC1TCCAlygAwIBAgIUfSXI7xTWSLq4nuygd8YPuhPZlEswCgYIKoZIzj0EAwMw +NzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl +cm1lZGlhdGUwHhcNMjQwMTExMTMzODUzWhcNMjQwMTExMTM0ODUzWjAAMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAETcUNnK76mfo9G3j1c7NN6Vcn6yQPDX5rd3QB +unkHs1Uk59CWv3qm6sUyRNYaATs9zdHAZqLck8G4P/Pj7+GzCKOCAXswggF3MA4G +........ +-----END CERTIFICATE----- +``` + + +## Option 2: Signing and Generating an attestation with a new Cosign key pair + +To generate an attestation for the container image with a separate key pair, we can use Cosign to generate a new key pair: +``` +cosign generate-key-pair  +``` + +This will generate a `cosign.key` and a `cosign.pub` file. The `cosign.key` file is your private key that should be kept confidential as it is used to sign artefacts. However, the `cosign.pub` file contains the information of the corresponding public key. This key can be used by third parties to verify the attestation -- basically that this person who claims to have signed the attestation actually is the one who signed it. + +#### Signing + +Sign the container image: +``` +cosign sign --key cosign.key docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd +``` + +#### Attestation + +To generate the attestation with the specific key pairs, run the following command: +``` +cosign attest --key cosign.key --type vuln --predicate scan.json docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd  +``` + +## Verify the attestation + +### Option 1 -- No separate key pair + +If you have not generated a key pair but received a certificate after the container image was signed, use the following command to verify the attestation: + +``` +cosign verify-attestation --type vuln --certificate-identity Email-used-to-sign --certificate-oidc-issuer='the-issuer-used' docker.io/DockerHubID/imagename:imageSHA +``` + +For example, the command could be like this: +``` +cosign verify-attestation --type vuln --certificate-identity urlichsanais@gmail.com --certificate-oidc-issuer='https://github.com/login/oauth' anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd +``` + +### Option 2 -- Separate key pair + +If you have used a new cosign key pair, the attestation can be verified through the following command: +``` +cosign verify-attestation --key cosign.pub --type vuln anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd  +``` + +
+Output + +The output should look similar to the following: +``` +Verification for anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd -- +The following checks were performed on each of these signatures: + - The cosign claims were validated + - Existence of the claims in the transparency log was verified offline + - The signatures were verified against the specified public key +{"payloadType":"application/vnd.in-toto+json","payload": +``` +
+ +## More information + See [here][vuln-attestation] for more details. [vuln-attestation]: ../../docs/supply-chain/attestation/vuln.md \ No newline at end of file From 189a46a01cdaee41dcf901be94805186ef9c64a3 Mon Sep 17 00:00:00 2001 From: simar7 <1254783+simar7@users.noreply.github.com> Date: Mon, 22 Jan 2024 23:44:10 -0700 Subject: [PATCH 097/108] chore(deps): Update misconfig deps (#5956) --- go.mod | 34 +++---- go.sum | 60 ++++++------ integration/testdata/helm.json.golden | 32 +----- .../testdata/helm_testchart.json.golden | 98 ++----------------- .../helm_testchart.overridden.json.golden | 98 ++----------------- pkg/fanal/secret/builtin-rules.go | 2 +- 6 files changed, 67 insertions(+), 257 deletions(-) diff --git a/go.mod b/go.mod index 1c6a606b3e3d..877dfd73665b 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NYTimes/gziphandler v1.1.1 github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 - github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 + github.com/aquasecurity/defsec v0.94.1 github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 @@ -23,12 +23,12 @@ require ( github.com/aquasecurity/table v1.8.0 github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da github.com/aquasecurity/tml v0.6.1 - github.com/aquasecurity/trivy-aws v0.7.0 + github.com/aquasecurity/trivy-aws v0.7.1 github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d - github.com/aquasecurity/trivy-iac v0.7.1 + github.com/aquasecurity/trivy-iac v0.8.0 github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1 - github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 + github.com/aquasecurity/trivy-policies v0.8.0 github.com/aws/aws-sdk-go-v2 v1.24.1 github.com/aws/aws-sdk-go-v2/config v1.26.3 github.com/aws/aws-sdk-go-v2/credentials v1.16.14 @@ -37,7 +37,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6 github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 - github.com/bmatcuk/doublestar/v4 v4.6.0 + github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cheggaaa/pb/v3 v3.1.4 github.com/containerd/containerd v1.7.11 @@ -96,7 +96,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.26.0 + github.com/testcontainers/testcontainers-go v0.27.0 github.com/testcontainers/testcontainers-go/modules/localstack v0.26.0 github.com/tetratelabs/wazero v1.2.1 github.com/twitchtv/twirp v8.1.2+incompatible @@ -106,8 +106,8 @@ require ( go.uber.org/zap v1.26.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/mod v0.14.0 - golang.org/x/sync v0.5.0 - golang.org/x/term v0.15.0 + golang.org/x/sync v0.6.0 + golang.org/x/term v0.16.0 golang.org/x/text v0.14.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 google.golang.org/protobuf v1.32.0 @@ -226,7 +226,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dlclark/regexp2 v1.4.0 // indirect - github.com/docker/cli v24.0.5+incompatible // indirect + github.com/docker/cli v24.0.6+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect @@ -236,7 +236,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -381,10 +381,10 @@ require ( go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.19.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.15.0 // indirect google.golang.org/api v0.138.0 // indirect @@ -398,10 +398,10 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - helm.sh/helm/v3 v3.13.0 // indirect - k8s.io/apiextensions-apiserver v0.28.2 // indirect + helm.sh/helm/v3 v3.14.0 // indirect + k8s.io/apiextensions-apiserver v0.29.0 // indirect k8s.io/apimachinery v0.29.0 // indirect - k8s.io/apiserver v0.28.2 // indirect + k8s.io/apiserver v0.29.0 // indirect k8s.io/cli-runtime v0.29.0 // indirect k8s.io/client-go v0.29.0 // indirect k8s.io/component-base v0.29.0 // indirect @@ -417,7 +417,7 @@ require ( modernc.org/opt v0.1.3 // indirect modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.1.0 // indirect - oras.land/oras-go v1.2.3 // indirect + oras.land/oras-go v1.2.4 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect diff --git a/go.sum b/go.sum index 9a434ee315e5..4f43615c6d4e 100644 --- a/go.sum +++ b/go.sum @@ -326,8 +326,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= -github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08 h1:mjQvKTiKYXWGxHU5pw37q1n6deky0KcJq5JJwtuVrF4= -github.com/aquasecurity/defsec v0.93.2-0.20231208181342-318642ac6f08/go.mod h1:NBF6hvbQSc4s/WCHdKV5sNNxLl258M2OiIFoUfgEn/k= +github.com/aquasecurity/defsec v0.94.1 h1:lk44bfUltm0f0Dw4DbO3Ka9d/bf3N8cWclSdHXMyKF4= +github.com/aquasecurity/defsec v0.94.1/go.mod h1:wiX9BX0SOG0ZWjVIPYGPl46fyO3Gu8lJnk4rmhFR7IA= github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 h1:jdymGFJpArgx1ZZW7yqgCV8Tt+sEZ4jKxjQufPYRSXE= github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562/go.mod h1:B+gSaiuXV258CtyfBwFvG87+GE/FOh6W4N+LMuQxvVA= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= @@ -349,18 +349,18 @@ github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da h1:pj/adfN github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da/go.mod h1:852lbQLpK2nCwlR4ZLYIccxYCfoQao6q9Nl6tjz54v8= github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo= github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY= -github.com/aquasecurity/trivy-aws v0.7.0 h1:Ax3NcYghfdtPXVPsrHswSdkL6q9fL5kwuEgui+I5hLQ= -github.com/aquasecurity/trivy-aws v0.7.0/go.mod h1:ax3XNWIwKrypBXMzV7OKe5Qsz19OGb6WlACg0WCpzxw= +github.com/aquasecurity/trivy-aws v0.7.1 h1:XElKZsP9Hqe2JVekQgGCIkFtgRgVlP+80wKL2JWBctk= +github.com/aquasecurity/trivy-aws v0.7.1/go.mod h1:bJT7pzsqo9q5yi3arJSt789bAH0eDb7c+niFYMBNcMQ= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d h1:fjI9mkoTUAkbGqpzt9nJsO24RAdfG+ZSiLFj0G2jO8c= github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d/go.mod h1:cj9/QmD9N3OZnKQMp+/DvdV+ym3HyIkd4e+F0ZM3ZGs= -github.com/aquasecurity/trivy-iac v0.7.1 h1:YqA0B1P/5uJy2YOrT+QtoB8Z/DCqMxApsMkvmyd5Lsg= -github.com/aquasecurity/trivy-iac v0.7.1/go.mod h1:SK5XaVwGh5M17QV81139BSPXNlm3bIGp+YmAYs7slRw= +github.com/aquasecurity/trivy-iac v0.8.0 h1:NKFhk/BTwQ0jIh4t74V8+6UIGUvPlaxO9HPlSMQi3fo= +github.com/aquasecurity/trivy-iac v0.8.0/go.mod h1:ARiMeNqcaVWOXJmp8hmtMnNm/Jd836IOmDBUW5r4KEk= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI= github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8= github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1 h1:/LsIHMQJ4SOxZeib/bvLP7S3YDTXJVIsQyS4kIIP0GQ= github.com/aquasecurity/trivy-kubernetes v0.6.3-0.20240118072219-c433b06f98e1/go.mod h1:v6B8SO2ep718ccGbbjhpzMn6p27IijS+dMb+MeYz3jQ= -github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842 h1:RnxM3eTcwPlA/WBwnmaEpeEk3WOCDcnz7yTIFxVL7us= -github.com/aquasecurity/trivy-policies v0.6.1-0.20231120231532-f6f2330bf842/go.mod h1:BmEeSFgmBjo3avCli71736sy0veGcSUzGATupp1MCgA= +github.com/aquasecurity/trivy-policies v0.8.0 h1:LvmIdw/DfTF72Lc8L+CKLYzfb5BFYzLBGFFR95PKC74= +github.com/aquasecurity/trivy-policies v0.8.0/go.mod h1:qF/t59pgK/0JTV6tXaeA3Iw3opzoMgzGCDcTDBmqb30= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -499,8 +499,8 @@ github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c/go.mod h1:9iglf github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc= -github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= @@ -719,8 +719,8 @@ github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyG github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= -github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY= +github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -773,8 +773,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -1838,8 +1838,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1948,8 +1948,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1994,8 +1994,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2122,8 +2122,8 @@ 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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2131,8 +2131,8 @@ golang.org/x/term v0.1.0/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.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= 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= @@ -2520,8 +2520,8 @@ gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -helm.sh/helm/v3 v3.13.0 h1:XPJKIU30K4JTQ6VX/6e0hFAmEIonYa8E7wx5aqv4xOc= -helm.sh/helm/v3 v3.13.0/go.mod h1:2PBEKsMWKLVZTojUOqMS3Eadv5mP43FBWrRgLNkNm9Y= +helm.sh/helm/v3 v3.14.0 h1:TaZIH6uOchn7L27ptwnnuHJiFrT/BsD4dFdp/HLT2nM= +helm.sh/helm/v3 v3.14.0/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2534,8 +2534,8 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.28.2 h1:J6/QRWIKV2/HwBhHRVITMLYoypCoPY1ftigDM0Kn+QU= -k8s.io/apiextensions-apiserver v0.28.2/go.mod h1:5tnkxLGa9nefefYzWuAlWZ7RZYuN/765Au8cWLA6SRg= +k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= +k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= @@ -2544,8 +2544,8 @@ k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMei k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.28.2 h1:rBeYkLvF94Nku9XfXyUIirsVzCzJBs6jMn3NWeHieyI= -k8s.io/apiserver v0.28.2/go.mod h1:f7D5e8wH8MWcKD7azq6Csw9UN+CjdtXIVQUyUhrtb+E= +k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o= +k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM= k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= diff --git a/integration/testdata/helm.json.golden b/integration/testdata/helm.json.golden index 5899f2a52bc4..df4705b12115 100644 --- a/integration/testdata/helm.json.golden +++ b/integration/testdata/helm.json.golden @@ -21,8 +21,8 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 141, - "Failures": 15, + "Successes": 125, + "Failures": 14, "Exceptions": 0 }, "Misconfigurations": [ @@ -312,7 +312,7 @@ "Namespace": "builtin.kubernetes.KSV014", "Query": "data.builtin.kubernetes.KSV014.deny", "Resolution": "Change 'containers[].securityContext.readOnlyRootFilesystem' to 'true'.", - "Severity": "LOW", + "Severity": "HIGH", "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv014", "References": [ "https://kubesec.io/basics/containers-securitycontext-readonlyrootfilesystem-true/", @@ -880,32 +880,6 @@ } } }, - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "deployment nginx-deployment in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - }, { "Type": "Helm Security Check", "ID": "KSV117", diff --git a/integration/testdata/helm_testchart.json.golden b/integration/testdata/helm_testchart.json.golden index 58bce82835f9..7b78e3f38620 100644 --- a/integration/testdata/helm_testchart.json.golden +++ b/integration/testdata/helm_testchart.json.golden @@ -21,8 +21,8 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 151, - "Failures": 5, + "Successes": 135, + "Failures": 4, "Exceptions": 0 }, "Misconfigurations": [ @@ -308,32 +308,6 @@ } } }, - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "deployment testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - }, { "Type": "Helm Security Check", "ID": "KSV117", @@ -367,76 +341,20 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 155, - "Failures": 1, + "Successes": 106, + "Failures": 0, "Exceptions": 0 - }, - "Misconfigurations": [ - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "service testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - } - ] + } }, { "Target": "templates/serviceaccount.yaml", "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 155, - "Failures": 1, + "Successes": 105, + "Failures": 0, "Exceptions": 0 - }, - "Misconfigurations": [ - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "serviceaccount testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - } - ] + } } ] } diff --git a/integration/testdata/helm_testchart.overridden.json.golden b/integration/testdata/helm_testchart.overridden.json.golden index 62d914c2b024..55725f96a6e3 100644 --- a/integration/testdata/helm_testchart.overridden.json.golden +++ b/integration/testdata/helm_testchart.overridden.json.golden @@ -21,8 +21,8 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 149, - "Failures": 7, + "Successes": 133, + "Failures": 6, "Exceptions": 0 }, "Misconfigurations": [ @@ -535,32 +535,6 @@ } } }, - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "deployment testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - }, { "Type": "Helm Security Check", "ID": "KSV117", @@ -594,76 +568,20 @@ "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 155, - "Failures": 1, + "Successes": 106, + "Failures": 0, "Exceptions": 0 - }, - "Misconfigurations": [ - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "service testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - } - ] + } }, { "Target": "templates/serviceaccount.yaml", "Class": "config", "Type": "helm", "MisconfSummary": { - "Successes": 155, - "Failures": 1, + "Successes": 105, + "Failures": 0, "Exceptions": 0 - }, - "Misconfigurations": [ - { - "Type": "Helm Security Check", - "ID": "KSV116", - "AVDID": "AVD-KSV-0116", - "Title": "Runs with a root primary or supplementary GID", - "Description": "According to pod security standard 'Non-root groups', containers should be forbidden from running with a root primary or supplementary GID.", - "Message": "serviceaccount testchart in default namespace should set spec.securityContext.runAsGroup, spec.securityContext.supplementalGroups[*] and spec.securityContext.fsGroup to integer greater than 0", - "Namespace": "builtin.kubernetes.KSV116", - "Query": "data.builtin.kubernetes.KSV116.deny", - "Resolution": "Set 'containers[].securityContext.runAsGroup' to a non-zero integer or leave undefined.", - "Severity": "LOW", - "PrimaryURL": "https://avd.aquasec.com/misconfig/ksv116", - "References": [ - "https://kubesec.io/basics/containers-securitycontext-runasuser/", - "https://avd.aquasec.com/misconfig/ksv116" - ], - "Status": "FAIL", - "Layer": {}, - "CauseMetadata": { - "Provider": "Kubernetes", - "Service": "general", - "Code": { - "Lines": null - } - } - } - ] + } } ] } diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index e93640fcebea..47eaa716f34d 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -5,7 +5,7 @@ import ( "github.com/samber/lo" - defsecRules "github.com/aquasecurity/trivy-iac/pkg/rules" + defsecRules "github.com/aquasecurity/defsec/pkg/rules" "github.com/aquasecurity/trivy/pkg/fanal/types" ) From bb6caea5cbe83dfdf1812814730dc65aa08ea785 Mon Sep 17 00:00:00 2001 From: Anais Urlichs <33576047+AnaisUrlichs@users.noreply.github.com> Date: Tue, 23 Jan 2024 06:45:55 +0000 Subject: [PATCH 098/108] style: update band logos (#5968) Signed-off-by: AnaisUrlichs --- ...ivy-OSS-Logo-Color-Horizontal-RGB-2022.png | Bin 37370 -> 0 bytes ...ivy-OSS-Logo-Color-Horizontal-RGB-2022.svg | 56 - brand/Trivy-OSS-Logo-Color-Horizontal-RGB.png | Bin 0 -> 44777 bytes brand/Trivy-OSS-Logo-Color-Horizontal-RGB.svg | 85 + .../Trivy-OSS-Logo-Color-Stacked-RGB-2022.png | Bin 82511 -> 0 bytes .../Trivy-OSS-Logo-Color-Stacked-RGB-2022.svg | 202 -- brand/Trivy-OSS-Logo-Color-Stacked-RGB.png | Bin 0 -> 29953 bytes brand/Trivy-OSS-Logo-Color-Stacked-RGB.svg | 3206 +++++++++++++++++ ...ivy-OSS-Logo-White-Horizontal-RGB-2022.png | Bin 37211 -> 0 bytes ...ivy-OSS-Logo-White-Horizontal-RGB-2022.svg | 84 - brand/Trivy-OSS-Logo-White-Horizontal-RGB.png | Bin 0 -> 45352 bytes brand/Trivy-OSS-Logo-White-Horizontal-RGB.svg | 69 + .../Trivy-OSS-Logo-White-Stacked-RGB-2022.png | Bin 81763 -> 0 bytes .../Trivy-OSS-Logo-White-Stacked-RGB-2022.svg | 59 - brand/Trivy-OSS-Logo-White-Stacked-RGB.png | Bin 0 -> 28743 bytes brand/Trivy-OSS-Logo-White-Stacked-RGB.svg | 3179 ++++++++++++++++ docs/imgs/logo-horizontal.svg | 115 +- docs/imgs/logo-white.svg | 3166 +++++++++++++++- docs/imgs/logo.png | Bin 50574 -> 26755 bytes 19 files changed, 9747 insertions(+), 474 deletions(-) delete mode 100644 brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.png delete mode 100644 brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.svg create mode 100644 brand/Trivy-OSS-Logo-Color-Horizontal-RGB.png create mode 100644 brand/Trivy-OSS-Logo-Color-Horizontal-RGB.svg delete mode 100644 brand/Trivy-OSS-Logo-Color-Stacked-RGB-2022.png delete mode 100644 brand/Trivy-OSS-Logo-Color-Stacked-RGB-2022.svg create mode 100644 brand/Trivy-OSS-Logo-Color-Stacked-RGB.png create mode 100644 brand/Trivy-OSS-Logo-Color-Stacked-RGB.svg delete mode 100644 brand/Trivy-OSS-Logo-White-Horizontal-RGB-2022.png delete mode 100644 brand/Trivy-OSS-Logo-White-Horizontal-RGB-2022.svg create mode 100644 brand/Trivy-OSS-Logo-White-Horizontal-RGB.png create mode 100644 brand/Trivy-OSS-Logo-White-Horizontal-RGB.svg delete mode 100644 brand/Trivy-OSS-Logo-White-Stacked-RGB-2022.png delete mode 100644 brand/Trivy-OSS-Logo-White-Stacked-RGB-2022.svg create mode 100644 brand/Trivy-OSS-Logo-White-Stacked-RGB.png create mode 100644 brand/Trivy-OSS-Logo-White-Stacked-RGB.svg diff --git a/brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.png b/brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.png deleted file mode 100644 index bd5034c509435e87d3348f07d65b75598d68f55c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37370 zcmY&=2{@GR*S}pUl#;RxZPrp`$xbR|mwi|ET`_|hV^ASw$r@rrcE-NV7)!npk=^SRIMg{iR~H0`Ffp;N zGcmE8JHi1xQQvCH1b!S1x@Q~A#3Xx>@t--YSPR0$B*t|AwvI*E+x2-wRR%7PK)d5Q zTuwS0^on1ChdCno)Ur66dfp3uXKoj%@gEhTd{^`~_D2=ozHbhx$zi(Fao8y5;(4$d zAEPl^t&soaeE&0 z@#-cS3WHgz&Jf8;+p~WkkJLKVw0!iK5GbsoL7jyDKJ%FZeouyCi(ay=HAo%ne2Zf& z1XI*Men@IsbTsw4`}dYD^k31GD3Up0$?RamfKJK{^Z)y->=UINX?VJ9xa5E`*{<~W zSy(-MjnkKF!V`Z7q4xL5vD&50G;a2_9*cm^=l}VDE#GdrH8}kMSXO^4CHUGh zF9lk&P9iTD@ok%o5qKECl1z0RKSL-zs7%8yAP8ebdd9hZYT#$iXjps8N+2g7fp$My zBVd}x9Th6*`VCTeIB)CvMcrpG8~*e#pEOJEt(x^6B#-iMjQ75oH^{s)BT9SDP(1N6 zN~8=}DgTCUsKXSsnzgsRcK%KF>c_)%?%c$^Urw&Qg)(!z=Ukhw+1CHCSr=ddUNYrn zfrzDu{7~|K_2Oj?K~w3-#IPvWA*N+r{^!r?-gXJ}2Y4s<-10plD#d4kSS)d&k6t#&Tu-3iVhn2RybI@!cyX_tl(g7#19WdrH=`^M zEnN+?UUd5YlpPSPJ<9@d;b}H;JV$PAY+~6-J2gq2s5CX94dFR}1%yKi)#)TauItE& zT2@^@B)V|EwKpiE9rJtF%rw(+{6}ECZ%YfE#5Jq8a~qJ0dUCRsHEXv#Fi{qPyRO2W zVK7tbltIPwxB4c--nv3^{#B=~dt}b;Ey_>Si;P!qSahj zL#cRRCQ&&jYm02KPJvkNiSM+DCKGx!E2$%$YibgY0_}!jCchj1wINec7Rc$o%+5`t zvC_z&X0A?a)6^&A7J_QF5BFOt{-VGDW4YfPV^&KTBa-Jd$$vD#+!>X@M)va)gbok+ zNx|0nofd|SH}JtD5F@->swS9y&8XVj_rq1ptG008gaZm)DX6ql1Q5Cx6(wTZ;5#dx zwo@)+iqIHe3uGq>>bG1#8FZndVIlpgmqm!D070hNI6x9Gcr{W*^UVMxRA{Pk(uhbn z&DaH;!d|AyH^xV20aKepN%PN@SS3mof{) zt%m}9)mfDMwo%V98fpw*vn(@ol35(vY1wR`ld7T_D%F8`Yy%s{LLM?3zH@mKwJ(w- z`58qgc>}xA7#z(o6JECUl`HsC6o_0sy0pnP#$S~+0&Le*msF6+I6<>p@FpPS@(_@^ zgfH#5(Vx@2EHSWdUZbB4;VyZ3EltafHB?p;kh#vu0tra~+&|mR2;YAcFrg=O(m-n; zz8dtOef$gz=akU5zTQGN&^Hvy``-d;}Sd8mfXKFC_NS!(+H8=JmaF#Vd7{Do@#80;~4Y4?ihif zoyQZ50~xEHpxu@9x*jl$BHF|x^56pmked0|eku+qr1XA3NGz0X{p?X-*`uF4rgd5T z27d08hdzxVTf!1;PqyR@lUsm*@{Aq<==*erSxwOWue%Fpbc~lS7~xQ&Y#YEHO4zUh zLyr;$)>RHzgO|V>Oy2GUyOp+CW5Cpj&vhZ=VnNo(fBpONIfm3FKxz`m9C%G~YsrseaUA0Wg2xi1 zZi0a74%u@5&FQ!Juj8sdj}p1R1I3b+Op`awaoQ@}nXC>7+SM%sb_?;E|5(omKihiz zqtAq0@l|uJ?J~J*byh;brU+VfTKQC0d1u~7I`B;|4Hk$6kgWjcZp~T3?eY!~R?Yh! z{r~P=Fmz=4UWI-rq!nj`6Zo>(Q0b!fG=Kuz_$J-jbv_J(4o1;<(-UX z0akW2-5zo-czfzJV9l_&;r&5iH0nACDGqKVN3mpJ0TUb}s2r@RQB z?rpsYj0zs37{nMo3p1=6Nc3MW`OX>}kCY}s%uO(O0w}NrI`^;VQ4m$U8cuaC?9~0cDzrWP&72wU0N~Mvn~hb zPiuPo^295-KENVg90deZFSuO0U4z5>HLPvH*SIDK9(NSwzYhHPj_V?|oLc(#yL@cx z+5d^ZzDTM)r+(-APp@OZ>?E#*?`1!JnEmzr6kzxz!0?SR71gR4?a1(nH(8L3$opn2 z|H%w<0e|IAJdM)O1$-!%dkV-giWW(V{*sAQJkAjC{?Y>o^d2y(6R)B)F8)ti0PJQp zV8(rL$ljdX5?E@;fK}&@Oy6(;UN@BuFv%DoD4K47E5f2*p026^;6*~~)p%4V9LNhh zS%7TUF=klYj3(In0Mth^_cRi^u3U{U|352lbDSBb2f(hYN|hk%%F6Q19Kfwr7nfs) zp8k#C|MC946SbkQfUtWGTVezQTz9;b=b3qSyH!{5Y9PT=V!(U>FomekfYdXFX@PL} zfK9SK;1NrzU!VPJemZKRhQNRvZg(v_(S@(s7kwu1zn8HoH4(XI;JXO8pyuw)zIBCg zeP=*QyKBLN5pPN6$ku12)N6e3YZHB-M{7|&i{L)AYBn-a<%)#^w z3ng=f306vSrT&*mBWK{Ydl>g<7NE|q<2{%Sr&-o9Rk26ygFH{Jox{I3z*$N{O;4=K2j1X}HnrHd1bBEOOPw{}{>@A|2N3p+bY0+Gw`WmUW&q|zLmh53#1slNpE~<- z#dAoRn8PRf9S7!Ycd{1OMJcb; zgZqZ;Vf2A`yjxnJ=ia-ff!kzTA^o0;);WreEG>2oP_-FzVT7+!f5FR&EDMEEU@+oN zK2oe~>)jP}%(hU+NIt)h&D#Y$*PQdAQrgOLp&^E4_kZ64u~2URPqZ@CY(LAsg2P`? zg|Ez)a`CZm25Kn&5n-)3G0N2nyz^h^s2zHuRmkt}wAsjsVVJ&A^GPTvMy&ovHeB8IJ1@ zQX;#p^malskV5UKp34Ly3zHQ)$CiUJ1jZ`5&hqJE;2(tVje(!nfY8Feu~joKC)8@r zfTtsm*w*=h2ss4!JfRe|y2*AS%UrwsV4mMOz;nt*=SNNHHTEA+5rPJO2sg@3k<~?z zR9#Va3t!+n=nh~_@WWp-HAQnIMG^5$1mpC-P_^Lsk!jZd*lm+Z-V?%SsUvNxpGim0 zIC?ll@8SD6b)fef*n9m>)ZlcZBeV(v?^`*^@bI^1sS~@&Exy+sh4UiS^%)>rn|7iW zR{JlMT|3Q`|2LdA?X4;q=q%D&1cS#jM>E?oi~IXuyEmyHpB=Q7U$KwI#2&2fnpx?r zC_>4j^$i>7gZ~4nq9|f6&Wu>^@s!-^_28UNMrW4O0P&S-E=t>^czxiljDdmuEwJo1 zifMs;+bHTdiKk~AX^Q{J{JcOB(-nWRcDUz1DO)T?(LYN+Om8%IgC)d$gse8R zO}TbjXg#`7aK8#luXy0{8^$(l?5Pl$gcHFV)FndXy3KKMAcvq21|^ zu|aQ+Q_I>k!>WInixDh{y8TEUM_2CRmxqI78b0fa?JZH>e@i3#W)lD~^*yFd7+gbG z2T=~Hr678=hlo(+RydXGTkfZhEaBEl4V`Eh@b#lpU4UOHyo`dMs0w5hXcNeo+eV0M z*g3mswEUXUPH96a27lVL;!fd-y<0aZ=(a=>ONpb}& z*dYpxQ}QJQ+HqJp?QV2sjMUIo3#_U|(?$yQ4`C882U6 z9++=BlPsozK>2liY2z%;94O6|dOXEJV$Wv;9)+T^D0rF4Uni~)M$cSpGr_(X3(dM; zDuFc|V8aX~qNhG)2)35e_CXEfKmNwcdsT0uumJ99hOccgoLCZLg5A)bCkx8ly9Ng_ z$(nUVHi$g3(d&;WCocY*LwuoK92*f{z}oQjYq|jR1S5qAI7$bptC&HMXnk+R)(TYl z=0K2it`qeN(-p($V(MH|bU~8RE510rwH!2^v<0c`%VWUxsIVDes{dw}2b>lv=xkhK zd%%kMIN8z}0Il__M=X~MdiZcRO4QPGo9U$Iynld+#;3V=E&Pih1x?sr3rbr*L83pS zi)D3W!`hq7pk$;_&?kOH08y`!OmaTy9!tzFKlOG+Hij6lbWX?_ z1AXl_GXp%DV`AY4tGcxO$3^E7!@TJg4U=XEC~e1cVCuLW7np5BHRM4vwy{S-QRJ?7% znRfEviJ!FZSt#v9h9HS4yWbn>;OP#Da4i;)s!;9jfAbS`mARN|0lt|3WLOc$@Bg50 z@wUjXRSl=v^Ui2Uwysi;1Tpm_?8c$H>)_87N~4TO!)C5tFz-TNFD{@S_t@MBw}rR+ zXtQ?y$Om8ulgoR@D8YHqnhKskWc{XIOsES_-mz(aBz2+d6jo-`z|rJ{E?@};8gGp^ zw~+*MkIKHQmp(#~R|ZbMIy@EU6p=L3rIFiTOi>MJh=!Wu%#?Kqph>W> zkTbrL8tPeM9P$$c@rxjJ$2Skn-!PXD47^;=FKX3ED%`GX)OWiYF$dOk{q$plsTTH;BZ-vi$}YX4prVIzKu zV_A3g{YDt)`a`zGkop_(XVABBCR#$@;aKA*O>|2xtvH$ zdaeMv5K-15Gx=`8Sg5r{>5p_Ywp`20Ia$_pQBFmv12UGm*Bk?V3Ro@3-?o42RtPD- zk@NVcSKN`wcZXwrzN|Hi_A-OLjk-{V2?2wJaSpA9w&j=0drrScth+>v6f8d1XHUNs z7tx11UjL7r#Zc;6ZPm-2h7Tf9|B%VMPivfNLMH-_>O74NSi^*oz*>)MxpinG;Pr1( z3rZr>jjO*{AN!5qDbmS%JG|d#_eP?iuhbc_GZ%(k=wJD&D6nqSEKe-xSmiCgFbG_UzoIrLWo7(O&_M%jE9-@m7sbh_r%N zikv96gV;}85}`~FzEwzfnR(b~*+1fCA%`29k;dGmleIDno;*xZ)X+!3u(2^@Vbs>A z7>JN?6IN>)2aTZw2ysmXkK}L(76c@60yzs_a}|+HG!LC2w5T?HEY_69TGoPY*nA-$ z1~aiZ6rK@sf8nZ+;RkScvW6j19!CHj2IH$mRRQ(TY<6N2u`ggq7H@6t`=m)ww)D~Cn9I{%EF=ysRIc4}-w-x_F zI-=yIBfAJb01SK(UcxC+(Cu}OgZO2wB*qA~vgI~U@Vq@2&7=Cr%ilh!d1O3kPLZz` z4^S>7DH{hQG{@;vL~GT2Lj0vuw%{%#(LZ^w%FDWqXGWjo8~Q~eSEIh)11}+!R`Z3U zzAZg)*b_bHRD36a!{|5pJ6ZeKAPru&H0u zzDXBOaI`PcRf0zv@Xi{IkwEry0DZ_?brU9(|0vRH#X9YGsJpLl~dY-T*k;cEH!@R{R%%`17;1FdhvLxN7}-K9TSvrfJmZEf{Z zTO_`y3ugJxT@Gu|mxn*1c*MXOHOUJXN`yYX0I2HPZy%ms&8}{EW*_*g)WKBc2Kdnz z#Dss;I{`$|Jg=kYBCHPxRPROAbC)U`N-5vKZ?je9HevW?rK-S1)%+%0-2)dTrH*E6 zve2+$UfB|;naA#>fLx3BF7TQ@ry(RRGB4Yc`=W}U*7!@TXq*-fEFxxz-@T~ATA#Wf zmnXt>+L{^wP@m8{QllMjV_4<~d(*pQuA6>jVP;8*jWNt ztQU`PeYD!)o53EAehJ^!7gI*tMZIt6Czh;C)Ux|RF9m$&NTLfNT|sCL~N+$=9NQ|=DZU2A7eOVJ31ZR zf5TP-k=Fa?X&E89op+<}PKu2mkCA7eJVmwRvN@&IOMYSS-8>6~Gzt^p<#z0ws01sS z2@>?nX;U;y10a9xM9zt(eaz2RecT25J?GDBX+G=0D--2+`>$J#<$wEF?QNcd>KNI! zxbDuC2MEp+j3z_+dgP$!)W6G|zP9b>G%qPxK#9o`3g_ z>Bfwf5|@>KS9s_*O;WW~NiY7@!vV3c+KIR=5KP3};|`^Mty*JU$6`P!9^O2mzWOd( zbfLHbaGiJWD<8vnBBi*&;xPFdMy?WdIUzP^Ct_=vL{kA-kC2#M8 zDzCvrwc}>w$>(LPj_jug8hs1Z&%KFGS8kTRgH;nh)qWN)0So=$NBezSV_8b85zlXd zn~C$S`7Uy_A@{TIMn_lspDA-TX*W>=fOd*>$bxxmlr^lA+HGWAII^;+HE=wB)oiW8qa8HhNt{Z5uc3x1V_v!fxqIH%iScKLC0A%b8`^Xz(`E z{U92X-5+n8!;83t{hBo|u zYwN_-)4}zea48wDPxTjtbQpuM52Q_ex5`|(Ymm)HiM(dm4IMPX=m$$hbKcd}!atI> zf24J&GOjooeGed=Jz6+WBL@@<+twEo#r2x&%-tKeon?R8y+7j$U*A^w(m#Yk}A9f_#)7b-q2Z%=o7q$^8=q40Vq-Bck^NWx}ku|8y)gG~ye zWuhP=%-x^^OEC1Q=s9MQ_Q-wqUJO{`@yHk2Nn0BQmljs2@m*xjTC62}jqUZzm*>>^ z?GuiPX;_mUu>&9yE2K7Mn4) z{_!Il5#^kx#99E~*|Tu5U0N2?p?&*;NBDljM=8x5Q2GaHc-IEvIHW$<{(WoP;jQPL zr(hzgg^8!0Ms3r~!8BWHiKlwK-CpuMwxmdC|L~t$A90FCB)qe+a-#Dx2<@PoAL2 zz`~rC;GVluT>3}6WkB6hpTFwPb)^PD+Sl{if{D|_{IxFeb85e2o8vNBFNG|8{96Jx zEo}n(C&>05IM3?%ATMcyn{5`7KB!8Zrynm+2^e~mp?@|8qSdqg;2S`mS~O+PC#Ale zUVc(m-amTYPYdSv!uAv0B;(b7Eggcj!>=b*S=kud?%(^TLsZm%{QO+XwC*#q-!*L< znH8euwd}UTW0W-$CWU!+8}3jW>Hl0>d_Mi)6@5*6`JcfYF|XZaaq{66wB@~-6$yU? zEP>gzs9Eketu$xQDQ>#&4ByT_9L3e`NlIQXtF6Rb0-XjGwQ_@u9zAG=ic_Leb}y=u zHfNr6_OED?k@H6PA!XApj>?6GcusUbJoe};u@sp$(A+otV8*SbIK**qh!|qf@Zn4J zr}bK#)+Z%bfpIIK7`x!lpL;Z3M;lI5AWSxxSCz!3z z^cERtLP%ksS!wB`j%Lqhc_r-ux~i;ao>h_6ors22vzo`-r?<1;T>|Bu5vWCcTM_Ho z26?EknMwH?)*9oPQ?lL^Xn63uy~qrZ_n7Zbt+6#cp*a6rK0u=R$MABAxVX0J)bHP} z5)@UwT4jj}jiQUgTS0@)9>0XqS7cq3m3kUFR&tTo(QPPs?gf&KgbnBK(?X5cE=SiE z)J;AeD8cjc9AF&GqCEsqIoz?XpvvJFPzrOZ#@iQdtH3T98!ioQC8_sK4|BV3tyEQ} zst37GgL}fZr@Bo=sWZz~il=}h>OHIK-rFKSkF}yisRaIsA^s7p+VEjgz+)X)MrJlX zzY6qg+3-+v)nzX;uh{vhgn0bgKq9t|j`GLqXidiSEfQ^RtH?3Kf*;lQ<*CFA0o7QH z9*e>?qppn=4)d8~BxmbIVU*_^34SVO z+`V`$*{paJV)+!JETpSD8J5Vob0d`B-~K3gH4&`-h|q4rf6MUtY_Yjw^ z3p^=*;+XO>lw3kBepfqRBY_N;uF`*+DJQZK_kwl84{>ON!(GYNs(o_sKIUir4%Y%f zGhnc$v^>E(ce(((Lpf(z>D4h%ris{-E{^DtID73fOgQ*gG|$Q>hlJBpp>ER`gPucK zAbOYMWjfT4%o*f;vIjfMcSA8!*B_V`M7gZ?8q92?)FJG@8=i){FFBs5IV`#5(daOO z`kH@U0|&h(UFq;`nAfrNpi^zo0-#93%amP|DIEIDL?fl3Yf@>YLY^^X^;RZ2H8G2Y zJU7VmjlWhV2th3GUT)se&o&!T#8D01hje+Kov!skMcbw6F9Jli-t*s~1xJ923K!}o za*pZt3nbsBL39*wLfn;k{hc*)UO>HW`61E;E3zZFQ16@ab)PekI~FP>DOo&dg*0c6 zgf2i2&^(tl4x7u+U+U6DNYEr`pmc+At&_6mewJyB0yJXr)JV79GLkJtr6!8LQ%-mz zDiSF%l+hX%+$2Mgsm#60uJTSf87(JaBYJhnY2;lhMFArg#RS&I>A<_uvS`hnBg%SO zLh0VTP14_SpF|SG)!7ak8bs%MIFvR zf_z;r*?{l)n}v3PPE7>==4o^=y}y5opb{8)80vH#1_~d4t3}iLhRhE51-@bHz8qw~ zdRKm@?L?LGu=~rnry&F0m5-lxoNgsH40hE}y*i$IL_ZrLZoih;4m(giYlo1ZfvwL4 z9-u_uBPiEOhi=py%J<{eqk>QJz80bx=pR+USDoU#2W+FO$r*S6k1Gp==UY_fv5kko zY2xx%Wok5yxAX9&!mzO|pS!{7b%=^r#n_FtSpAb#xMA*+G1w5<_0;>);^F#AtC8p< zw!1q{v-}-k-5P@|e2NA8c+HP{xY7f?VXTKHb;sg``!BiZpHHZc*HrnpLUGB7HA`{d zyS~PEV!Zt#`~?n99^M*srU+LFY`2x%VfAVo&|S6=Jj{SO%Q^24zWiC*=Q*Zsz>XQn zmrPj`Y}r+QW{>}eS_N(Mrpv~^-$X}l1l`ujls=pJL@Q;Yob+_y?FlXjW-8`AtEi>_ zibnd%FTJJB7A<=4_Rz8u(R2FPX&UdBEQ5Bh;P^b_F9F-p)4Q$$DAz&P9XRr%u-K|t z((c8PN29*;Ny3q(NdL}Fq^u(EW?TOiN03UGlQNa7Vxe>LP1>n>8`fognyyp>2s+M< zP-PlZ?Y<31-CrS3=_FF}4(Hpt5xkw8k>OX`XK!t42@I}mf9JV`a`YUu{H)h`(MhK; z()-SwFM(&6=ezz!tqJGb^EK5xsCC6%`zTtPP}Pwp3Q20v&H0FwVq zypB1#?wXtPV$7q%t*P$5jvP@}fqxc$tg1FsMEUJ`M1yBnXqqqKS`}Q2+COkirfF`l z=}7{LZ;#d)`E+J0arYxahh5B$HME<@&WFhDG5OATIP}N$Lf;+LxkmS(#Tx@p{IG%i z5r@XP)fv4thEV=U3bz(3(ez{4y(#O(J2Scw>7)VE z^F>-|-7~SFqOMR|@(~S4v%WiV7wRJ`84O)^wyN0v@UvbK2V%jt6p@dDVG*cs*(HIXTT9XaSYFSh~e>= z4O)EPH!5n^?ECA_j?H1G5J$2-^Um|w4I%Pu>ty)xvX@0Y1?JKH#>zo;{+YA3;ztov zm0FGf@FZHtuL@=6DXN#qCeYvYgN5UV)|-E;&W7{W9e#S=-dEqA#KgzBoTiWqvS_tMoqju9z zysh*?=b|_?js^gh=1Xt>0WeeAsB84O&FS6mXJYkPNEQZN8)co2Gn70vCxZr#fUv`j zvOuMIv4#^|QMYy_T?33b*0?_KpO89L{i>10p1rlLSz#r7b+6pdZrFO$R^t$@bgnGn zZg&n#Xvu(e5l(U^%6)=1Gw*4WappzrSAKNK)i>NMk4%0*GBsD{G8_8x$BZFvW8rxZ zc8oXu$H9%9c6G`X1fKnEDU|DC;?*ee3Bg*mWG%>4#9DJ2osec)8v&c`@78e;^*S=u zQe0HQAu>C0u1w~hwF)N2DkDio?14DC5oa=N-Hp!gltI?WgayKA2KZGmsUP6SoCQUT zN-=Y(D3*prMSsiZ9IOqix;gzZhmv(VW536qUK(P(cl~AnJmwXIPst$fTb%s}?6Xtf z^lp)dOh_1~WJ)PObGp*-8Q!?tdu~Ac(ZCLCi{sG3B2ip_+Bs*ubA!g|DVyF=QeAQS zsYOVzGxYApD4VnE4V?!&%&B#k=P%OZdOY?dF2=5?#7Xl+89WvVO`@u@v^uylV~X-f zKywq%?j<@YfS$~d`X!DWd!C`E-p4)hXF&(7g`0$n zE!B6X_s6LOF3UU{86HO0)a6~rmU^GBCUxKR!w=S3yXeD!?+$H_6f9cLU-JG-X)_L|@>9u`L!|vmj6sKjerU$Dz2SX!d zqmP!OmvS!TYtZM8h6nEMewWZZ-8NmH9x(OHe!K*`7Vp{6Q?6OYHH*CRI4Wm|r&P6k z;#cDZ&e56qgL3_*5N@GW?-mWB#3^>7xY8o(tLl?SJg=rdu|iyNUH-JSO1ffDKNWwC zM^S$#_^z|WC7Y3gZrHKD(LN&U$J;|P{BS~s^Apk(Ju*NTz z?n-Yoatb`>0rq^uMv9Q^gS%-%wL0RG4jhlG{p~Pe-@Fgho;Z$G4h4mASc21v3p8=6 z)P5^O&eVDaGw|#j6{jw6v*h@k;vFaE^JzZ>N+54Xd_l9nZ}^3gJU(cGTS`b0%aIvB ze7`+W`kep!r;{?7(*V=mVoQ1Een+6@yW2zDmi7l9cGrdlJ#%Nhj07NSYh-%~?$=)8 zJfpN?5-vj4rN6H@W21XSp~e!h-QQsu{gs^>N8Q8INux%Q8OI-ZAv`mLmQvfQpcUAW z23Bx|@ZG?hK_+sxPR#FkLf3MvUmp_@jup08MO&4-ls&BPoNAP+{F2jrciq6|7O_<* zf<5nr@k4u)ZmTur^)oOLiDT%bQ;N=g`iDW1rjxIjh0083bu-c#l-a%P)%&*9iz}k> zE$iU-dfZ;0Qh`=c-?~#DL}vzfC9533O*8aBt2e{&1MF%CCbmneVEgC~3og-AN8C^y zHS{PSU2;+XTp2Pv-crkNI@j6L`^FVgYvu25(rnS@Los*n z54GO!$n{+?(W0q>8crSho(vZWWe}D-Ju^In$_7q26d+-S!6GEjM@>Uxi1QDVsS(M` zNfR~hKZwh&qr^9p=hbrkJLlG6z=26`ZE ztFOF3zNF$U#cK{ImwXpbi%GgTv}oJd|mc3<_5QtP-VbbbP|(lSsLI~lYwj1xW6m=YW|M!Yzr#a z#j174M0sx@qL;%gM>fAOLXcFV&(FRghm;cGdEVTZu8qt~NjPo!&z#d^Os}xb_!PHp zxA>C5NjqUb$OW5FdG1*u1ot}l5{50rw3HR12jsnGUv7ug1Ih`(FSnUgw3J(~l@KhM zdxtmA?H8J0k8@2a?p*oVP|UYsA#~))yW!#f(Yczsl4|>Pwq3PPjeXt^YiG(`=KHUB ziO%@CeBRtFPzSAK0$sG8!##mJH2mc9!dd;V%cbjc>oZL6=1kj8V=$vvQS|da3wp7f zM`y2@5xa>^&4x~QeP}U-_1Zdv6QHAw z{cGsK#lLrlK`QPWw5`?GBnv%tb`s>{xnj4Iu{>HiYF9B1rBA_q9J!$(zfP1BJjODc z9_hy26YgaeNpbAj*x&hM*x5;!+3iRL+Vakt0~1>K`sUza)44M1yed^;kylb)HFg(F zMk3n;Io<0^u9`q@o=GdYINg){;-sPGFtGHoJg;ZbNde8SkYQ+LfKM#S^`H0FOh%so z5+U*r-Fc^h)U?ymu)U|xHQ_qtQ_g0G{p>a=CxF$e;K*SkWmSG%&YEhdE4k{dv}n_V zqTJMl|6}B)+`u&z$2c{>{r1BIxHSXuq_yYEGq20JWKSpdkw-I}>%EykWOj^()gM5V z4X=K!C^8;b93htpR`q$9n(-*(3I^Ws=+FvkIy*neyMUK2%;hM#1Kml(xkCf9IaSN!qvp-L+ZhO0))s+bnIJ4J@zb7WIip7AwO(j*)5R<4&C3q%Hy7hn~~0Oyx5w=^wZ1@2sP?X(J=V|J1H1H zW}r$2paPY5)}EsVU+KuK!rvEQ2XgB9Vko&S+|p4yunPkfGNwR#X6%e%UBE_Qt@0kH zWHooG3Ul+4%OBNPNhKRm57u3be{&d&TW7gZqhRdEu8=}{9Wk2fAP9U>-NBN22krY^ zakaCo-e#a#239p0sN#|A`V`D=o8EPiUpZbjBsONDGe`Fwe~gMPy8n%0T9dFa3Qh5u zYJBJffzL!{`2(lgm556gvvpt27Ae0!2;}Iz@+gVe+V6yUj=I=Qy`mJqusp>#OI%q< z{!Bt#^O!vtGy43Py;_B1`Plss5oQaEh^~WGRe*l7tTMn?{K)=6mT_>pA zl6!Wtx3Bgssj7F`W z7O9QfsW}9kJSPzPnDaMkgBz1@bShX<`EIBM_pCLkx?`)rd(9m8BQ&E+dB5TIImR`k zi5j4@ss-U#N%+g#IJfO)9LVloO6NAWs**XU!OqS`TuGJI!LT@6b~o-_A0n3%Ky}8C z&j9GF+jBVVFpt}92B7AAtRb=U4G8+D8-crs!>_xDha193C4dFGF@FG=50f!yZv4oq zL_S+7eC0%y>qG?`i7Q^~w;Rn#mELaZo)qbHNquD;1Yo+WZl$WWjAkY(ztG?Lto%~T zq7z`C$ezCym&V3@NrMuIgOlHG?ZTslU!)Pcs?Gmejn_1WmLnn%$VKhs(>XUaQHmy#H2!rl2>P#Ho9Y{onQ`><# z$(kCIhj7iqC2|Y4W2(NA;HufSz9|9o19qmB?;PdMALBUd@b-EV0N&?a$}7@lTrEV} z@6;wKGcE&8$E%tE1Em-is8i}{2JnkfVE}`(cD@K4V}=U zWsNUjSJ(WVuat#;ss%bWCn`ThX}BFylX++vaXjYUK;t!h>&CSbpgq73Pfa89ei*~? zUhTF#5#j@LOg?hYAkM&(@*LjJi)%$X#<^C!Z>#>GGo#Lk(3862ooao1DO`OoTu zfC8k-p+YeT<*9jlQpZVK=vhZ-#zPa!uZ4Ut%fU-mnnHbNK{u)Op?kE5B;@v{tArOr z6)&JFHKTzS=%iQC%nRUtTmNL>i;1BkY*9(|;^z{nu7gCANKAsQW z{~5HCMp&n45^|cQBR?#v0G17$137CC0Lcb{Vcg`<=oh@1CT3q+_0a1?p|(Wh`?FrT zEj-V58){~S4lY@A7wXpG#{=L&zOxn_$W-~A`SxVOB zaHOIVd+0aVrQ!_m8qEX(3Sc!T8<61_<6PoXY?Nwi+n4N(ju~TrKI+e23xFI^KVh$( z0k9Q&Jo)x56Nq>TK+%WO0<|>`B!SvW2aWqb@lQLF*Bv@x zN8Ck+MSUo@n2ajz1Z(uq3?(1YV6)dA0EYI=@a^Fx_bp&xO_DX278>H{J0aW3pBlXX zTj;yfE7k)$gS=AUY)?v$!#+)f!ApP^n3uRl%O#j;?c3BaVE64#^Vh~1#v|k`??W$T z^!^P%e~WY7DgAP`{PV$*FDmXg7R_51YR^vq#w<;!|3k2U>?i}e223IV01jEQ+rum( z_xXh-3j2zHe(FsiIKbb|g3h!vIhN{5S3`YGPx;PPnA&zEFIn?jR{`z9Bk_eB^_m?E zHN*9zQ8!ZtzW=RuX0hNXI8icffhMqqoEiB6m}mqq@AOAT#7O=izaD84divBiU9S^) zz~!Dd#;j{TI#TNTp%oohXp&QnmhT2TYbaTqUd_v4H-0R^N}~B%o8q8{aen4D&*~=wjO=r%69V7xJ+hUk^F6?bQ|$iL zfCLfm#=@1zEeL?1`?=M}=ibX-Wns(88Ir+M(O5$I>EE9p1#l{wWV0IY%2Ssa`?<=0 zs`i@W#-YV9l6aTmD?3oTIk#ok*{Lxjc$1W4)ofXQd| zM6MrgQ}kam-_+lOT@n8Xc=P*Z+=SyBH~8Y!f&+*<{%{{AdL2pIhkX}KVZ6N14z8`F zM$jv3>PrjEIz#;7F?YFd(a1ZCp^zWeMZVRnW%dwpdcEBcrK>KhK^kr?N(1nPfA>XT zXCzJJm}#ZT)cK(1a8B4OBLKgffzyEQyVTN2zvpP~`zvldr4OllVw`osr8V{vHvjbI< zVW8{>+J}0#$azxgxB`^ipG=CvdjvST!$o>%JK#801pB(`y|$pRUuqmXs*Q zGRC};!-Qosxr7WDs}+HyRje4mosZIjdCFDYVP33bZ%y#th=RRsGof0$_ryCTryBHR znV$hV^+gv; z`wu;ZDOFqO!KvIOrQ3jp0)vF3({O_ih@5U7%8V6?vKbNf4ZlpI;alM3Nd+P)ecmF| zy!)#pwT)P?yz>=1&l~2rcu?1<_DSypR$Ns~|E7g;G}SZttvo>8EzmZrfG+Ls;Eqhk zkLQ5fjoSKij$h>is^=MJcbZ^)e`K%5QTDh2C`9Atgjfq%g0pk^7IQ$B%z2+MqsD=C z0QK##g0mh@C4ogN<=>v(lxbOGT(~m3=yEM;oF^TCF8}^rfK49i48SyO{}TH7Wy^cJ zXY=sF(DNtV@8mK5By#>s9^sJbf-3=8pwJ_hw^o`~2ci?E8p{XHZ~6YNUM47r!l4z1 zv|1p5v#+b5Ab^u}dDX_jGd*uyd9k}xPi$C491dV>-e8oRTqy^bT~6{p!v@7adT4mO zVKUfKH=4R5^VIpv*G|xW9~%G4Hj=*BnbnDVLl!MxreQ$8%<*_NqlJv$5(}jVgF=D1 zzyYU1pg4U3->KB=$`z4WIsb)Tp~cL&hmG)S^In77r@T8nxS$TwFzd_Ox41?`Z&H32_Dnkcy82?cHjciISvqh4 zobBvo`E_=iHfhr5{XedrLx?|L_9916iyArdz>U4ouOnjGZ?i%4m*1=kim&imYez2D z%9)6O*oaac`LvwEl2dBH)&1R+{$kFray$Vaxd%rS1~yi7662u+X_T z=j((xSP$G+x|cr3h^kSID-W+}r}9y3End_H_xaLa!Ri%*aJca_VMFX_dF=N*tjplR zA^we8hudJzP_G{$SKP*V1vbBp;OW3^XbJ5H%As0tk1T5X#-JXch~1r;NF+M2R#r>J zIRNvjhLPEnL6U$O>Yb?lUMNkc{Tn)4hjFZ;gGO}F#{mWSF#Z%<*+7Jey5C?9jH9#i z2lhVo00R<@IGpa9CpRgdYs6@h0gS{COhUXEo$@J_eTXC;VGn~p`gC8-Oy+Z$i&i!okYjd zF&s6p53E8!-Lw0B{AU9~WnQ$v>f=@d0&q>HvV2}-LwbvT3c+&F;lI?<;JogmhbwJ3sx4Xc?F%*a@*5W! z`UZiU!Tqa?u6S!_#m+;uYwwAHxc3lpiwrGC)#VlU)GnR&=QzZCLaQbcs_|3$bR*(N zeK#MQ7Jh)3Mf43^e%Ql0%27O@nTFrrjL!`!&3PPzS!I)g}0KvGX z?sEPP+q#VPsoLb!f$tgq0B^Oykt!u4G)@4Ws>1Ydf{h{qV}P3gDi-JBOML}`y$bbT z{PUEZMw>|PnACM;tpxj&2Cp3yqP>UjkLiIRM)+r2y9iSsK0H z(a-Qhll*YZxp75Xo2 z?o_SccTY- z6>U(!EhM7{liFS*sN=L-oR`sGL>JV;9Qi2azKQ@iX{xABgfD$YMVcG~G5+iX8o1zp zvG@SOpnYI`3{8~<5vV65UTewkRw<}KD9`0zFU$EFi3M&bU+8wT&eGFJliRi-Vw{}iM`rpxp-`z#?+1aN%LHI@BrxWQS>Be64`kk zgI)X2+qLUTnL&q;Z#RGl+o!JXH9cg-v#hBqJkZW4U+zT4el-*x`YQ*18wX|p$XM2` ztPDesI*$Cm^yXV^vog_jUCd7yMz?q}X+T|GF*ZZ1;-2i992f&;zs5E8lK-5A<_@Q; zBCuJj+M0$Jv+dpMRxM(y@EbVZYlC^9bv&8L(87Pe)C|aWI|ZBx3*pZ1}B*Q4st2i1H=G_Lw_W!~eNIxW1j2Bf(y?M+7G7NwBwlb$^zj>S=@wgkRi3%Z2zbiQ~?k$E%&wAgo_II>`PcOFpHXMdWL{UMh>a! zNwXa1`{Sx_l?Xca2=f!AGxev`!OWj4y{hfcs0-%_I5q?x`Gtl}KNLObIkO3@Z5nlh^kZ8fr8o3L z2N)EW+0VeN7iRHW$ZIzcJ?MI-<<#IsWooAIculGjxM%nWF}sY5iAT3Qn)%uF5;s0G zEmX*y8?_eXaRL9gUrIt%ZS$RNOR`mz%HSnA!ZfA)V2?-r?mNrZI*VbwzV{oElHhl7 zrW>fHp*Mph6jJrfB%QgCzJ;zQw?B`u zq(*$TtveA=ni8%Q-p}g_R$4IvIUTht5KOqD!=n&`!c_x9_~+$QBJY9^*WOk^QMk@D ze;(L!rT}r(vSf6^_SL`uFo*{p6L*x*T;|Nc33lFn8#J-&m%KzZ*T1gD9s30!*-Z=fqKJNnHo^y3y z55Xp{?w8L8*?f*`h3m=Jvrn*4l&G+A-kec&Ud3n9?`_twZRy5Q zx=$`!Ot$Au;-kM#mH4?&CdNBv*tXc;M&X-6I7-vH@)47ixbt~PhFz(2MXD{VhnV|p zc~c#8dRN5!3vIp0-97ZG{-#F$$la(=n-p3EMHG^5U+q6sMN2vPEST0D&F3%zV7Btm zlz0F7;-`5*tM9F`Y78R~Q=Hi|o zWi%K=z(@KmOy#N1hwLY?3x9ZI8Z!d4d@SFE>%4Q86TY#S;@RVRvzaLN(mqEB{N58K zx!T`+gNib{*8GfQLL2z0cERD%0aU2ux?#v-$f;hdVkTgh?#>{L8h$BC(?%whHcIR5 zx7dl%yOHt&<&CV(*o9Pyxe}`tWgi&~l8dR>=T#!J*7BPpBeCjRF=h+q#{D|wf1zKe zhKPc5@%D^p?le6beGtnzk|s@e=^G`AVeG~O9@Ss*yQx0E&a@&2YA(EFWWxIs%uZ;o zTAj!sT14?khvc6S%Nu4QW~PD zW>NPxLYrIN4fX+NQ$=ao4Z$@D_A&{3!~Wdr)St_~7B=~gX6Sacz;4&6R0Ms`yBv}a zh{+}LJc#t(TL#L)bpOej1koTTY*j4PHv{3V)H~X6)ux&+)p3#>J<+znS2g<#KduGR4{H}sxGrUkPS6@uwPqoJPvB6vK=5V z9jz>uwBU>G%vCsu*Q4@EVp|z;oRae_WalfdiCfaVX0iwa%zq%GxksPwFDJBONy-(g z_B_kBn&}T+1C30ybBm9G4Lw1|2z9m45N1Ig4JrxPl6}jlA1o%7Dcmb*qWH>6cQpsV zjbK#6blw{WOJCw>q*PcRqTg3i1JD9EuaumfGIQkOGaKTm{@yfWi$+4wg-oL5nZ*+l zzuYMyEe<=W75GgK(e;v|jvR%Mp(-;9Vz;9J3BJuNe#1QyDqn<6{0S%fE}EVy$$~dS z4yf<8diL>QceC>d^?73z_}mP8irTl%0>n5)C50xawufQxI*9rl4{%JiSB`M+c_#T* zIjf1#sV>EmRtTjCRnWvI3}q;U`e00`e76d>&3+R<&6BCOQJby`P&3Zh7L$CXu*imN zonU>6{v)7=gR~Ltkg28{vDbrGpuVaKfKUi~i{50}XnJc>$R1dS5X`#-rd%+sn0T~! z9qOFX)V2u80Dn++DZ{kDWWK>JR13_^DQ82Hl5udm&o&6u4_P>4=6TgwV9;o5i5y0{ z<^>Jt`|#T!c_SM1OV*CQeVZ=#SBC4#+g|A|)cv=aR~zL1GUv<|=OH7)7qd5ssdAmZ z5BpXcdRF(@oG{$@F>nAuj z;H8<;ZbY{1&|Vy_MY+LCPN?xzKRSIs3-F+p)u%Lj%AcZzMqKwU@1zQm>P&y?)V8P~ z9o8$(48cY~CX2rZsJH)z(`=BGYuX<UJDX}){9owET$;Oia8pbLi9a|C%$M@d}$Yr)C`rA?A&?NGhOShGg>%j`| z(dSdu9IO11{t2y#a&`~23yGE$sh!g%T*OiK^>|0qOqJMN;RQ=;kV+ zcnP18F(5Jv0iS!ey${>Rkir5N{QrmATPIO_}a~K5RnP=6~S#JQ>K6F zdLG7&uT*mx6X??)jHyTA_h|QwTG96E6)dcxZ%QM*D5`s&uaaFq8u5|<1W(K5W2L+*GZv?8 zZ;Cb?ShTFyja3kSk;#mtzz}V7VwJRAg+G`1AG-dEy1ALtc)-p2<-|7hL;S3(;6Guz z8o*!j_hRJH{e1zdZ!%vA(@?-QE3@U@D|boUKN1{yZC(yvU)x>X4|t0)8eZ8}17p)BTo$?DM7Q5jGxUG}YW zl2Hx#EN0OG-Y+v7%DBIh87bwQqb7^Un%P9)8*Fs!vrXTk(8A$*{51B z9daC|hd&Es+A;zv=1}Kd+);|Q&{Z$5b4NzbD2+nKr)HrL&|9z9E<2h(2qnplW&`+l zO55Lh#!9Hz;Ys&(+_-4;c|7qs36#O>9LMNt?-S`gN2rrh#<|vxn@8BzPzO-RIzN2q z{kT}z;`HKM-eJWv8W$Qs6NAZVrIG){n(&|6SR5IX5`sV-{v5z^&AaP&Ji~Qze$2p> z52(pJ>T2G%u>K{F0$V`V^eXD=M0=>MM3+XQ@MNIv_2@J8N}ZMa&CUzov_erWP&A%y zYT7iz8h8gX!Zm!jxw8kA(lQa+IUNy#eXwUE^i9+C9rh;H<8(P8O$#QRcBe&ygI>P# z<0RVZfmHX+PILf0h5x6u5Hzu5Z2t{*>lNbS_tYqs0LMWR{8mXlXcHEc$+JD}fYFg? zTl@?)BQ_H!f^<~W<1Vs=z?c%{mPa}Jvp+a`Un$3TurcqS{Ul8~Y>=R9>Kby`4!WT=k*7W3KP{2hgECRYUzG-^$NUlFx{fb zJHLZz^BTazE&z`wtbF&v{MvGyqqid1U9r>T5bzDq;p?=!WAk zIn*tU2yX~oqHW&k;bib#m`V+yz6?JW@{otuFN1rq%2YpMZz2j4m+;~$yekfR2h<)e zPFtNKRveNM;2Nf=Z$?on9Ct;ZC%R+@2`n zD}ex}xg`A9?^B8pH3F+AcYm*Ee)g#e^Xe*G>I3wS5?DFwXaV~hX;3byXR+b5XF;y8 z!ThYFyLY`kqotfOp`-6K%5N9Cy?o_RvC2VV?8G21E_D72lo!|31Ls`2>UfGV+o39l z=rEX~^SS9_2TEL-m2hOeyPQ7z{16OF8!~I67x5^N`OO81wH^(@qdGjQH!lkzi|WHZ zn4mv)PDM&&XVk?(VbCN}+_N2T2+{T)OQx{L?*6y&l%D48D1bM908%cHQKu2EqkAXv zlx>V3pRx$WiCH{>W_+~dSorD=0~Lyhk0G6MK_sL*ROrm#UFyaqFP^sO60g$qfS6U1-BgjLSl*@nw~)r4pOYeEnEdyQ})P{P5M-dQd+YNM+E z(JU#%V+xhILe4`NlKor=tsFOU5`Xdf zM!;XqE;?UEP`2{|#!e`>thGAZc9&axt8s_dU1ZA%+~N%}smE1< z)}`OddhVo_wGF24^aK$#4PDh&PFZrvQbge@U6}a{)@_u$2hY;c;32D+tNV8W#a45U zKwQ>SiR*R3yt|1R3o}{5C14bWvBd$^b}@{F6gU%L#-8xqy)RXcQ1`d>g{>T^&yBjCT zdlnpB+ZTCl=b)RGBDDnN2)B%LEIEVq{}dh$2`36x^qV%Sbe2bd`X$xY3^z0nXZxee zymAt~pOxvJ{bbiqign2;BJ4Xqjt0a;?r^~8&f5-1=$kt@Nw|zE>DK>XDaGF zrgG_n@*U$@|Jvy;Qbk3EaFzla#NkAJ8M7NIXFV4kNxMzdEF9k|dd3ot``~E!j-Yz~ z<_o^N`0+5m9pMu6w|h$$AGscwt%Y7(N|I`$U852>GmGlW@nV(k>X=7?Pk66Y_H<)x z`v9h@#Jg;cl;bb|GHD!~{^UrnyhFA|+_oT#r!$8c_?4C|eo*d?@!qLn&nMa|N~INQpA>F=7(34!dZ`ybk5Vfe!m<)DG@4^#-Xp*rTHph(-^ZqSyR zG5XwkYbQZF6!(n&H?cy7&eM$=Xo#u*^C0cUkDuKipMPfg^#v5H>j1Tx{O5E)dN~1D z6a2SIyq4;=D+o#r8A4z`u8SM|t3f;ZCFrGcLQe9|OqX`y#8I84QYN_r(V$9I74bx-j9ELwgZ>pv+WJ zDc&ISqlg9hO$RFb@hzR>9p(GRns67}`py{>5#Gm#hZP;xXzwV+YPJoeP;Ke~V&f2H zk_qJlyJ57rIT(Ev&IjOdf*JnpQu8cEz$*ANw3-oI=G!^OC^s2CS!c=v4Q=N+(3Kq!C#&L=m!%iY^|Vxl`mv=$#Ho%QC#Rq&lGqPL0XmD^4(9JF?0 zQn;0E@YKa231B&0PChamn-C^u`R3}rI#`eeocg5$mPp4vtMF4vv|VMTge~Y2@k;M9 zA-u`YXl6p*7tI;4(PDZ|`Yhhnd=4NyUChqVyJ7K~A{(ApJ{)DJz0Z&bf#WG+E<|;G zReEng@e0KuTJpL%=9&gn-ZuFQVr6x`?HUvIoH>!boKOLv2b>H?yzp8bVTRC7Nz%*?P z1JenPpp=6fJ1xeALvQ|cE3ESqK8zdfWpw#dYV3ddQ|*15AF~?*xDA&9wjB-HZFqTg z-w^-~3}AQv`g)@|=|4y88LfcVJnGd!J%_&NYwuIiX~!@XFZnVxHwqFGU_~j}enhA{f6L3`cc-WR6I;WcnPeJ9rs$1KPi z<@lDXw-gkE56Wr|FpZ(1DlAJ*uMgw=r4a{Piq-?Ce5flXQC(+*iWuqb^PrS^C5!(s z@7d6T>UNgQAs$dZf6jO$^rsW{H;Tnq+^*!q{h0vTTTBz0nPmwz_na&lx%A22EH~{8 zbM{}^`R3WkgnfpifU;|Pj0kR*ZpFM+^wKI@vg*~Ewt#`doCUBVgPM)+@a~lRbqTKR zz;8866Di4rMlQj8PxoIoJ5)jlHsKo76G_eG_Y(4I9NzDhGNQ*XP8N}_GrJU1i+sB7 zKmE7X0q2O&dLIuxQ>O`}j&~`ApU*qZr<6%^Y*#7kL^usmSAMPWqPNz!sE>9Y74Xq) z*?|4hch-F@{69tEsjS;C|J`cqT(E2S^X_)hEm5tS{mG)G9eLCpk3JMv6rF+&{Q{br zE_WOl(z{k@&Fe^o!#1t;VX{g0r*&|grxiH(JT)U1${#=YoJLSB1=D(?2tjk)L}ovR z$lFKzTx45iq}#UFpLr&nVB*|&)<~fo ze@60ZmjO)JoQWB(bCaVF%qreoty`YbNg{({@BBP!FPg%PdU~P83W`SZe3plq<3cqx zpdt5aP}8$uF0nPE`u7x~gPD)Oge4U@W;g;f>1vEij<%o{m}EOvs_;jj;~W=GF%BhZ za@~bA3c~x-l3>OnX;DMoCa9*q3_A__KuorM>g=;PMBRj^aLl^m(BC z1o;|W5>m+OP|5VOoWvG2licrk!Ot40yqC|m1~be3V;S{hhhxI!zBe~uue_(6tSB6R zSc=LFZP!s&qV0_Ka3}01MrhA_d}`^H_LFQ39I((+eGl7~9v}p0`+E^;O{z`U|?LNZU&w_+3cgeeP^lrs?`JAhB7P+Givjn-t+RN zm4}94jAYSXWN*4X*TGpvWj2SIw2P#Avhab0-t=B|rAZ6SU2AA$ZjTCZoo- z9NX}IhtCWmU-1Pcz@xE=jx+&j9ziW6ba)FCM&4)TGCXIt*Ez zOXxt%Pndnxo70`&kc>C0(n++92JVHPl2Ok{(H_ekTZzJEPEs*_&D�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 KZ{=>nh5rC|#*Q=q diff --git a/brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.svg b/brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.svg deleted file mode 100644 index df77ea97d3d1..000000000000 --- a/brand/Trivy-OSS-Logo-Color-Horizontal-RGB-2022.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/brand/Trivy-OSS-Logo-Color-Horizontal-RGB.png b/brand/Trivy-OSS-Logo-Color-Horizontal-RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..04ae7cd4e9add1fbf34ec05815a4c72bd0b2f2e5 GIT binary patch literal 44777 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

G2}w})K56G) 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

Y{twPmd`w%Nim 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 literal 0 HcmV?d00001 diff --git a/brand/Trivy-OSS-Logo-Color-Horizontal-RGB.svg b/brand/Trivy-OSS-Logo-Color-Horizontal-RGB.svg new file mode 100644 index 000000000000..9cdd1b594dd9 --- /dev/null +++ b/brand/Trivy-OSS-Logo-Color-Horizontal-RGB.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/brand/Trivy-OSS-Logo-Color-Stacked-RGB-2022.png b/brand/Trivy-OSS-Logo-Color-Stacked-RGB-2022.png deleted file mode 100644 index 6cb94ab62f3f61aee7f540e17bf62f3d871ef037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82511 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 b`MGv!_ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/brand/Trivy-OSS-Logo-Color-Stacked-RGB.png b/brand/Trivy-OSS-Logo-Color-Stacked-RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..de36d4fcd7d301c7a18c745cbdd4c7e41e726e70 GIT binary patch literal 29953 zcmeFZi940u7e9O>LzJO1lOiQU6miVTRFts{8OxM;o)V5cmBJ~RG7E(=%RDEJ%ptR= z!!c!6X5Mx8Jm2?y|A*i2xvuZk^}Wx1@4fcgYkk(*>$A3JS{kZHsoAIz1UY*BnvxEJ z9KxXgqoRN(zvvxaz(1@W$_5^~&ek5@cipUzE0)gptWI5bylZ2nV|CZk*Y%5)41##1 zUst+v%V+r4m}ZuxVLZ#9$RtTUO~2;I9+3=cp%aJGKJzg@uvLovdiD4-@zT4A!n|Qj zDjqT-rQXq96v51A%^sW%s%gM2G8rFB0U5 zCd`*+s;l5(LcD%j2f;QRhnGX5Nz<0z^?n<|d@!^l<5acgLd<=@2WLi`1f(PToK!1} zC#Ew0eIK1!)SmxTC9QS}p(ca=JW_8?<$@HrR&=Ty5^s(^D)flG(9vp6kOWyzKqwLR z$a#m)dQsP>6q6+I-`6x>Sa-4^3i5~H6EAY=ki0g*^Gei6w>l{Yl5_jQDKoHTw0`S!;YkyqR+196*CxVJ2`*J z=kS#L!^lmJWJQ7qnO-Zcomb|}NWOZ;y)7lQjz%Mh799yKqLC9rn#LTkR@Sppw;$Ql z>-u^)S76Q^LHd>rznwsqn-2_(hgbvW2ln0ihC&wjnu^40OW^G$?}K@d74L(9%I@8z z&4XPlwZQ%9w@=oVF5?5gwzuV<+U;@dlG&^;^l6(nVXHz8)Ct{T_D;W^+FH zGjPyklk#?&Yaipk(i>>{;Qhb5kp@cNd}6F1R&;ss#NLZO=Y75H{-ynz_1wBW@9 zb(rm712GI7A7Y+D=-^2o2njH#j7rF~3PL z%a~p|IK_FeBCM`KXzcScj;l&Tkjm5bB=w(Qe+!TDmZpbM(@ibw(;iHZFic`z2=7nT zUF!;54{j2Vc~z&b6LJDcMK{9e0(HncaSID$AHL$Kk^F$2;1sU>sdE8;hVG5DuBGf} zSf=tkVuuktN=Og~970(i18e6gxOiSBD!tEX`nAwO!!Rj_;m4@GpN)Z~EpvSLlLNb+ z=E))0-(ZJ>mr731-^`ztDOyDEI(<_ijsnyXq{xvMFc4FPkCn}HisfBjWlhok3!r!b4xvm0#l@Xx@RM>e6Y5sY>O08z>=A3=~0K&CbSL= zVcb=&J_GSq@O1{3?zgl;#E45Rw~zie=hs-$v~${*>I+W@S*4fcT+Kj`y;Joh-R>3G z`-jB6sOhX6Ls!^HIcVCpIpp`Qf4Q1rf0&H~Ig*4>Dringv43T?LU-XKapAh)n+57LTA(+U}?8NJEb z_b5viWH-{gH?P*P&2cw=IE?nUB!bO7TTh}@2nI~bPWYtwOxeR`OlJGogn<@nLeww{ zBkByD%}zhwwCk`BzV_TotD$zWEHvRAZe_ZlB-J%-KX-u?DGi5ZD!V0xw+xn>`0yz+ zxB4G(5fqwpf4E8Ld3?<#Tfv+fNj(F*tY!?@`Eri$)V67{h#a3JvptoIjF8NW+0b

+XN(`01^cgh?K&{!<{CCqBNIDW0C*9(ey?u`VTGimRq< z^NyB-?}Jyx{~!p(bu3w`g|@;+N$xC$hH%%0H|_C+WESv5dG7;LqmXsygQQoz3_;1~BuA)_ zRBuZcBu880_lw6r!En=*=K{>;1w5h~RzBIQgh%^q z+vF&+{unTVE$0NizeLFxznX76^SfTTE*tQ_R{Nz4@$QQkBq>2n8-c={2lMjhCBqDB zlX0U{5SbmcNidlp@7dW8q-k#-vA26evYXDVf?d>67L)2M7Y)^rF4C%E_UPtQ|F zG>gYvZSGhxfY_Nz2eKw=7f*yXjqlx3CHZ=PLz1g?G^QQ&V{kURV}>s_u2@iM`^O9Q z`ox;a44vLH=_ zhA}Im;D}D6l~=4?O=V?QcJtS7knVb46sV+JCHoO~QRp@Y*M9kvs~N$yv?SO72+%&k ztuTRJRO6d2-&_)0^h&rc`wUBLV&-39H+#6*Wyhz)A4-Mrbuuwx2U@Z>U+4~zriGIG z+0lfYloFVdt@3q@0hClDr-^9xiUyDy-`fG$l>74dnsAjAg4F?;s+Il?%Yaq!6nYBl zXY9IQ(1~b1>ExCD@5u(ST_tjBE#G7x)x@A4}{knuhyw=&HpOy zVk(hLK3G2&x@0ns)YC)mVsws~Ug-Nz(UK9qKeFEfY_%qQ$mG3ZhQn}%LF1Xv^%^6Z z7=}0^zG-)-(c8L@ah3OwU_Bw5D^-CA$JnQ0aN*-OULQw=37=s3fcRkre0BX2a&-cK;X=7HSqRe( zX6LVsSRxaBp!_Q>!FVz&fN7R>vt}ky0e?@t)t*E7P?EIeo~l~vz zJGo$RcqVPX{L|eI9rl^mjPa4d#I~wzm(xAd^4ksEAJRoo^K^zCc|d@CKdH}4g;l?x zI~?L`XKORl8lI8P`D^D#@ZxgHv%Kd{m41*(**Bft=FnX8$9Uoqy7pgp)_yBb2oY=xr@8hO2AT|5esCeBiG71}~zOh)`Pc>$9vI>?)jcJwwKUviruTx3L%p}p$s~^Xbya!n^MRcItcWI}b8Sz?Q=g=M z8C*pfvX!Q)tCNqlevJptD|?6JVFxhYicvJ*yS18l;cs5RMjf#@ z^ne0s1VKG6Fw@uQK4>U0J~WbUmg0E`joMx>1NDRquZ9Xfdi403^Yl*MeLz_^rGoSV zTTtTY4kB_2v|+=~e`;Gq*ooMwmekKWVXzf<+hORMWN50EKaR>t=_SGI%VCHH{vhgt zz~5wxj0eER7_gA0ZH$^JhC1X={aI2D0eQc~;YX$EpX!KrPue`&=D0l?iDt9&AfCew zK=WPOLh>624v+$_vQ3paObR}d2=@$Llj(F9x!_xy{?_4RjF54NN6aAwlGFh(&G2#` zt8+{amm$XG8y0Y2c=mdfu{?F1MS}}TpXyd+N`6b8WQt$9&TqmzUEDQ%H3QPd*{d0) z1tbcZph)}M+9Y3`*{V!BvH#7+_g68gyQ!*8I-k;ZI+tLPRP|Hv zWjGz6$F4gv-(-EarKn6OF?yzDG4nq0flqydD)Q6j+gG>_+!$u~j8hbuSdjG)gwo{# zBO|@Z$BB=D0W50d@V-3L#U}xE2T-$LtA~^Bxzbn z-vuoN4|6q`q?tiJ{mGq6+9?)yW{ksh$xUqTwW(QpoIrC?P@h5xXhOHj$0{>^@i-i5 zU+gaT9h+#e$j)Z(HU%a7o`k^L&wnSy0#evUuGm_oO!Uk=miza>H}M&KVyJ^AQJXw8 z)ITWv$NTg3g_quyFNQh~U2|l*V(G!bh!MVhf;)VH|EpdpKu@TU()Um#l@ZPKS+^w^Pp%OCgC#D?j&q};CSQGmq+LU$4kVg-uNkD>|b z@0M~;9np~*5lr`TjIF4)h zA9l$JlVJLD*-~0)n3q{liOt=#R1ROa-MBSv+7me&I;evJR%@L)Ahnp(Ij>?fR)Hm`1HPrKkJdcAZ|HK)4tg(0PoJQfAlx*2@%B!3-YzckmU#M{9rgV6OX_Zrf3K#h=5~+?iFRkvvh3o7)xFccWs}@>1R-`CYQ#f~j_`3` z{F`6qm;Ns#KiEp?Ij1%{;=D-_3@3d5ny9#a<$XGK#;=2Noy_JR(F;B=q#sr&-+WC? z9pS|p73P%}SXi`Hn`DE(WSg|7!1C3UC$UbR#SB>*#k8a?I$_rSc~74 zxG-G$r#1S}9Y1zsV>97B>11=-pR$V?S4OEmF6R1GY3JFWuz(Y!)Zg-o4=)Mr3@g{i zAqqw~GXLEE4l?3Zs3XMd1|FX@IS%$AZ12r^C4NJ^rs4VklPve`ct>q*EWv)@ z;SU8>!Mv^_E5hxQ;&olQCr#Ne(xpcSiY-;*u6<`?iMuTQIJ2=|0WkpZl-1HMtg_t~ z5h`eS$6SbKq!nO_@D|`xlG2#ZuF`efJG#`7`3~|FIKyV`HM&2%pU2DjpiB3vl<{XS zeVOWVE~n^rVvGC7gkix)#e#X69h)1S%kk;E0Ux*HiydjBCLM#>hpu|4X|C<8D=wWv z90XvXonUvtGbb52uKuzgFY8Jm4c#ELK4sZx4)3{wlhJRBd4JBtSXJR?^LaCiDAPJw z>*QfJmZwI$0i0`r!nw{gUk#O*@Il`6Na?q-8zjre+RgmrSPm_Uq+mN%q`{^FP zYzKcp5$a1A?Ar*s2^Twwr`w@Z-0y50gCF4Eu2`AiBH|FN6O=2}2}GaKho|aNs>&2n zno7gsY%#HGhn!U^k{0^yzN@Bh&PRGwk`^HKlJK%{{O6~u#Kx^F0ozpm>rX3QTc7Yx zOu&f_NluS*ITJE2FC|oUFa#YPfuoKEM2Zieb@9rnjkmh>wJFmi)0VAIbd4#g4`h-h z*K+E2e^EACB8EK5(YExoR6$bx;DhS{wMD^IddEqATZLsKA5N-%cfxRS} zL)t&;%t{77F<%bVF|x5Jdv$kV_zqRQ`0)vBrN7pY51e87D5X?1==@LQ-g5WHVTjY4 z+DppapLe>vzS@x^c7@HzUjDWHqGH5rt@o+iM072M1gq%fUfB zd#u#0=W51N-w$oirc#^th?~8Aa$7GR9DR{+5ID*~XXlU|PjU{>gG%T=?m%ho{QDWTzv%eim;<)i`*(sgb^gN9VDX^2XD2{r<;j z8vmB(Jt!nUv^Zd%m%SnBnM7N4cMwv6ypB zRpi`6IYxpCbmHk<$xt;1tuF^`W= zxESRLS0IBDFP>*E35HpElC*!;JXj1v>W2WnmzA0Sxh5pMcgW|}u)GbvlizToGiC0ijM^A_jL4zlIILhLk31sUz6IwBx`X}ehNo|g8 zbinb@o$5sLm9_81#XYQ6nG;$}3myp@#19=8J*|<6-9s4jP%*AFo2~PA4@ncrpI)-V z4Hm5`oz}rbD%%s$T;W+ZCT=F|n9)?cGmm}x`c5Zzah|WdoQE}H?hjwnDANr1*bP3c ziXF}jc^ei_h`TfLCk$zW+yF@6ALmICNgmb z;e6r^RvZ6dN`i1Lb1aggM-*Zgbkbig`RnfA?AZB|HsyrI!rw$$Z%x(n$RGy^?V#Jr ziHpf+o1ZTA$(ab+zJly};{^BHE;plr3(Q4Tr5_$zfhm2Q6WTI87L>ivsMW|3r^ z+94mG;{+<`XFtciadut|M+@6FFRXZ41waavd!m_@%8TH%EhPf%)oItXk!s+0i0H;16 zn~+SR!K6|uK>@zto^un!pA}7`7|Bkr=<;^Ai5h&RvznZenJ<;zZv5@voV^bg<`M06 zz>mVlLb=;W+#6vy&6Q?{Wi<$u>r17}T(go+S5n|Fx|~PtfG8xv%0%tuCb@DwjL&aP zVn{hRJdEFHqGemLf$0zheBVaKk7-;qi;{>DoFH`*r}EtVe};wbSj z_RSzr`>#M{!578YwU5>~<;{J1A`hG^V}XUJdi+%MCW>p$5FhL#Q=C*%2~PYYu2zY) zbLE%ZtY?C4B=S4lPWSXuP!mk6zHa;qXO>Ej`tHWWdRgC{L_6pxGIJP=BiEEq>4AX{ zhS1kPU7k;W{_m8wQogA!F~buo`Jti2T&owlvPs%bvtgvj9(vMLqV-T}eJI4KpFC53 z)vQ`81tMzov_R-`c_w$k*ZB#R3#Tf7ggsq|VDE+PWJLfS#YIV#)Zpof)1fsKO!^0W;>yjt!RU0-FK6${*A???R>Qx$hf7 z>&Io6v)MvQ4>SQA>Sn@T(S*dno+%qR!=X{N^9XVTd|Jzx*5h+bG?j;ppiJV(bvz@c zc$Agb&Y`b|bqe*40!}apJEdVC_fa*+(>3gb^Vi%ywbj#)~LCw;$orcyb3f)gH>xl$CsdQLt&&HP`(bgbQGGqjnk) zM|TS+@WKrr&1pkX+s_Jg+Fy5ZGe>QI5DvKtzvIcn4BAr^v_$)0=_iLtIE9>YvI1S276^tIQFU z&I<#KumrR_Bz_k15fQ*yS+M4bGoa-wP#%sA!o6zF&h2_bpssmYX7H_#bt(pySZ@pB z2N(Ca@{)4)erkNCOaN76p@eTxI5>T!Xe+=Vf-MH|DeOV}eKUL&=66nT-*i;LJK8*9 z%kfZoW^v1fuW-*&-dn|YrX4|S(0Ze3@qMW~v*nkBF;P?=qiq0TNvvuufT%|4FfGF% z24V(w?Qi83Tzf>%Zl-+o6f-xcw5Z2v)R%!dlDg^GrjJfu0;Tg(4G-h%3#HLLochfu zjw+ni5ubY8$@jMGT1OAOMTAIFpaDA3d+>(dc6NPpFt6xWIcR&nI&?hl{4Q7r;g+UN z6gw$9QvVLtY$QY}^#{uDd?phjOzD~)##?Sz9-dSkk@5Y@^riJTXH94kI|?&JfdwZA zMr$3+(+G_Ij@#+dVOOi7rp(Em>CLKM02D_nlc&V^A;a0QBCyy{(zFWE);{SY|9;0< zL2r9Vl6&ytzpChh1&nx|1lSW-w;7T8_^Z9}HrTLIzsl^q)e!4cy)?`R2O@0jeI^?^ zeW|>tb_$larS!AnUdGQJul_m_DA(B=j-ptZ)uaD;aBI*}R8hx(GBoAM95B22+rzk` z4&3-&!gcr2Yv z`DOo#T=iMFezI-M(MM+=t>L1P-`1|GV^?GQfy7Iy`ww51eS{1qf%g$xI!b+&VrSZ` z4k21_e%CJ(~z2| zIRaRW47yrnp~_1N@0q@Q$p$bAc@Kv}7mXD$X+T3wE1HPKjC`rQUl`H7k3FoscWO1L z>89`6k+JW99Vje-zWOr^kqgOgnUS7*gBh-ZxUy_QtJY+$3g8Y<+E6=@h_~NHJw?F` ztR_cWW~x(Jp6748Y`P~|M8YjlKa{QS9^jQ8qh=R65F?|%2B(7NqhqiiwP3h|SmO{e zJ9lGLmM1L~5a%3i-d)fZTy$nDv&>%EPH&8A}uLUEMJ$eC$(W+*#BRNMPcb zZWzSJ&eTm?Qp3#Cm{n3Vp#)Sw%Ko;D8p`K`gU1IE{BaP+6;)E7VF zeE4}xeu;-l#T&4F5hY-UA5Y>0cCwQJO+AebQ;ZcnhFGn@>DT(0=+O|(A_klD2~BiR z9Pg%bP>N~bxq@4RqJ0{6CTl|E-p-eR#js1BkW0ORB3hQx1*OVgf59Q?OpB{^1sJ~+ zJ81kVoT5N(V_krr{hfY4#cU;Jz^yqOvJyj2@!$?o&3V7@AP(+Q=gBglz$9e=R^X^$=?SUg#6grQb0*H z>Vt3FF+lfnOKN2MgW)eA<(@*hPYEB%=TfmKbZm_+po_3RroCnr6or zy|&V~kkc3+bHq{EjcU%@-ehMLj3oN>Sf%n%{~uZb_WFW1;|Z>7Qf1Qd8^IoxN8+tSu0#CAxCf zu#qbT0Lt~_tgCXr%G#9c9nI$E1SJ)G4e_$YPU{pcQHCh>h{>7%q0~)CZyYYVm5?Hd zN!;m(5w{KH4NzK~m|5UCe_4xr-#NyY?Ch2LhOaGnMdc}L@fNB4xsZ{<>F85S=k{a3 zs<7{Ct1;fb4#oBQZCJBIoKzrVknIis0S)1 z!6xx&jnWSY(tQ*fl%!k}Yo#?j4@tzRbgZ<1=dw`1Q}GKnYBE_a_oX`q7bO*;apYV* zi2^gXdwT!EsWNx3!w4b^;8d?NHPPTS)fm+TZB*{C?+(LBC&OINF)NTGshOb4!Pkj3 z7Z<;{EMY8Q3<#$6XKO~%3vqov5oAUforl|7V`yQhpl-Synz_(Us)QnY2)rJUHDGUU zC7r}=t-5Y6;&dsIZh3Tq*1>WTWac^g;-$IS@`LyP`z6Put14nJjTGrtg!d3cVF?Q3 z@Lvr`4*#qt!zZw0sD;2ke}61EtSWnQM>mrWNeu*94XS8nZ5YnX*r!g=C0#+V`v5%V zy4&$h7v1L&WE*lZ5GXa1Am{e~{@=LYF70${f7lS@feQQ_Uj8zGDUNi}`TtbXJc+%+RfM^h__UJ+Q3wRF3$&Sgx@dLw zN-&G9-$7FnpsC6N{gpu+Z2uSZi6pAK#jD#xIa_XJpWZ0hBP9=^D>jLR&{{(zm9Ab18LWhSp7w*NbZa55}EqYX&%CrG35_ z@@u&hHq*sSx9U`xzh58zN{To@+F2jtJKuv(C$=RKUsq3#H~rkHA!2qX*UBVn>0jJ< z4nqumXf8gx;`hrtuEcd$`@s~4#KDC}*Sv+RBl`{z#DK@>7E;<`6f1`#-yp2dnSYw9 z772_ZJI&6_${5iRF+9vMZ@jK*&U2^NbOBSo@=g+$6Gz#R5=toga11e*1(lR4IH=m< zC_BnFdcTwg3o`xiWmi83s_cj-=&db$gQB60fD+r4a9j6LyMTVPu>Ow~1-9qhTnHKN z)gv65@pZ-X)a20e1%gm4=BjfoCExp6V|VVL#>fOGG0=huBVhc!4bNGQa@0lCnu=PU zpYu_o=OI1QR9QUfcz#1;YvAWb=nY(p@sMr`88Yz;M55rgF;l|+lwl>U>gZw(T-_Qe zK31pLS^Ih_-OJ`Mx4&dp$3?mQ`wWv>3Gl@cNGw=V6H8Xkye)AE^ce`NHSPS)lCp*u zESBseB7aNtSQ5kRl9f}r`M=+@F^qLa41=NDK);s=y?y7f&x%bOpHEF2`=)Qi7gtSj z%6~y}ee_9@xT)BsUgc3I93Ib=7QKm4ydpl^%HjRONZ zM>{?|uJu!>lNU=aqVha}1S*xMNZcm^X2SlifT%1kP$V8N?5(pA6mB3g&ZcILb_Tr0 zyP76G&FpYp-|bB|91kpOA!7FLM|6Ds?FnTDiG+N=iV+$pBEa|#TAjn?DV1ZmWA{cB zEuCZ*b~sF{;WR;W@I_#MuX<}0?VY9F+4WNqS6#C@*i2u)f*)wVlt6G2eM06fgmmkd zW+4vO-rQj?9IRXUGVQ!Xcc%OzFmTCV?Dq}YmuiSza;=6ZYu=%oKZK^3L*TXFZE?p+ z#P40cQYAImKC)zrr}p{T!Dc1`I@h!P-AxubjqKjci9+P$jsE86 zy@w=fjZ@7)%GXU5s3IaE=Q0S6&Iy<1tXoel5|2S!5HgCL7ks^`jBdx6wh(77VR>QG zXBfdi++URxGK@>($HOO@7rW1%v2izc#QnE>smx%xo!9!CRl>WrHdGZ8qY^t@KWvH9 z4uRtcpuZ{ftNh-ddl^_kvm{uAQL{pOt|QcsAX(5lSbx4{cqY6-xSqz^Jxn*D!*#@p z0_lSkbmAXNN3Ha$Lmb-ElgS`)DiHOE^C|n_Vbt^?QScEmWM6-Vnok1kNwrc#PPoDA z*5QeE)T&3+UQTnxcq8MZxu1N=c!JmUBT*r`|VHD%WlzIeJ`dLtVQY#92Zz3!m z>-*7BbD&+mI}YLqMp&fsj6E4YY8HQYlVI91%;LET$d^i~S0q`vXpO3y0t|YP&ycWPJP^$ zVWbij#s_%hi9Rs@&yR>ta*hrNC{ zyZ?Sd4MNs}x>;T&b}+6}t!QF}bouOgnCQzurZBckwx-3RV2sA|`FKVfHu zq>>ODT|%<1G3$T}+{pJYB?$h@<#fvzWY&qyElU;475Afy}ccv5^kkn=)fK(z_L0L2r6p}0jPz31NZB^ z+D}p7i8>mJZ&}cI;&KNh%teiL4rK;F``8;`AAOLNV-6d#Bf{u*dxDltRr@LG+0i9R zLBm76zw3{#&TV}{@U|zsS?PbmuJ0CdDN_Xuy zt~&?*;i_AF(M-7tl}c=Jr~{7J7EXB4vp}3rB9`wK$#3i&%nkGeZq)5ht?wM*^W(%2 z11K^L9s^1#2xk*`x0K55;m!ej{{DQ+aQO~w7FYav?C%f<9N`6%a{Q76KGwOiZny3r zcin71vhJ1K=6GP^8IpQ7AlG7i_jBd19}oxjGnG~F`GMls>sF@&En;AQ96sBL<9p?+ ze3t6A&js@OA7lo8`3z@4P)^MDZja2~Y@K_-Ze46|Ch?H@afqcA4`=1?IOzJun--d& zDX+3h5U}P>a@cWaT*NG5kV5qL?0M+>%2YQLkOOYGn4g#XM>UmjDp@?97F%rpUDZ2* zhm>7Auo1d2Jm9v10VCHZ!g)d@F?h?dm&8S?!*9A=^5o@lx%;>XRub$Ypp@|OAe`UI z`o&CrvSqfyCgIZU%i}6877qVX*IH%1cA-7daOBSdLOEGYiW4zoHrkFSnA*)d+~D7I zra&B^#*sA$$;;2ixo^bsgjNcv|H$XgBLxd?<^+_g>oMB4?r^Qya&GR6BSB-Y!c;t6 zj%EUnoRVs4`ufuWSG#%lnQ~Hx+-lDySN?IyQ}E>(~0UC zic3r<)hwgX3nC2vxLO;mc?LY}ZeR7GvWtr5>c)GH-bA1fIUNdv3 z9g#PM*gA#s&0rs2xK!04GeXB@O*f9LQknm{JjfhHZ~ z8YBci_{GJ=d=luy#6QD~6R98Ug}!qw-CCBD)CBsfz5)*AWHC@o;m(iwTXiF`gKHlD zl|;X?zLm_QaYE|1S|+dy+Y0j6bqZ$jCH%p`H%*MvEor!rBR~c_OjGWn?XkeT%+;un zV+=Mfm;4ITY4jU!1U`odEKSY}A^w8L@pRuPXFuQsc*Au^T&HSr0`>1Ef0bC-M4>I= zcGBsi$ACfl4I3i2`9eo_cKGYupF9ufeJ^-7f4>Z9sc(fs!k5IM5fmwq1YCAIT@cAk z3YSd2xQR2#erQ47M+fl4cZg5`?i}HYy{FoD*`dHB~N!lkf9suFT z2y-pA03?-Yz0Qz=f?|P{+3B9#s(nirm-u-rR+bu*2A6l)9mB6-ce=rXCvJv5xl>6C zmsVylZq}tghmTLBzF5-sgYvExPKdu=K>27G)R^A(=HQ{XA&o#?(0<7;aSkOwUC5AD zXa-2MzH(6w>gCV&7N{d=H||6>GJH_NYyXb^djcCrJKfkX3{lT9z(R5C5m*s&&$8pf%HniyX z*N8mJ%!}x_m~D>foy@j3%jaR`81em1@aOqkxPRu=w^P)Bq?$oIzbSOjgT@NOeG%dkgC=P5Dt01?CV_!??5rJ`iNp<_HY zNn4FVf+2q89(Lr)V`k-Ol&gbgDG?Cq>6Yx3C(Ot? zG*Nf|{$xGGcm>aB>YYU8a%8O<487W@!LME{`zsj|d@q!`JKOpqgQmLu956q4#=&Zi zQDZNa^Q@z!`uh%J@7Kiq~Fqv-xez|Ii8U{;Of{i!O~d~cC}Gk!2>Q5tUY`o z@1cj7zlP+KQVJ48Md>f!MpLhwo)1qc?b(_n!*VbvV;?W z2hx+yyOGF>sR8cq3b+KyO8`~#9(V}{undK8nvCnfB0i7$b7=s31h=15OhpgZJWwn+ zYt)ID&jVgx7Jf~u!#T!eeH{-MxM~p9z|Pw@fe&M;$cGLQhjU;8c9%n=g4b{3qk*Uc zLfs6{xT)4z`aT;txQ3%ZSi=6-3TCLFK!iHs`bK!NGb@K@N{Xu;4cQC8nB=9V>|#;` zX7e{T_|_A51s~m!WJ5x`F`lqkN9Di)mR$czh+iRJi4%2-wMUAEUdFyT1Zu@tVCtJy zKpucIY<@%o$-4iK%h$mxhIB(b9H(znsB%uRm zIz}O4kk3A;Z8Hf=!`}akkgV)}kAQKThj*WRJhk@G7c;Fxp;}Rqk|9-;hSM2Y^(5vX z$T=vZ9dQj}qAB+4C^Twt;VuRyp*Ka51h+W-FmWlNhxOW81{7>vC}3ZLj~haZu|Nsj zH+%f_xaOynNsquR4TtRKxwo^0PTjdwUihCEV&L3kUVzdP1s0~j%jJr8aIb<7_T77n zvVpY=^Z#+iiP3-*;zBcLvu`%k!Sy{mn(8g%p|qlkitu^)xjrz(8j+iJ-w?!}JD6;c zO>$w+j(;2oD-vM(r{m{^Na5Na&{xq%P!D{9vZ_*G`=y?5Bw9nO|5|}&p_z>QB}~6` zO5`n7o2c^U4NGAXBmwd%hn-KtOb@l6n!~&i+N-8Lu2#OLhcNx3FI-K=vnRHb&!L3Q zQ2@TH7<#DQx_YsQPmTGWv0&dCw`-}@nsB{qC z=wuhnDDcmS_a#b3v{isr>Kd4Y*pDb&ha>$tGp)r*@~QG=EsAkhWh|k@{rJFml3HG) zf0H5!_6`I+m#ZCD7lC1E)keD)jN>q(Bd38%k7-8vD1Ino_rVpq`XT1T$XlBD=qrv4 zFB?`$Dhwz-+TG`px#{?Iq{16PQpI7eX*2A}45>=}_8tYPJSvx41FXDx*(fERY7It| zs9QWEeGN#&#!rf@nQ-|SIwH1(Y$#{ zBG&q>$!?B)`jZ!j4L!?-sfdHDRiUhT` z4Diw0C}F<9NBGoe__sF$d2k)B1WM2hUAIf=j=jJnsp(kQVmP&SdFBWXZkBlSvvi7~ zEha~>M`*FMlXoak^nVpQ$`1_a=^j;I_M@C_Cf>;ztLXhLW9Ph^V_+>;UN(?)?~zI* ze^(X9XFP&#tH+v4PhU4g6#H;zUF1hE{W7H_Rj`v_Pec08S2hv;*y)gzmjH`KpGmoq z`stq2V85frXi)6&&d{ zYJ4qF0-`no8ma;3iyCE~Sm^3Gsl3E7=vK-qzIZ_y99|Ii=n zcm`fve7wdd9Dk1Sh)ujyEA@;zg{o*LA3giyd#aDSZYD;eEjL(4;9t7QB)b_rIhz@e zoV%n>D>3By_79?}42^djzXVQFBj&JLVW2w;&GX-YyZtIFBB)(BwSDR~aHo*(WiHag zAHCo}{7vp_>agEuVLaI?Q!=9W&VGOIed`2-L5o^veV1*EybX!CD`ZHwDp;ayOfjF` z%O%r1La#Viu5&3Enw`QQ<)wdeXK`l+j?H8Y?qI>fL_|7B{m+%;s^cF&J$9M< zySmLxxej-|wjnf%(Q;PClOP)CwZb4yJ8*%5dAEFma z!@_037_e&)N1%N

llxzabaa!FOdeeJ2Q>8Rp}JDt!{N?lxC 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

l1{Ld_3@+xJ;>OC-wj~fPi3env2!U0% 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 + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + v82+dTLO1RDGbbAO/HPo4KImk2Xnuvyid29h9OyZ22RhLmhaMpe2sjFul4m5sNVjWbebLNv2ybJn +fX6RM5txvnU2jvfu7yTi2TJ8azXP415t1On1RJaGPYl+/+cR0BtpHtpFnYVeSFOw4xze9Rc7NO1L +3V1G43WjgSwB+48l3++Z3Kt1FPloI1DD3sSK+JNGDe8eR77f05h343zrPg54zq4hfPNEmYL3E+si +Dpjux/Cp0S5wdhkNYFy9dOq9E3hwtIcmCW2bQDs/0ydXy/St1S5pfutyxt1m28y4OuI7u4ZQrsfo +sc0xe210TJ7bLMMHN/Mw6vkeyrz+Mocm8y5rs2tdWSaPrc/wwXkZPLc6Bm+NnuFj+zByaXVW7csu +3ZnrsjZvZQLZaB1FPH9TeEfzNO55n0c+ewcx79YR13Vl9No8zd+bHUT5ZxdVHn4iTEJ7qfR7D10S +/hvDu18TGPdtCul8jeBctymk8zpgPJuJ9HtTmZi0iyoPbRrAN28zOPeLPAf9DqLeh8FLm3HAczbR +5aC99Bm+mUDBXaPNQlvp83sndYLtHkg9G+ewzt5B1LNvvnN+pg+unvGDq4s2D7sSqLc7JCnYDYoM +vHG+dbYMYNvsAtfLzjhweNG7uTOEbnTWrZdxLQYNfMOEL77FoIHfZWBmZWEwf2famTAbF2ZPbZuN ++2M8bawDN9OGxQSyjdkkxnFtwHTyyx1aWYwemzb7dpPxPraBk2HQwMu8LvAaDENWjiuWxeuKucjN +Yrxj2MA1QJjAx7y+sng2WUzfmlaGsI0rU9jGnTFsm2UO2bYub1wt/2FgXHsBA/dhGlzaxjq4qJWJ +uaDJY9k03yHrRpNl3Wgyl7VtB0532MA7WPji9AYNNhvqnC0trSosJgdoe2gXmLCYqJiqmLiqmKqY +sJi4qJio3momKiYrLSYurSqmm0qKiYqJiunniNVMYb2DBTY1uD62Cw1yMtRMVUwJonLy2Pb00LQO +7qayrjgwUWVpYU11YWltSeXQMVFlaW0xVWlt7aGRMa3VfeXIOW05HKiupqiwsLCyrqa6uqy0sqa6 +rLqs6KqsrKysrLaytKiytq6quKawqLq6uKawsqi2sriupq6ouK6otq6usKistKauurSyrKqourSs +rqimrKqorKy6tLS4qLq6sLI4bHFtZW1xaXFRdWVdWXFRcXFpWU1tbVFtbW1VUVlVXV1tYV1hdWld +TW1pWWVddV1tcbDa0urasrra0rLSssq6utLS4rqikhXktOVYqMq60sLSstLq6mrLsXA1tbVVpVWl +tcWlNVWldaW2tWXFRWd1gamqb11xUW1tbXFdVW1VbW1ldVVtWW1tVVVtcW1RXWlNWW1tTVltcU1t +WW1tbW1dSW1tUU1hbW1hbWFdVWVtZWVdaV1xdWFhdXVtTWlpbW1tbW1VWV1RVXFtYU1tbW1dXWVR +aVlZbVlxUU1tbW1hdWFVTW1pZV1hbVVpSU1lbUlNZWVtaWFtbV1taV1tbW1dSW1pTVFtVU1pdU11 +aXVpdU1xbWFxTWVpaXV1TWlpaW1RbU1paWlpaW1laXVVZWVpbW1NZWlpTWVhYWVhaW1pTWldaVlN +XVFVTV1paXVZWVm4srrK6urCutLaotLaupK60rLS0pqyyrKy0sqy0tri0sKqwpqy0tqy0tLK4qK6 +4sLi2rLi0sqqstrSotKi0srqyurqysrKyqKyyuKi6srK4uLKyqq62sqqmsrayrLCysqa0srSusra +yprSyurC4srq6prK4rqaysrayuLamsLK0prCyqLKysrK2rq66rLK0rLK6trK4rriysqq0uri6uLa +quLK2uLCwtqisrrCusLS2rqSwrLKwqrCypqqwtrKqsLCwqrCyqLC4kCFdcU1RYXVlcV1hYU1lcV1 +tbVVdVWV1VXFpdWFNbWlRaWVlTWldZXFZTWVFZF6WAJAGvgkAcs7KmPJPiZMQBWFbHIiAjnFNPSB +A9OLo4amN0cBmoc9YGwi9ljFLPRRQ/OwRwvORBysm+IdqZrhHB80xTdQNxV1hIJKEln0FBEFLhJK +FVuxSuwPb1niIalc+ZUxspgFjgOgrRsnQJZhHIshaUuoF04BfxReLs8k8LKtBpzpx4kHvTBxID7E +c/gOr+E2vIbj8Buew4NgiLiTEBM/QGSAN2By4nBaClBIPMEcjFeAZSEgxQaqBDyAMfGQDBMycdiB +RzUQzAeEoYapAHjQMDZWAoaIpQByaHiJJaVfkySVf7FGPC+XEIKvYKH/AiBF1nxxJa2T0Qem5yIP +UE3EHSE0wTpGeCrqIBWtHII4GjmE8VMRtrMTMQhppiGPF5eDsDcwDXvowDTUgcNTrMNVk4eUszsE +dPi1sY6ZzwBTuH5MpMODcQwNQUIaK/A7siw+IUECjoVkgE/9MHEoGiTOBEPEjbI8XOglhxfxH17E +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 +Lzi8h7eJOcAw9rEhcLzAdm6MhayPpXBoG2sRg+xhgJ1ZCERK52EPJZvfGy00vTpebHp3oND04pjB +KaaRYlN8Y5WTMcfnZiKOVM5EHKydiDRoeHIeAfz8NPLH6aEJXGYBTdQmh0DpKlqR0t/GWsQUjEN8 +BTl5pMDnJCzgUDRBnIbbcBgew124S5a/uLjkcB++w4F4Dc954TKccxdOw294EA4T5xDhCqkG5wW6 +8QDGMr1MMCn5ohABpVxy+LhkAD2ySQD8ZusTuc3EHp+aXh4lMg9zsNAE6xgBSgkk0dKFFbTPSSHi +S8MdMjALfczYROThuhnWwYrpvYFjU2zD9fNDE7lIJlhstvER7eF4i+w31qIVIqJ4ga9lTXEGPUQ8 +iOdwnawM1+EzvMdlhufwGU7DYbhMlnPOOc/yF84555xzzrkLh+EyvIbf8BqOw2P4DM/yFz7DbzgO +5+E+3IhHFUXxOLMIYmMqGjq9sZ2Wfk5sWAIyoeHZ2cQPfEAAZMckCHhHKQDooZFDGjEJYXVseneg +0Pz2IKH5zVEiE0yjReb3hgrN740Ym4g2TGyKb6xuJuJI5WTE8bm5yKNz0/FGp6bjDc1NyAI+NSNl +aIZ3YPELxiQuZCHnB/xbUfEEOUoch+NwGB7DXzgMl+Ez3IbfcBxew2F4DIfhMDzLXfgLf+E1PIbD +cBgOw2P4DKfhOpyHMy09vQjCfQGxhsGEXhM3ZPHQvniUFAPOBIWAW3BQ5RJoR/ipIbaQNc5xQW48 +ADFMUylzAVtMZTl1OXTO25yWVA6d1tZUVZXWltSWVhcXl5qV1hZbF5vUVppalxRbGxeWFFUXG5fU +mhbb2pWVmpoW2laXFVYVFduaWpZUWpVVl1QX1xqW1NpVFpdUlRUWW1rbldbV1hYTlhUeh6osrS2m +qqwsJrOnnAdob3dzXl1oaWprV1ZrXWpoVVJoV1tpUldYbVhSWVxUbVJYVFtqaGpVaUxzaFhWU1Qy +2h7aBT80LZsbGt0GJiyrDV5sa3ZqcHVyA6YEVVVpXVRUWFVqWVxqUlVaVF1SWVlXWFJobWhrUm1V +aVVrbVxVURc2yHt5XmZUVRu8opgeMCUw0zKjMoticsB0YYPMoUPdQCwnj21PD02roc5B20O7sFb3 +9fQ0bqDC/1D6JQgB+bNkbNZPIRZl/NZmGT83GkGIyTmsSWvvEOW1i0U5wZUA5VULFDnYY+7ciDQJ +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 +D5qxKhdwFiKOUEo8iBUaqHXX7xn8M4huthBo/CT+txWLjsVPlVYOmUy4hiySvqOdAK1QAzaGSlAK +0LK+shG1gxOGaO04Wkf7aFfE+N4H5w8PMjSJ8DCqGrimxGHh8refOczAAXlt9w6i9D8WpmftKIz3 +gaseXEWXnLo2a7NJEH3KY7LaIjS3oqFhbKoKdhuiWxkjHMo9hkaPRfRkalVaFphCb3hS9qPTc1UP +PoEIHXFBsNILEC3NtV+W+BRFIWOwIssM1oCgD50M0IrSXVbxR3qqHKN5irsUPBCESAu2M+ZYsJCL +nYZZX382grKeTR8VPwe1Cap5sZ4EV0N/vfKLW2az/319BQH1X9AcrfmkaJkjihiW7C6C0OYAioi6 +pYSkrvjdV6Bnk0csnhOD5B5KYweTCOCAVyZ9fY4FIsOu+k+YToyJhYXy9YpHSfUyIfpKGH2w8Nzw +t4Wg0+so867Ypye6kHDBGi56IbiMqGh1Dto8icYm8XIFLwFLL0Jv2uOcjiyS5O6NHKP1Qf2pMIL4 +imxfS1qnHGjhyvN2CUYZ6b+THDhO/srSBcrDop793RBOCSklm3e2wwA7ptdSwTd9tGHmS46l48ec +feBmoY/Wg3k2szqUVXjDhyo2pWQ/4saMMLZLCcM8CSiniWSwfvcvPH7OtolT6omFJJDxIdaEY/CM +kReskVFioGCyygNPhhw/H3m0AEA5oHaGt+ds6ODUU4xe+t3I01x/mYa6fLW1oiOX3XCbUGy/2WfM +a8t4ID0EPJ0aBS5uFxaqZnvXME9YQr0GRNJ51BltC8zQpXetBrQMOXTd6A4QjneTFn4CySCSmDgB +7AkAdApfMmFkYzkwNTUwLWVjZTAtNDEzNy05MWY0LTE3YzQxNWZlYjZlZWQ1OWI4NTBkLTU2MGUt +NDM2OC1iYTc1LWI4NjJlMGZiZDc0NCA2MzguMjUyMzcyM2RlMGI1MC1hZDYxLTQ3NWYtYjQxNi00 +OTc0MzBiYTFmODA5MjQ5YTM5NS00MGJiLTRiNWEtOTFkMy1iYzMzY2E0OWEwZTIzLjQ2MTI1NTAx +My4gQQXLISI8r/YSnv3mdJAGUK1mGlirkeZ5oLkj57eZqjkitM2pBN9OEOgGpA054K/AulA5gxCC +WMNY55qfmjGYhgfc2g3aBbImasdKejSmHzz45bdz9JjgAO58D+w6GTbu1AaONVeA5zenKTyYNaPx +30QE6gYWpgHyAwunYdB/c88RLoEI9OYbWEuP1vSDZxDRBTZcjABkO1IxODNlNDNmODQtNGZjZC00 +NDUyLThlM2YtOGRhMTdlY2I2MjM4MmVkYjg2NWQtODUzYy00OThhLWFmMzItYTY3NmUxZTM5ZmU2 +bWwxMF9TVkdGaWx0ZXINLyA6DS9YTUxOb2RlIDoNKGZ4bWxub2RlLW5vZGVuYW12YWx1MSAvSW50 +dHlwL0FycmF5ZVR1cmJ1bGVuYztjaGlsZHJlbi9yZXN1bHQodHVyYjJhdHRyaWJ1dGU7ICxzdGl0 +Y2hUaWxlcyhub1NiYXNlRnJlcXVlbmN5MC4wNW51bU9jdGF2MnRmZUNvbXBvc2l0b3BlcmF0b3Io +aW5pblNvdXJjZUdyYXBoaWN4MCV4aDEweXd3aWQpQUlfX2lkb2JqZWN0L0RlZiA7NGZyYWN0YWxO +b2lzNEdhdXNzaWFuQmx1MWIyZERldmlmZU9mZnNlb2RkZFNwZWN1bGFyTGlnaHRpbmdQb2ludEwt +NTAwLXotMnpzcGVjT3VzdXJmYWNldHlsbDp3aEV4cG9uZW50KDFDb25zdGFsaXRQYWlhcml0aG1l +dGtrNGszazMxMDEyMTJNZXJnTm9kLTIxNHk0QmV2ZWxTaGFkb3dNb3JwaG9sb2d5YWRpbGFyYWRp +dTEuYmJuYi1kbmIybjVEaXNwbGFjZW1lbnRNYXAoYm5zM3hDaGFubmVsU2VsZWNSeUFDb2xvck1h +dHJpNDQxbWFuaW1hY2N1bXUobm9uY2FsY00obGluZWFkNWZyb210bzV0b3Jlc3RhcmFsd2F5Zmls +bGZyZWV6ZU5kZGl0cmViZWcwczU1NG5jYzhjY2NjY2NjOGNjYzFjY2NuYigtNTQxQ29vbEJEXzY2 +ZXJFcm9kNjY0Xyg3cmVwZWF0RChpbmRlZmluc3BsaTFyZW1vdlIxIDE7MjAgMTU7MjAwIDIwMDsg +MTUgMjA7MSAxIGNuUGl4ZWxQbGF5NTAgNTsyMCAyMDtEaWZmdXNlNXllbGxvdztncmVlbjtibHVl +O2luZGlnbzt2aW9sZXQ7cmVkO29yYW5EaWF6aW11ZWxldjZkMTFsMXJlZDUwMTAxMDEyMm5yZWQ2 +ODgtMTM0MjAuMC4xNW50YTh4NTRkZG9uRmxvb2Zsb29kYmxhY2s7IG9wYWNpdHk6c0NuMzVuMW4w +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 +KIriQg1vjJaYSEY4RnS/m7Ng3iII1cY0EKRrfPvZNsSTaSmllFKmpJdFVYtKhA53wPG+Gt4HxgcD +CR5c883SaZw5y9mT5VfmmGsVfbqwzLNOem0V6+3KYtkv7XRNaScSlnkaTddkWfkx34z92pazulO2 +pdmp7GjnjJNWU8jldPkZSxqvV1Hep5ed2PGUfa3MkVbHLWe2hT4tNIUkvbJOoVxZpyGnnv1jnXVe +eqmVGM/s8kZqba2SejwaE3vXaYtO6VeJ71f5q+mqLnrn+63S/ZL3uiXV6/6kPe3EUya2g3lZj/2j +evxZYflTqKomq7o256b2XoktW/Gd/U5f0vfL/nUrKynaKr77Y49vZ/UR3eJPpPg//bPb9+rKjal5 +VvG7vxtXibviKv7nmeeMjy+O7ZOUZzWFxK6iexVxnq7Jijf2lXhOV+yrSnslnlX186eLVHsKiU39 +PQ6vy6h0eqySZrd1yq9IFOdZ8e3pyo+riO3Tl5Ri+ZPim/uraH+6LoyraC/Hw1PHTbFX0fO0cIWr +C1cVjjbaiON1eSPGUya2NV2TFW3MMedoJyvmmKtcxWzlzVWct4p2IsVsMTKw26zPlnFYRtebabVT +3uxO+yWtJq6+q3vhn0bT1Thj6Zb+t/TqsfSc35/OebNtLP3xvKhXcc7p8n8iTVmrOHuSOorHl3VZ +Fsm6rL6uD/Whpuu6PtR1fajJ+lAY94f6UFPpATQaYd5YpjhUdfZY5VmmlYvsrbDpNstY5nhUKc5w +1zrCKhddrMpAmVazgrIqgzLatLEBAAAAAJgXW9sz5o8KorWTdU3WdE3WZV3WZV3Vb73wvVfmLPPF +12TN+bJ9utrd3W2ersmq1FYs7bzf8k7XnS/vS4zxdE1WT5bTOV0t6WTVavOUFc+nVHa/P+mvybLV +V9Pl+PGUX00WxXlKd1yvt/Sruj1dGVdZq8m6tLaVdFaap6QkSavRhV3mimKLcTVZ18pL8knlxaPp +sibrPdJ7p7Uuf8r36qKzrVzhxtn7/+Ls3tht47f0W3a01s6fLTP4iZBVfESZgy8DQRha7MLSJXYu +kw+FwWw+1If6UB/qQ1H6oSYQ5kN9qBAM5/D4n+x52maNcNpF8fhQIyBmESMEIAClTcyj2VlkX1Qt +rq7NuHKR0woUmqHq2tDEoUwnINszlOGMXVFX1BurRqFLK1xzVnUdPahOO/lQFB4f6kMJQAAAAAAA +ACAAAXz7B3fsGRVUCD5UBOzjfKgP9flQU8niEX6ZA66TbSAM1DIjIGZR2UwhjM21P7f0/PN+9Wqt +7Env/adu7Y1P8z/1+1TiSe9tfOvjnl6lraJXi9/dXnn72r49r73xvk9/S2m9T2W1fael0l7P+T3b +eiOul1J3i/3Sz7Wf/pTVp/Xc9fbs2U17Zp8X12qxrBdbW78pro+dXvvVJbX3/tvZFF+Jn9L5Fkv3 +LDEJV6NrevVyuk+fQmI/kDZtM7m2GXu65kRyWj/3e71d68T9M/uc2X5H69UzndMznT/tvXNi/C6/ +Le739qb/j7O8/taVLenBLSaEubMdZ/fOE8lj2hszbXurOD/f3N3XZOHpwlW08ubK5toucTWRMMZg +4k8gzCTyiB7bejX5ZFuE0BN+l0/uXD4BPtQEQfq60UbnYtm+dlrpDRFFmejrQplG2F1U4mRNV74m +q3o1XS1vNVn2Voozlba6SFXa6NW9S+zSg07kdV9mToqh1944r8XUr1dxehX93p4sYvt0pxoe0SfM +I2aXtFJ3POutc9ZKa6WUzumKs06k7v/u/8a0ipf2/0Sad/ac7rO7aXfP6T7b+1ax53Sftq+ddc5a +MddOD1qlV28/0o+2shRj22m1VcRVpNm6nVWk1XRFryKttu2slFZbMVW6rZJW8VZ7I6VevYpexWrr +dMVaRVtVsU4WkVp7o432Tle0VbSVrS6WbSet9d0vrbezbTovxo/zzJM2rm3z/bdeJRVtmbbJQizj +HueMmEbrfU1WtNNVZa9I+atqurJHKy8pWo/5p0xsK/5XNv6M/5MV/6P9Kv7Hn9Kr+PPzV9NVTST7 +L/owK4aaKPusGbHHtpHWkTCUjb6sulOKHVtbxf5QbK+qLbZb7hXLjtknjocJg4k9jZpiQph4cf0q +PskjXlvF/yr6FIKJHjtXsX0CYZxeG9u7qtqreKvos3J6bc5Z5tyxPX/0OZHijT6nTOzRZOW+NE9X +vFX8+DPW6D2vyYruEX8Vc84df8aLM+6XVTVd+CdSdK/wTyGx26fSw5c56D5cF4YlTPh1HgSNSPs4 +IZymbZ78oaanLyu2+f83RFqJk20gjNNM7w/1oXC907OVPV1+G0v36cqSVqRYM7Yubaw/YR6Y9qUz +2s+R67jLJPrEfagP9aE+1If6UB/qQ32oD/WhPtSH+lAf6kN9qA/1oT7U9aE+1ET6UA== + + + dhJ5xI49cUyjyZoz93uWXaVPV09WfDpb1o+1Us/SRptb0mj/1tovf7LoR1yvjbOarsn6Wfms6leT +tsReXfeW1yt8q0iryYrzq0rrlPerKqftlncKVZfVY51VtD6F+nrua2XP6fKMbRVpvlN6vZJWsqel +Ocv80xWtrWgVcf5aRVtnldTWmek1WT9rlfTnYyqp/8yS+hTy2bllO56uOl3Rzr/SvaqwrFX0l/9V +zFWW7dUUqj+/sl7Nr65Xcn6m3bK/+mq64sVuZa7itJTK+tVT2VXEs4rUrVcTacI84ve1LmdujHG+ +Pf9OpSzUvs4Btoki0WUybR2IFIF650KJOA3FBZTW3E4npu3YvXtSt7azpXbavtctntTeiadsmqv9 +txZM9GvhxIl/+qRv2+KaHX+m9fHEt+mlXZ22nbnO+njethdbMDFnCydWn7Lz11rtt52PacY/L+2b +28p2i2nTvz2r7JgvvU5pV3cLJtLpFk6c1WmVtTa2mHb1Wf/Wvu4+s60X5zlxzh3xP/2nNec5L8a5 +c5724qeP8b//nHNiOnHG9s7+t/Nx35zfK223NnvGF3/FTtteW3Oe87N7tmBiWzgRV5/1LW7q8+I5 +G/ed2b77Y7futFJMJ/VafTq27d1en06f1H96U4ztW+r2c8bY3qZzugUTK7Vw4rfLvnninxVj/N9t +cVv889baleLs+XOtTWult9stmNif++nMFHf/zLjd/qyWUgsnWtq16fRM2/5tfzrvbDwrtVk2vbfe +ebPnjLFbMHG6/bdgol+3aExudQsmZmvnW0vvN/XZ+VqKvf6tVPatlXrPe/G704n/fn+mV96fb2+t +Fkyk3Tg3lR3v09r251tcZ57fjrsx7Ynxz87Z0nf77d72qfU67e23f5taLOm1YKLjOr9f4u5qb85y +0vbPnqe19FoLJuLsFk5s6nfi7qa1TveeOdu+bj3jiuvsrvSvu7ut1rPftxdjl3O+hRP/Z84S/33H +nzH26TRXCyba6xX3W9nx2re21r8430pttbRiOntaMPFSt3DipW/RmGR5vRu33/+2OMuO2R/f7p72 +7fTvbtnZwolOr//tf+9uOmtbnDH995yv7GinBRPxWzjxzq/z3TPO9ud3xbi76WfcTudnv9deLPu7 +ftv8XakFE/O0cOLMbtGYNM0X/+e/tmVXTCumj+9neu289+b7j//O6xlbx0IuC8EsanUsO77t7Lb9 +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 +vizkOqEuE2IUW+aZxAAQsjD0bFtp07mMyJbUJ1kIQQPGjNO2sNSNYnvnkoVCOO1BpnVgkRBNIwth +m3CUXVTjOLCQUhw9O45e6qxtyyzPtmXWpOC6AGhfR/HX3p+YcJRdOOOqEY6yKxxll799ztd12+bi +Sj8i7eNsmYPsihFCbcNKBWIIp1l83dZZYed5Pi8CZhYxdy4elrywhBFz59Izhl+mIJJKmiizQDDx +uoyYhWClEA67olcKM08Eo0j7QmLMnUtIDEvdSKjjRrINFLMQ2zpQi9EdFEkizJugtmFdSGqe6H6o +zgMfP/2qgfHLPMyLuXPpL3rEYp612lDbNBAWaiJNDCFkGzH7MqJ759KZeNoHIzDLdELY9mUhp/mH +eSCHfWFbdNxvFCZZGGIk+pyLjDAL+bAwhNPCMPMEQCNpoddl3PgnptRGiECzbfo/a5aTYggQwlF2 +kbow7EAirtRhspC2+YMRGOo2D+E0EaeBMs+HOXAQAX6YAwcRH4DUhWAp9AE5hgm3kSBgIZbJNo+E +gREOwDDzZBsI0z7MgWMhJsLCjJQ/1IcSKUw+1IfqCEfZJcqyDYNl38XrPiuAg50v2w== + + + Shoal4zH7R/qQ1mIPqwDhd+lsc8wLHQbdENVYyFQ9SNLq0kvrTDsE5vfkw/FdVqogV2GRrexZRoR +sfKhsojTOHg4nxDULkzGe8Z+//Hn3H0vru50Wvr3Z9fGTuv//WnBxPzutH3epvk/Z5xnfmpzvf3v +fumdGU9MPf98W7NTi6230582gjIDk+j0LZj49C2Y2D1ddrQ2f/aK39quf+vFbWe7bc+Xer2fM8WN +4UTan++0lebP17s67ew2V3otzZ5vvn7v9Wy929576dvG2C2uXbPtWXH9WbHPOjF26vQ6vfTWp+/v +Fo3Jf3vN1Pvmx30nnX5vV/wT34srdfd7c73Xgon3WjjxXptrtnP+12rtlB0xtj0f21qr2+t4Zm9c +72N7cbVgoleLxsSCifbfZVc6H/c//Zrnz2qtxfSppd237VswsUMyokcHLyoIZUw/iWAcIox4MJg4 +W/b/ndRx457X32K/E8t+fKvfeem81nrPSy2caPOs+N7auPbN8zadtzqV7i+70jnbUkx9ZotrbWzt +/VqnbZ94us244p85T2ybzp90Tnrn9aZv52O3cKK1Tn9i774Z5+9bndLaTi+emXqmt86m1WduW3G+ +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 + + + diff --git a/brand/Trivy-OSS-Logo-White-Horizontal-RGB-2022.png b/brand/Trivy-OSS-Logo-White-Horizontal-RGB-2022.png deleted file mode 100644 index 89613872a98bc6875c7fce82e166ce3614383591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37211 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

cea$?y$H%;*_K4J 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/brand/Trivy-OSS-Logo-White-Horizontal-RGB.png b/brand/Trivy-OSS-Logo-White-Horizontal-RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..06587180294a2de05827c2bcb63f20189a011626 GIT binary patch literal 45352 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�o`7d!P2}m6JunbG^4;nrZ+x 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/brand/Trivy-OSS-Logo-White-Stacked-RGB-2022.png b/brand/Trivy-OSS-Logo-White-Stacked-RGB-2022.png deleted file mode 100644 index 2417ddf34a92dfdd4ec155867dd7318fa81dedb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81763 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/brand/Trivy-OSS-Logo-White-Stacked-RGB.png b/brand/Trivy-OSS-Logo-White-Stacked-RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..0ece65b88a0ae3a9d3ff6584c7c6320b6709ea16 GIT binary patch literal 28743 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 C8#B-V literal 0 HcmV?d00001 diff --git a/brand/Trivy-OSS-Logo-White-Stacked-RGB.svg b/brand/Trivy-OSS-Logo-White-Stacked-RGB.svg new file mode 100644 index 000000000000..52def3a62ddc --- /dev/null +++ b/brand/Trivy-OSS-Logo-White-Stacked-RGB.svg @@ -0,0 +1,3179 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +qt4aktqds6qqLW8s9lK9PkuNT9Lag/WVrsxIzq7VtW5ke0qRm/kpIuNhDZqYXGjf0aruJslrwymz +Exyjvcwnz+LYVO3oI/GLYmOE4FId7f/OzszkuuUQ1eEV3Szf1BnN/WTqxDIeq05nW+vkLCmZcsRH +iZl2PKK4Cm/nex3JJb9rKp3Oc1p7c1ValS8p9y7tPd2n8zqeUjquqiSXLgah0G4khT0b1iT2SCxd +7zSZ0qsy32Bl7H6GQzWasl/t0izVNIdGN3cOIZhHau5TelSZaYVVNg/VJVHdf5V582FV1pUObUfL +y73IamIQDAXrqxvRcm3ttPqRq+xGLZv0XW1Tdlem1Ch7V2ltrpX3dPFKTyQjMrP7zzpZLssibOnN +29RVk5p1dzV99xlZ0b9DovSk67OzNc5m3V67NSl/eXOFFzwsnNZY2n6W3RVrvb01OtWmPGsv0Uc2 +NjOyqskP1p/FI7IlkhnW8ExpLsm8B1a1vesZ4S9vabcrMrrCjk2h5WX+TndlxyKOueyq+ezr3Cyr +fuEvCyUnpy9eonOuEJ/To3Qjq2fdVbVgHsXLl0csDyw20z8jcR6t25Na8yFDI06PeqYrZ6ZaVVnP +eEIQWmIzIt9dTm08DjXnprs5O/zcp7CkDM/1qV7OPgz/z91OkrKcehY7dyvzkdhMrxJJXe3omLf0 +SHY0dkevH8qYj8OXzz6WtWtO0oumYu4M2mCNPyxEX1H9PIlXuvV61BFi1U09yVbSeqCn5iyHsVx3 +o03qujKZw4Tkujowx3U2Bznnl3M0Uj6OkIhM7MCjOd9L9KNw8l5yc9+VVBVPdVMdql1mTySURmJU +H6WdUc/SXJk1I3QgXW/3fIUOH1kzj04d3pVMiBAeq5uqvIdlDomPjh7aZNUI/ubjHesu55aZHVba +W8vjHYnWSbmjbYodxxplb4k4qjzsYFEqsYhplVb81KANni9/bz91PSP02Ky/MvpkV9urkMq+K7rj +dO9omv5aT3yNquhopHRTrPparfZaL6xK6arXKlWLdTobZ4YohaZIViMsp+taxaSksik+acgyeKfP +JUpO/Zx2ZFp3uzIx0e7nlDfvlIm211Wyks9d0bN1q44M0dR1ato8iY2d9EkyqTIhoSW+VT+oQlY2 +NaI3b5el8ezicz0pxee6e06j1zSGdCupU+HHaFj7U/Syp8z1vrGJyPLoLOuosHdCdy6SzCOT3qI5 +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 + + + qyGM22Ad+OfQwUVNJsvOdflF797C6Nkzt8nCXNC0ZC5tZWPcLhNzYavHsm43Wbbtk2XP+vwiZzbj +fOtsHO/d30nEs2X41mqex73aqNPriSwNexL9/s8joDfSPLSLOgu9kKZgxzm86y92aNqXuruMxutG +A1kC9h9Lvt8zuVfrKPLRRqCGvYkV8SeNGt49jny/pzHvxvnWfRzwnF1D+OaJMgXvJ9ZFHDDdj+FT +o13g7DIawLh66dR7J/DgaA9NEto2gXZ+pk+ululbq13S/NbljLvNtplxdcR3dg2hXI/RY5tj9tro +mDy3WYYPbuZh1PM9lHn9ZQ5N5l3WZte6skweW5/hg/MyeG51DN4aPcPH9mHk0uqs2pddujPXZW3e +ygSy0TqKeP6m8I7madzzPo989g5i3q0jruvK6LV5mr83O4jyzy6qPPxEmIT2Uun3Hrok/DeGd78m +MO7bFNL5GsG5blNI53XAeDYT6femMjFpF1Ue2jSAb95mcO4XeQ76HUS9D4OXNuOA52yiy0F76TN8 +M4GCu0abhbbS5/dO6gTbPZB6Ns5hnb2DqGfffOf8TB9cPeMHVxdtHnYlUG93SFKwGxQZeON862wZ +wLbZBa6XnXHg8KJ3c2cI3eisWy/jWgwa+IYJX3yLQQO/y8DMysJg/s60M2E2Lsye2jYb98d42lgH +bqYNiwlkG7NJjOPagOnklzu0shg9Nm327SbjfWwDJ8OggZd5XeA1GIasHFcsi9cVc5GbxXjHsIFr +gDCBj3l9ZfFsspi+Na0MYRtXprCNO2PYNsscsm1d3rha/sPAuPYCBu7DNLi0jXVwUSsTc0GTx7Jp +vkPWjSbLutFkLmvbDpzusIF3sPDF6Q0abDbUOVtaWlVYTA7Q9tAuMGExUTFVMXFVMVUxYTFxUTFR +vdVMVExWWkxcWlVMN5UUExUTFdPPEauZwnoHC2xqcH1sFxrkZKiZqpgSROXkse3poWkd3E1lXXFg +osrSwprqwtLaksqhY6LK0tpiqtLa2kMjY1qr+8qRc9pyOFBdTVFhYWFlXU11dVlpZU11WXVZ0VVZ +WVlZWW1laVFlbV1VcU1hUXV1cU1hZVFtZXFdTV1RcV1RbV1dYVFZaU1ddWllWVVRdWlZXVFNWVVR +WVl1aWlxUXV1YWVx2OLaytri0uKi6sq6suKi4uLSspra2qLa2tqqorKqurrawrrC6tK6mtrSssq6 +6rra4mC1pdW1ZXW1pWWlZZV1daWlxXVFJSvIacuxUJV1pYWlZaXV1dWWY+FqamurSqtKa4tLa6pK +60pta8sKi+4CU1XfuuKi2tra4rqq2qra2srqqtqy2tqqqtri2qK60pqy2tqastrimtqy2tra2rqS +2tqimsLa2sLawrqqytrKyrrSuuLqwsLq6tqa0tLa2tra2qqyuqKq4trCmtra2rq6yqLSsrLasuKi +mtra2sLqwqqa2tLKusLaqtKSmsrakprKytrSwtrautrSutra2rqS2tKaotqqmtLqmurS6tLqmuLa +wuKaytLS6uqa0tLS2qLamtLS0tLS2srS6qrKytLa2prK0tKaysLCyrrC0trSmtK60rKauqKqmrrS +0uqysrJwZXWV1dWFdaW1RaW1dSV1pWWlpTVllWVlpZVlpbXFpYVVhTVlpbVlpaWVxUV1xYXFtWXF +pZVVZbWlRaVFpZXVldXVlZWVlUVllcVF1ZWVxcWVlVV1tZVVNZW1lWWFlZU1pZWldZW1lTWlldWF +xZXV1TWVxXU1lZW1lcW1NYWVpTWFlUWVlZWVtXV11WWVpWWV1bWVxXXFlZVVpdXF1cW1VcWVtcWF +hbVFZXWFdYWltXUlhWWVhVWFlTVVhbWVVYWFhVWFlUWFxYEK64prigqrK4vrCgtrKovramur6qoq +q6uKS6sLa2pLi0orK2tK6yqLiymRelgCQBr4JAHLOypjyT4mTEAVhWxyIgI5xTT0gQPTi6OGpjdH +AZqHPWBsIvZYxSz0UUPzsEcLzkQcrJviHama4RwfNMU3UDcVdYSCShJZ9BQRBS4SShVbsUrsD29Z +4iGpXPmVMbKYBY4DoK0bJ0CWYRyLIWlLqBdOAX8UXi7PJPCyrQac6ceJB70wcSA+xHP4Dq/hNryG +4/AbnsODYIi4kxATP0BkgDdgcuJwWgpQSDzBHIxXgGUhIMUGqgQ8gDHxkAwTMnHYgUc1EMwHhKGG +qQB40DA2VgKGiKUAcmh4iSWlX5MklX+xRjwvlxCCr2Ch/wIgRdZ8cSWtk9EHpuciD1BNxB0hNME6 +Rngq6iAVrRyCOBo5hPFTEbazEzEIaaYhjxeXg7A3MA176MA01IHDU6zDVZOHlLM7BHT4tbGOmc8A +U7h+TKTDg3EMDUFCGivwO7IsPiFBAo6FZIBP/TBxKBokzgRDxI2yPFzoJYcX8R9exI84Ug8UpyE4 +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 +sSFwvMB2boyFrI+lcGgbaxGD7GGAnVkIRErnYQ8lm98bLTS9Ol5seneg0PTimMEpppFiU3xjlZMx +x+dmIo5UzkQcrJ2INGh4ch4B/Pw08sfpoQlcZgFN1CaHQOkqWpHS38ZaxBSMQ3wFOXmkwOckLOBQ +NEGchttwGB7DXbhLlr+4uORwH77DgXgNz3nhMpxzF07Db3gQDhPnEOEKqQbnBbrxAMYyvUwwKfmi +EAGlXHL4uGQAPbJJAPxm6xO5zcQen5peHiUyD3Ow0ATrGAFKCSTR0oUVtM9JIeJLwx0yMAt9zNhE +5OG6GdbBium9gWNTbMP180MTuUgmWGy28RHt4XiL7DfWohUioniBr2VNcQY9RDyI53CdrAzX4TO8 +x2WG5/AZTsNhuEyWc845z/IXzjnnnHPOuQuH4TK8ht/wGo7DY/gMz/IXPsNvOA7n4T7ciEcVRfE4 +swhiYyoaOr2xnZZ+TmxYAjKh4dnZxA98QABkxyQIeEcpAOihkUMaMQlhdWx6d6DQ/PYgofnNUSIT +TKNF5veGCs3vjRibiDZMbIpvrG4m4kjlZMTxubnIo3PT8UanpuMNzU3IAj41I2Vohndg8QvGJC5k +IecH/FtR8QQ5ShyH43AYHsNfOAyX4TPcht9wHF7DYXgMh+EwPMtd+At/4TU8hsNwGA7DY/gMp+E6 +nIczLT29CMJ9AbGGwYReEzdk8dC+eJQUA84EhYBbcFDlEmhH+KkhtpA1znFBbjwAMUxTKXMBW0xl +OXU5dM7bnJZUDp3W1lRVldaW1JZWFxeXmpXWFlsXm9RWmlqXFFsbF5YUVRcbl9SaFtvalZWamhba +VpcVVhUV25pallRalVWXVBfXGpbU2lUWl1SVFRZbWtuV1tXWFhOWFR6HqiytLaaqrCwms6ecB2hv +d3NeXWhpamtXVmtdamhVUmhXW2lSV1htWFJZXFRtUlhUW2poalVpTHNoWFZTVDLaHtoFPzQtmxsa +3QYmLKsNXmxrdmpwdXIDpgRVVWldVFRYVWpZXGpSVVpUXVJZWVdYUmhtaGtSbVVpVWttXFVRFzbI +e3leZlRVG7yimB4wJTDTMqMyi2JywHRhg8yhQ91ALCePbU8PTauhzkHbQ7uwVvf19DRuoML/UPol +CAH5s2Rs1k8hFmX81mYZPzcaQYjJOaxJa+8Q5bWLRTnBlQDlVQsUOdhj7tyINAktDEGlkUC/QJl/ +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 +TkKEEUqJB7GFBmrd1T2DfgaRzRYCjZ/E/7Zi0WPxU6GVA5MJ15BF0ne0G6BVasDFUEmVArSor2yi +dnDCFq2dR+toH+2KGL/0wdngQY4mEQ5GVQPXFDksXPn2sw8zOCDv7d7Bl//HyvSsGYXxkOCqE0fQ +JWfXZtAsCaJNeYyjtghPrWhoGltXwe646FbGCJdyj6nRYxE9Sa1K1wJT0FuflP3s9FxVg08goCMm +CHZ6AaIFc+2fJTJFUWQMVmSZwRqQ9FEnAxSjdNdV/G1PlWs0T3GXgicEIcKC7Yg5FlRysdMwy+vP +TlDWs+lbxc9hbYI2L9aT4Gror1d+c8ts9r+XryCo/gs1T2s+ES1zRBHPkt1BEJocQBFRYykhqRO/ +eyr0bPKIRXJikNxDaUTCEgEc8MKkr8+xQGzYVf8JsxNjsLBwvt7xKKleJkRfCaMPFp4b/oYQdDod +Yd4V//REFxIuWMNFLwSHERWtzkGTJ1HYJF6u4CVg6QX0pn6c05FF0ty9lWO0IKi/FUaQXZENasnr +lDMtXHneLtGoI/13kwPHyV9Zu4A8LOq7vxvCqSFlZPPOdhhwxnS1VHBNH22d+cKxdPyas0/cLvTR +92CezayHsgpv+FTFppbsR9yEEcbtUsIwTwDlLpEMzu3+hc3P2WrilD6xkAUyPsSKcAyeMfqCNTJK +DCyYrHjgqZHjdyOPBgCoB9TO8PaczQ5OcYrRT78be5rrLzNQl6++VnToshs2jvf9ZjnGjKaMJ1FD +4GrWaGFLuyZTNYd3A3vCMOpNQOzCo45oWyANcXpJaELLmNHVrzyrJIt1sZssp5PmEewJAHQKnzJh +ZGM5MDU1MC1lY2UwLTQxMzctOTFmNC0xN2M0MTVmZWI2ZWVkNTliODUwZC01NjBlLTQzNjgtYmE3 +NS1iODYyZTBmYmQ3NDQgNjM4LjI1MjM3MjNkZTBiNTAtYWQ2MS00NzVmLWI0MTYtNDk3NDMwYmEx +ZjgwOTI0OWEzOTUtNDBiYi00YjVhLTkxZDMtYmMzM2NhNDlhMGUyMy40NjEyNTUwMTMuIEEFyyEi +PK/2G5795nSQBlCtZhpYq5HmeaC5I+e3mao5IrTNqQTfThDoBqQNOeCvwLpQOYMQgljDWOean5ox +mIYH3NoN2gWyJmrHSno0ph88+OW3c/SY4ADufA/sOhk27tQGjjVXgOc3pyk8mDWj8d9EBOoGFqYB +8gMLp2HQf3PPES6BCPTmG1hLj9b0g9cP0QU2TIwARDuBMTgzZTQzZjg0LTRmY2QtNDQ1Mi04ZTNm +LThkYTE3ZWNiNjIzODJlZGI4NjVkLTg1M2MtNDk4YS1hZjMyLWE2NzZlMWUzOWZlNm1sMTBfU1ZH +RmlsdGVyDS8gOg0vWE1MTm9kZSA6DShmeG1sbm9kZS1ub2RlbmFtdmFsdTEgL0ludHR5cC9BcnJh +eWVUdXJidWxlbmM7Y2hpbGRyZW4vcmVzdWx0KHR1cmIyYXR0cmlidXRlOyAsc3RpdGNoVGlsZXMo +bm9TYmFzZUZyZXF1ZW5jeTAuMDVudW1PY3RhdjJ0ZmVDb21wb3NpdG9wZXJhdG9yKGluaW5Tb3Vy +Y2VHcmFwaGljeDAleGgxMHl3d2lkKUFJX19pZG9iamVjdC9EZWYgOzRmcmFjdGFsTm9pczRHYXVz +c2lhbkJsdTFiMmREZXZpZmVPZmZzZW9kZGRTcGVjdWxhckxpZ2h0aW5nUG9pbnRMLTUwMC16LTJ6 +c3BlY091c3VyZmFjZXR5bGw6RXhwb25lbnQoMUNvbnN0YWxpdFBhaWFyaXRobWV0a2s0azNrMzEw +MTIxMk1lcmdOb2QtMjE0eTRCZXZlbFNoYWRvd01vcnBob2xvZ3lhZGlsYXJhZGl1MS5iYm5iLWRu +YjJuNURpc3BsYWNlbWVudE1hcChibnMzeENoYW5uZWxTZWxlY1J5QUNvbG9yTWF0cmk0NDFtYW5p +bWFjY3VtdShub25jYWxjTShsaW5lYWQ1ZnJvbXRvNXRvcmVzdGFyYWx3YXlmaWxsZnJlZXplTmRk +aXRyZWJlZzBzNTU0bmNjOGNjY2NjY2M4Y2NjMWNjY25iKC01NDFDb29sQkRfNjZlckVyb2Q2NjRf +KDdyZXBlYXREKGluZGVmaW5zcGxpMXJlbW92UjEgMTsyMCAxNTsyMDAgMjAwOyAxNSAyMDsxIDEg +Y25QaXhlbFBsYXk1MCA1OzIwIDIwO0RpZmZ1c2U1eWVsbG93O2dyZWVuO2JsdWU7aW5kaWdvO3Zp +b2xldDtyZWQ7b3JhbkRpYXppbXVlbGV2NmQxMWwxcmVkNTAxMDEwMTIybnJlZDY4OC0xMzQyMC4w +LjE1bnRhOHg1NGRkb25GbG9vZmxvb2RibGFjazsgb3BhY2l0eTpzQ24zNW4xbjAxMDFHcmF5KDBP +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 +lWLD723rnSEnUzAhO5/X/n8zszVTw8iilFJKKVOmFqkfq/b/4Jg73lcD3wfDBxcJJKEPyzy45pul +0zhzlrMny6/MMdcq+nRhmWed9Noq1tuVxbJf2uma0k4kLPM0mq7JsvJjvhn7tS1ndadsS7NT2dHO +GSetppDL6fIzljRer6K8Ty87seMp+1qZI62OW85sC31aaApJemWdQrmyTkNOPfvHOuu89FIrMZ7Z +5Y3U2lol9Xg2Jvau0xad0q8S36/yV9NVXfTO91ul+yXvdUuq1/1Je9qJJ01sBvOyHjtI9fizwvKn +UFVNVnVtzk3tvRJbtuI7+52+pO+X/etWVlK0VXz3xx7fzuojusWfSPF/+me379WVO1PzrOJ3fzeu +EnfFVfzPM88ZH18c2ycpz2oaiV1F9yriPF2TFW/sK/GcrthXlfZKPKvq508XKfY0Epv6ex1ep1Hp +9FglzW7rlF+RKM6z4tvTlR9XEdunLynF8ifFN/dX0f50XRhX0d4Oh6eOm9pbYa+i52nhClcXrioc +bbQRx+vyRownTWxruiYr2phjztFOVswxV7mK2cqbqzhvFe1EitlmZGC3WZ8t4zCNrjfTaqe82Z32 +S1pNXH1X98I/jaarccbSLf1v6dVj6Tm/P53zZttY+uN5Ua/inNPl/0SaslZx9iR1E48v67IsknVZ +fV0f6kNN13V9qOv6UJP1oTDuD/WhppIDaDTCvLFMcajq7LHKs0wrF9lbYdNtlrHM8ahSnOGudYRV +LrpYlYEyrWYFZVUGZbRpYwMAAAAAMC+2tmfMHxFEayfrmqzpmqzLuqzLuqrfeuF7r8xZ5ouvyZrz +Zft0tbu72zxdk1WprVjaeb/lna6XGOPpmqyeLKdzulrSyarV5ikrnk+p7H5/0l+TZauvpsvx4ym/ +miyK85TuuF5v6Vd1e7oyrrJWk3VpbSvprDRPSUmSVqMLu8wVxRbjarKulZfkk8qLR9NlTdZ7pPdO +a13+lO/VRWdbucKNs/f/xdm9sdvGb+m37GitnT9bZvDzILP4iDIGXwaCMrTYhSVMpMBQPlQmw/lQ +H+pDfagPRemHmkCZD/WhRjK8w+N/sudpm1XCaVfl40OVgNhFfBCAAJQ4MY9mZ5F9UbW4ujbjykVO +K1BohqprQxOHMqWAbM9QhjN2RV1Rb6wahS6tcM1Z1XX0oDot5UNNfHyoDyUAAQAAAAAAgAAE8O0f +3LFnRFCFfKgH2Nf5UB/q86Gm0uUj/DIGHEW2gTBQ05SA2IWFM4UyNtf+3NLzz/vVq7WyJ733n7q1 +Nz7N/9TvU4knvbfxrY97epW2il4tfnd75e1r+/a89sb7Pv0tpfU+ldX2nZZKez3n92zrjbheSt0t +9ks/1376U1af1nPX27NnN+2ZfV5cq8WyXmxt/aa4PnZ67VeX1N77b2dTfCV+SudbLN2zxCRcja7p +1cvpPn0aie1A2jTOtc3Y0zUnktP6ud/r7Von7p/Z58z2O1qvnumcnun8ae+dE+N3+W1xv7c3/X+c +5fW3rmxJmUz8CZSZRB/RY3+y7UHoCT/MJ1NgPgE+1PRA+roRBwXGeoiiTPR1oWwj7DAs0cFtJpS5 +sx1n984T6WPaGzNte6s4P9/c3bavnVZ6x74mC08XrqKVN1c213aJq4mEsfXJmq58TVb1arpa3mqy +7K0UZyptdZGqtNGre5jYpQadyOs+zZw0Q6+9cV6LqV+v4vQq+r09XcT26U43PqJP2EfMLmml7njW +W+esldZKKZ3TFWedSN3/3f+NaRUv7f+JNO/sOd1nd9PuntN9tvetYs/pPm1fO+uctWaunR+0Sq/e +fqQfbWVpxrbTaquIq0izdTurSKvpil5FWm3bWSmttmaqdFslreKt9kZKvXoVvYrV1umKtYq2qmKd +LiK19kYb7Z2uaKtoK1tdLNtOWuu7X1pvZ9t0Xowf55knbVzb5vtvvUoq2jKNk4WYxj3OGTGN1vua +rGinq8pekfJX1XRlj1ZeUrQe80+a2Fb8r2z8Gf8nK/5H+1X8jz+lV/Hn56+mq5pI9l/0YVYMNVH2 +WTNij20jrSVhKBt9WXWnFDu2tor9odheVVtst9wrlh2zTx0OUyYTexo1zYQy8eL6VXzSR7y2iv9V +9GkkEz12rmL7BMo4vTa2d1W1V/FW0Wfl9Nqcs8y5Y3v+6HMixRt9TprYo8nKfWmernir+PFnrNF7 +XpMV3SP+KuacZfvLHH/GizPur6rpwj+RonuFfxqJ3T6VHL6MQffhujAsZcKv8xxsRNrXGeE0bfPk +DzU9fVmxzf/PIdJKnWwDYdxmen+oD4XrnZ6t7Ony21i6T1eWtCK5tLH+hH1g2pfOaD9HruMwlOgT +96E+1If6UB/qQ32oD/WhPtSH+lAf6kN9qA/1oT7Uh/pQ14f6UBPpQ9lJ9BE79tQxjQ== + + + JmvO3O9ZdpU+XT1Z8elsWT/WSj1LG21uSaP9W2u//MmiH3G9Ns5quibrZ+Wzql9N2hJ7dd1bXq/w +rSKtJivOryqtU96vqpy2W94pVF1Wj3VW0foU6uu5r5U9p8sztlWk+U7p9UpayZ6W5izzT1e0tqJV +xPlrFW2dVVJbZ6bXZP2sVdKfj6mk/jNL6lPIZ+eW7Xi66nRFO/9K96rCslbRX/5XMVdZtldTqP78 +yno1v7peyfmZdsv+6qvpihe7lbmK01Iq61dPZVcRzypSt15NpAn7iN/Xupy5Mcb59vw7lbJQ+zoG +GCeKRBjKtHUg0gPqFBhKxG0oUd59M87ftzqltZ1ePDP1TG+dTavP3LbifCulNbfTiWk7du+e1K3t +bKmdtu91iye1d+Ipm+Zq/+0lE/1eOnHinz7p27a4ZsefaX088W16aVenbWeusz6et+3Fl0zM+dKJ +1afs/LVW+23nY5rxz0v75ray3WLa9G/PKjvmS69T2tX9kol0+qUTZ3VaZa2NLaZdfda/ta+7z2zr +xXlOnHNH/E//ac15zotx7pynvfjpY/zvP+ecmE6csb2z/+183Dfn90rbrc2e8cVfsdO219ac5/zs +ni+Z2JdOxNVnfYub+rx4zsZ9Z7bv/titO60U00m9Vp+ObXu316fTJ/Wf3hRj+5a6/ZwxtrfpnH7J +xEovnfjtsm+e+GfFGP93W9wW/7y1dqU4e/5ca9Na6e32Syb25346M8XdPzNutz+rpfTSiZZelx27 +Np2eadu/7U/nnY1npTbLpvfWO2/2nDH2SyZOt/+XTPTrlw3KrX7JxGztfGvp/aY+O19Lsde/lcq+ +tVLveePF704n/vv9mV55f769tV4ykXbj3FR2vE9r259vcZ15fjvuxrQnxj87Z0vf7bd726fW67S3 +3/5tarGk95KJjuv8fom7q705y0nbP3ue1tJrL5mIs186sanfibub1jrde+Zs+7r1jCuus7vSv+7u +tlrPft9ejF3O+ZdO/J85S/z3HX/G2KfTXC+ZaK9X3NPKjte+tbX+xflWaqulFdPZ85KJl/qlEy/9 +ywYly+vduP3+t8VZdsz++Hb3tG+nf3fLzpdOdHr9b/97d9NZ2+KM6b/nfGVHOy+ZiP/SiXd+ne+e +cbY/vyvG3U0/43Y6P/u99mLZ3/Xb5u9KL5mY56UTZ/bLBqVpvvg//7Utu2JaMX18P9Nr570333/8 +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 +kpdtbBio2zoZUZZtmVF2YdqGRS3kMBuGNE22gTCOjIRhbFiou0ANxZeFHEWo04TYxJZ5KDGAgywM +PdtW4lBgSmRL6pQsdLABY8ZpW1jqRrGdApOFRjitQaZ5YJIRbSMLYZxwlF1U4zqwkFIcPTuOXuqs +bcssz7Zl1pzgugBoXzfx196fmXCUXTjjuhGOsiscZZe//c7XdRvn4ko/Iu3rbBmD7IoPQm3DSgTi +CKddfN3WWWHneT5PAmYXMVNgPCx5YSkjZgpMzxh+GYJIKmmi7CKE4nUaMRvBSiMcdkWvFGaeCEaR +9o3EmCkwIzEsdSWhjivJNlDMQmzrQC1Gd1AkiTBvgtqGdSGpeaL7oToPfPz0qwbGL/MwL2YKTH/R +IxbzrNWG2qaBsFATbWLoIOOI2acR3SkwFBNP22AEZhqKELZ9Wchp/mEeyGFf2Bcd95wEShaGGIl+ +B0MjzEY+LBzhtDDMPAHQSFroddh6rg8e3H+Lp6yOHTgIR9lF6sKwA4m4UpfJQtrmDUZgqNt8hNNE +nAbKPB/GgAEE+GEMGEB8AFIXgqXQB+QWKNxGcoCFmCbbPBIGQjAAw8yTbSBM+zAGjg== + + + hZgICzNS/lAfSpRA+VAfyiMcZZcoy7YMln0Yr/usAA5SfNlW2tjAaDxu/1Af6kL0YR0o/DCNfYZh +odugG6oaC4GqH1laTXpphWGf2PymfCiu00IN7DQ2Oo4t24CIlg+VRdymwdP5hKB2ZTTeM/b7jz/n +7ntxdafT0r8/uzZ2Wv/vz0sm5nen7fM2zf854zzzU5vr7X/3S+/MeGLq+efbmp1abL2d/rQRlBWg +RKd/ycSnf8nE7umyo7X5s1f81nb9Wy9uO9tte77U6/2cKe5MJ9L+fKetNH++3tVpZ7e50mtp9nzz +9XuvZ+vd9t5L3zbGbnHtmm3PiuvPin3WibFTp9fppbc+fX+/bFD+22um3jc/7jvp9Hu74p/4Xlyp +u9+b672XTLz30on32lyznfO/Voux7fnY1lrdXscze+N6H9uL6yUTvV42KJdMtP8uu9L5uP/p1zx/ +Vmstpk8t7b5t/5KJPaIRPTZ4EUFIY/qJJNPwoMSTycTZsv/vpI5p457X32K/E8t+fKvfeem81nrP +Sy+daPOs+N7auPbN8zadtzqV7i+70jnbUkx9ZotrbWzt/VqnbZ94us244p85T2ybzp90Tnrn9aZv +52O/dKK1Tn/iCyVg1l4CZt15dCAwDm41VIyDM1g4Pjg+GhJ4DQkmunqoNFAaEky0hWU9SRodkkYn +omLhWVhMC89SqnCJClLFgqwwZ6nCJSgUQmFWkCoUKBAKs4IUXkINxcKGIkGhgOIpFIQjIIL/NBQJ +CuhCPx+Z/3xk3iNTkPXEyIJESEmEEyMUv7gw/EPpM+FQ+kyMPMz3tnhcGN4jl3SyC8NrdHRKIheG +D3HJd0SdB40Lw18gYM5B+CBgXnrQhYB596CNyEZzYOOTmrwHkI1IwoGNyGYj0skR3gNIJz2QhNeE +LHgK6KJZuMqArcSx12s00OsADQCh8ACRQACEfgJMTqETgrHpDwIYOBORZNcCB0fHeVLIgZJdkLBB +CiCgIp2CICDARfJBJzBYgQC/XHUSYBdaBpVgCWQ4OG0RcRA+QLqJAMqBpF5khAJoQBDAYMhEwATe +qIqFJWNZIZmxqInToWWAFLAxoAG5EhwciyG0DNhoRHBwRAYoZM6mJErQfDCPrUOSEfF9JQxO9JRE +yAbGs7oLy4YCyg646LSFyR1I2AYMCBGhPMbF8qlJpCFx3EWNeJCPz0fmreleFgEUJgjqgKCOtEqi +j8xLq5KWx4XhLUmBGH2fzsfHx0cnR8zv02kKxOj7fJ8FByoEH1FTheCjCsFHFYKPFhwoUOCjkyM2 +EDC3KgQfVRB81B6Ix4dFTTwObNzKOLBxawHDqD2QjgfSieg8OhZK5qFSAlZKwEoJWCkBO4+Oj46P +jo8FAzAOXikBG0pAh0xB1vIXRG2F1oKoLWq6LIjaojwsiJphmg0fLJuz4YNlJI1OhOfD8+H5WOhk +gom2PljWmQ2M4YNlbeFVLCrVITEhAEFNFp7F1EAA4rJwCYrhdkjMzAZGAMKCAIREaYBdkBUmCIKP +uoL0C7LCnEoVLrHQkOCCAIQEg4XPCtIAz4KowsIlKgQqLCVZYVIoaKCYJCCC74AINh5qKBKVAiVg +1hQKGigYNhSJCjVZFFSIIGFDkagQmDaTTkSFAuwyEgQi+A2HygqR1qgnRqbvQ01gxAQ1gRELCCCX +hUtUJjYgjINTk8KCjwyCRDgh+chMUBMYEX43wYT3fUA61MR5OhEVaiJpdChOIXdEnRxBTRsZFRJh +RKXTXTx0RAylDzVNTFBEpROGXBg+s4FNgLhk0xFVqMnSEWY9AAR1IjohAuYEMjjYgsWGIlHhzJAk +xDse/ME7HjxBk5FYSh8IGAdzoCbXHNg0TNCl0pH0BIMC5t4DiOZjoSHBxwKGUW8WpEZW0VDThkNl +VRYsOhccHhIT5MCmAnnYPMyNyIYmI7EsTB/Fgc2kpo1IQ0U2kPluQcMABWLUDgsOdKoAHAUZB++6 +qeODZe2QgOCZMGhEVAhQmwiLTAnBU7QEwz9cMJQ+FLmkAOiiWSiqVjQBh9JnoqmFBBOt0dHJESWa +TgUSUdGAXabylCYjsWTeu2AcvLt42EREVKiJwEXFMj3U0huMQdSakE6OoHCIKF7EA0SCZslsYBNN +TV+JE1EhQKJgDmAcPNNgTSpJpaaMj43IggTLkUoiJJEBqyFn+MJSouGoEAyYTCI6wI/hkhMBJJeS +MXgkeOg0NVGQgwAiABF50oZCgsXozOm/JCh9IA1064SQFBZEzI2MJAFMWFgQeTIYGFTwUBEIDX0q +fMGDMeK0K+AggAZAKDWFbF5HQoIlMPICKpVMUPo2CBgHbwBdNEvCxQKCgO8rfVwszcDhC0uGeAQ6 +gUGLZJgJEZSDX6VxYXiE76OQrykLbGgeJtaG5mHCKYmoTKQCkgeQXFEphF8RKVR+oEGV2fCgsTAR +FihovqMR2bA0KFBI3FpY4A2wGObCpKaNjUx+T4tLxWY2MO6iRlQ8AQ1exMLFhodaeuOBgpSAR9L0 +T0BQScSFwuT7VKuyMPl03gJEAIgFGd7NCAynNGe8YyQvjlUe1CMiMA6eiYyIfFCKSAalBEElpBrQ +kExQDlgFDYUCJWvEoxccWHA7PDyQin8Iv4xug6OpKbMh8eTs4VFQUspoqUBHtslFKIHow7FxdecR +MjHgas7zIBKw6W9BI6JCTVt3iahUFKE5osg/IWl0Kpvvm1QsiNpBgOZDwYHp0aHQ+gkX/nV1SMyt +s8FRwYFQWbhEgcpyqZQ4C6IGuZSMYUIlKH3SQy3N6dhsmgAIpaYKiBDBgz4KTU3gikTYHsamwQEL +ot640DIoCwcGfvBQS1PTJuwgKhoNE5QIhv9I97PAIZd4cF76FkAsiDokACNUBnwGpqZKiQbn+yYT +ARYHERAEysdMQE0BKiQOHkIlg2JERFriQAXDBlFygQBC0NREcQhNFGQUGCKXBwOthSQEoGAKUNOC +R1VAAmNC8WDIVwSDiEdThNDvI7FgZBwJVgvb44Z0Lk9YavBQcDQNoSZqQTvXnReer5PSwgCDBYJD +xpbRIgbo91ETSGRzgbMR6WoqkaF3QckEAjU5zExxdYQBTsmBzYanZEGlVCDz02EAvbsgao+HpYTq +AhgYpCYDCQQ6nXWyjIuFCq3jNDUR0GBQKpM4CBoCLDgdAkKvgdKChAS7EUBAhZoQhEhQGihPUPq+ +hcsAUhAEdCAhHZ2gpokAA07LwNkQx4NaEPmwECFjq9TEESDS0QVRV6yLCw2RDR5qaYyKR/CBgAGo +aQPCOLhoCwPMDmZg0LCYggMfEkTBMKDqIHQYSOg0NSXAYDwaVILVFODgNEbDxlWwIg4CaGUfarpw +aE5/gNALKqHgQFIF0FCASkWIBRFBTQwXAhogHglgyESAAQtoS5jQMGBF2nNYUBNcPCQfBJ8I59no +6AX4IF2YdCIqJXxNSU0DHCwEH4nduHC+IGoKhcCA+UF1MGhlH4qHWtoCbwc+DzDA1qkRFZGJBInv +YNAiSzQahAiG1zAgmIAcCTwXBlRw0GhLxma/DRDZsDBcG8zkNDSQL8jQyrxwKB3H6JCP8SYiusqC +lG4MsMtQEwW5WNprsCZ1o6wQBlFbDpVFoMGa1I32sDDpEWxh8pBxWZgQqEKVCYcMVSYEJqaaWMhQ +ZWKVRFQmYUMwVC5HTajJYlUWOBSQPEw8Fa4mGDJUmUzC/76Ekg9Lcxfj4KEL5sLhAOEY0LSBA9/G +gxroOLKAgAkcAWaLAdRUgeE9YECXiO+zss9EkzA88hu4zxuAgYDjvhEReXBQg0FjQGdAd2Gx4EoK +WkJBR8cTED4P/nEBIniQbgRwOjhEMjCTA52R9YG0N1Zo6KYmC8hDIqPBmlQBo2vKSkEXJhn7WJhU +l6MmlstRkwRepzK5Pi4eJgnm1tnQDFCgMEz6ctR3NQqTENHnYUJNFAgEKhMDCkgeJl1DMEwerMrC +xOFy1CS8GoVJB4LRMLlWZWHSVmVhUqGgCxMDoc/DJIPzD5MDDJZq8g3tUElIMNGkihpRqTzU0n/R +1UTzcfEwoSYPRKkykaMEDRNPc6CaYDBYqkmEDFUmCRQDlQmG8w8TEAGumpDA/z7wCvE1ZcNIpeI3 +Nk5JX5m5efAS+JxmqDRzKHSRokShUohmJAAIAADjEgAweCwek4mEck3QMkTaAxQABGZWMnxQRDKV +RkORSCRGUhRHcRAFURQyxiCEDEJsasgAJFbkxA7wPyp+C9w5lSupFMu1cchfgovw/WblOI92xU/P +d8KmPalWM7fnz2OrGqL3w+0RAiIBGtrnt1Z5UXN5ayU6kPDrz9CID1z/XHAwG0d0yhO5GAs26VtQ +Kw1h6zWE2/QxC6s4FNOIatVwseou+yrxa6lLhMYXl2iRKVsnEjqASwBnuKo3dVzb300/JjRy00VD +xtTZO9ENdkSsPZ4Z/+L9Edy9QNeWv6Zz0x1PDjZ0LvzIUFqKHACH2hjVeegQ68EEV8GEdg/Ez0Dl +DtsKtkw35XXzWfWAhgn70zDdE4JM7I/SaFpaRRB5mKah72O6M+ex6ktT7VS8xnRriRG32pq3yUbw +9T9jN1Hpyh1MV02fZyhpkdnvApzdyoANP9FFnKIYUqpUuhVWxVPEdPGwDJLSjd/7ePokH44x2k+B +AsyOKj9K54psthHpTr6QiGV5UTTNodJIWb/GZ5QqQ/CDDIhN1JJmBk11dhOOp5tli1QGgPF4P9Dg +WJZrasUOyJuBGNL4dMrzv2h60QMFfRfrkdJdA1nDZ3iguTLLJkeTVIbMaxPQaltLin4WXL4yHmol +prPlcucYXB4U4ZEMoq7OaExYTtbVR6kxjnauzG+CytTTZZiX5Ktr+q7ghKsueyVug5zZ6Yt4wKQr +imMIBw/GryCUarPRfzJWB/pZYf3VOxkR81FJfXhBPryCcIk2Y11UKQtes+DW1aUZ+5natmNyudiS +MmZDCKdV4uZjzrgXA2hGLoF3mYaTSIhEEGQCu4tuWQ8C+Y7sEOgf79/zHbpTYooXMg8prRcBak1A +SKSGV6a6jl3LLiAMHYJrnkSD6LeLgOI8iMqIca8VvprmpDDuW97ABh30H0gXwNCFu03jJ4FO5u06 +htqtEj1cw6OzyajZfy1clK+kKL4d6ivjhMw1OXrHoXurfdpstuUB+HS6NNCSFByrEQULgbBHnIof +jI5Xh8MxHIfz0DxBqZE5I33vWbR05OXSKt8g7CGi9srA26sMBiDmO7EXaCmnsVtuNnYmi+j0E858 +3yODiVLkBk9byqfOG7gzACYK3MxoNY/HaxzFqvRKY9NXht/wevMLcWY2sJdp4pQsps7hMAUKjgUb +k+/HDpcZjoFZnHVQlA9lq4Ch7suX4+7KuZJvpHCoUy87H0Xp3hcJ6/P9kXCre9ZT/sCVAtpnC55m +s5jy7fJ1xok2kc6175svoyHzDPmmX+HwHm2Qp8v5zxE4YQC+UgCbFdfGum4gbNtkbw== + + + c8VTOjj/3Ga4FEKHO7GFIx7j7A8CA2Le2Skc4hQQebRGgUVSX8s7yyy19cZ+VjKBt4tO4vzXLj4w +A+a3JHMMVixRecIpmXYNSWcbIyvdncKURRepDXTXiQagv37N3pXIdSrFc1y9ovlSg3GocuTMtxzy +bi3NQ7fNgjzvVhqdeXoWYIR5Nx5qK8m1JTxzC3Qsn0O0/EhqXg6kmwHVj91aIs5aNTPR7yfBUDlj +vrV0sJ0/UrqybvdavIRS5LwSEUXSZ47sBJSJGJb3BriZgxU+GGkOYFWzkzHrEEFw+Hr1bZDGtNsW +4l2PKV2POU8hIea1PZHdZk6J4wh0/sGh2uVb1gOb163V0pkKq1jRrXgTszWoBHZVwjjeeuAdF3SK +yjQ8gEDALv6SWDiDDoQVjWdJ/VIP3HEYtD0jDk8AdtOraPwMcOS6RaFYH7RdbG8dpU4YBoeJuPuP +zEC+3zmF2E1B32ObLxyzNs4WSMXAHLkQrdlLt7e0myyeqrASjUC6AoMbU6T9Ed27p2Q/C83J7StW +6gMp6Hucibjm+WADW4wZxi7H+wFShT5aMjhfJm6hyCmvTw0AxanYxMC/Us0F2OxoAgKQpdBjK9Sv +0d30T11oyuVeirUNiYI6pmT41TQxMTDwgCr4CfUBU217wT+dJzWt2xhzI7Vk9BN1CetHXVERnz+1 +BiDI71QEc1MEyuHndPQ3jfQ7tBQ+dbwawMbmUH+nvOw4PoA5F14yb+KLpATssMOGYgCnTzkTRrx7 +S872MOA67bSMWLXwwP2w8DaaETMpVZAyG4vy44uJD+egiAkXStNexzfgyW6jWKeYJtoszMz4DoH1 +df5GIvGobTk+p54ZgB/++4hYiHU3hSqQqra4VIv3rY9YcgaFRwfFxvHZhln+hGgcMoBJECitFX/s +OvZU3q7xEWAx4rTVo5EstxhtKoECMAgOFxwy2TtzMfcOSvrCZXdtcj/YFhx0OqTgLxP1CfiTC598 +lXG1cdXmWCEgIAC4jFIMPOD4Y9StGFPvCNt/3RKt/mEQ+fXXZICbCHvX8XEd5L+NveRNBSi4x4cV +z7Sgim4vtN+TGNnNtJwMj0hnW+KMlleTYFJiegQ8OXok41K70gkBqlnrf9Q5fZrqInBdTZrFirQo +PDfFVFMZdZ0yTM2vosr+f2ozKZxXU/sCRMKmOHHyCoQE4L5PoQhAXySs2fK95Lwdt6okBK4+OfzS +fJWNxjkbGkjIhPCs7LDGYUOhBk4iI0yze1v2W5BL2ZRGBGuqIyweJMr7IgFREbw2GMCFc9My69rH +ZY+nt3BK0vt6Kv1dUdo0N61MBd1YVPx3L2vfqhpGdBs0V+AwU/G4gpHitebnhWQUeUKqoE3K62iJ +DzNQ3+rOEBab5Iffs5A1CpvNwEUSOLM7Ow5U4G7B/m/AaaLifZwZVvYGFwRsQ/stTKzjEYFPxXLq +dEfH8YL66UxOeDXYoqV+Fayw+x2UcfFQFyuCmfv5w485KqLNXGGnKX8jGG92JrcxRYJFTJJrrd7R +aThtkAOs4NVCnuqPaPrqF0RBEkRdLMdWstLrNG6NWSBNFGOUNU3KSMWvMFFyeMaYa77iQBxg4CbY +nG/S5A15LguGypRFLpQ87X54wAWLnBIAmDO1kmUhwxPEC5o0mcByVK8ds7AwCR71tLqtguTy5TNP +nH/zg8N9pDfHfNoh643sX1gUt8/dUYoyxIVF7gq5vqdfnqgVy1I6+Gt518Qw4S0sNh1syZVU5fXQ +AsXPtcHTtGWGVXKod5fJP8YcAt44gltzKWUMl1azzLzBhy2YqsEELFJbIPoosWEIIKPa0KpIBNyg +0U7qZYVNgPBMERdm+bas+Ffe5yrG8bVxa5CRXENu4wJpalypMcBS40vg6gXBkSZg+wytODantA15 +1aJqIRIDItxDV26110oA3JobPWTbUYLYZJQS9RE9ROxEzSWO5UO0kkqfrMwZuKzaaYFcspkmEkhK +uEwj6cdcDu67vR5GQTpHJBc/Ql67pfby9rsai8vMvNZth3NrEnaoisg8HFRV8a6aUEVOQqGyCf1A +ZR0DYT4w8sp4Na4eLkJxmTIGXPiWuUkBhpMO5Jcd5eZZx8cXG/nbcqcxwnkEgELzj/2ZOjK94NUM +vYPSGlrnfnYsOYnEx2tonYM1P6Bm8xpZXzWqc/RYVI/Az5UgQKqOf/ZI6b3SAjTHEziJEecauhCd +wlvfJK/Y8XDMH5D9sgCNehDLPMRCWlDqRXtov68Xi/SOSrWtEW8v7f1BOXnRKtfe/Tio4h675nGm +bxHJP7ClTm11ipb5rIZ9ORB/n4sPOYG6XtY6XwYvq/g5rDuz8GXcqTsu3W+lCi1Ape6sOGEH9Q8j +MGPezRjBsVj3WLDkh8KaIOIjOeVor8KwkWQA3FRlnn7DU7PHqWFoTe5SCMAxvIOwoh/b6AiT7f9M +YFQBoT6gdjmtq6/zXlhrTyK6S9n7sN0ri68sw4sIYgeUJ0lY/0yGUzCYsLwU18ULLG+MG3YUosZT +Lq5rvuJ+Yr3C4TP6psZpBWW8TASNFBIes2dnm0p4VSzud+x9yAB5pii6iZaOhnHOoGd7GnD6+7WZ +UodZCQpjDqakgXGG9KulUElONWncADU6uG0E6vGXxLkZMuaDhIflxjsJxx0OrIiKkQBze7/CocLL +rUS1388oYA4Onn/2rcKqmbhBP1ow8f7dF9Itlu8TB37KgHT2lQRteAoQoyKuqiAYfd9qF3nqkVW+ +++WzxU4D/wP17Oqw3lmHQHyojs3vp45VGv+XjeFmJhM2lYs6Psxfwm3yMhze1+Z+KQguopWCd9Rx +T4dUTdycxf73s5QcQFq/MDUHQvVvcqHuVWmCJqbzSWyo3NgH52fhVJXVyjYAWX3htdLjWDpNcpA/ +rtvyMC+fZ5HPstDBTGMwrDGTi9XMyFyZ4v7UmXavZhh8BLGt6ZjuJXsI3E3q0JkazOWi2XgBCD8S +qwm4i1vo99CxUlNqdxuWEHDN2dCJzDZIOjc0HWw+YoKEpdTrjhjSHTcvFgZmA2a01BgmJU0EHj/f +PYbKd6zbY7/1cIDIV0XgxOnJnTpOy+nJfNdqgF3cJUJamxPssd8xPFeqoISWzfZugmCcxYMhwvh1 +Co7nDmC26exS/ed4V28/Yb1/S2bHUh/xcMZi76usN9VxcPFt8UzkfDoV1go+8jlBgm8oMzZt0CR7 +b9/7xeFLcKL0OoWZOAxft68w30IdvpbeuUtdw35iNuV+kYd2+kAYx0p9YakTFZegZLxuWGjvpYtd +k91OtsjImsWrO4ctdHMnguKVbd6BpyrwUCC8UKepSbEVJllXWEE8kz9+u/8zgc6Vj5iA6n+KEnrd +yq3Q5aWqG4TRfnKsPZNGYYeQw+xOsaWuIOhqDDLwR4UGsbSw76kNttQHu0FuFCEbv2JSwG91VeFn +tosux/ZRLF6VVgbYu8rL9sHhLjAWrTZyiuJ19DVQYr53tVNGSDAvch1mIuNYnxB5o3jvjng1Uz0l +1a4R7BhxFnpq6w2Pl4LBPg8jm78UaMSFy83EIar9e2wdqrPRDyz6hQpqkDt0gk0WEnzgZJ4siFcc +YhpPnDfBoEbH0duKOwDsGvnS2ODbAQYAFAS+ORlnEsY+C9goLwlAkh8sA0MVWtlXpRL6arHv5/Z6 +aFXqr8cyAvtOHNsCvddJXOOcsErjXJumju08Tr07rMij+bSEHdpIJDvFBKVEsVzUk+wIEzwZ4+Qh +S7hpYkBgYXp6OV13RgYY8s8ZKSFbKFjV7MtB7zboNdWkAMqteoe3kuQ7zbYn4yZ+nncN23QVrpgI +yd+tIQBxypP2npHU4RJlNaZ7Kn4IfHs3eI5jdYEH3heyDPUNtYVWcvonxvEieWc1BvEYaYYtIThu +0yce7hOsWTxWWfPuyZLgTv/t3I2Y7EDnZdSJwYouuv/YOlLZaUkwZcKP3ZQpZNm0wY1fzSMr6eO7 +/0uSAVSrhxEhSZhdxQArt3BS7Rn35VbpFviBNszb0UoUVN1F2qlHIDUd1Si+h+1FIKXtseFoPeoP +u7M7q+jLEa709CEYACqpQOt6TQ0egRy8ENzOBOfJ+LeZHIIB0RodCdX0jOGQ9X5qg99sBUioQfa8 +IMtdy+5D2KADeqgJ81zou+O6GQWuQMUihRv1+UnX3LnY5iyE3L/dsnx5mqOFCRWvR1C2vJbNBjYu +G/QixqzRF5p8CMYWiHVpcmXE9gZsNgA/8MlynptAUHlk4w2z2UcQoeW64IfDctoRW0FIM+ZJQh0f +WgOsDw9JQ6gHRZoJ+hFEid0pDmd78noh2n8mqZZ4mRNaC+cJu0xSBPVzELoA1vNzLAJiAQyHyXl5 ++SunqeE/5JHnYWW9AV5jJWsXl4OvVjcjlmZ21B8aWaFMCBsdlvrbLV13GtYYHiduT6mGtv7uUqTo +v5FFAwq3UtTXOHP+hw8LI+XtEC4F+aj9t6WO4izwldJ5DkFNhl1OKqcbQsmAQqi0Lh9IvCv938ua +6CY8cFAwEQUafmtgepadAMIBspc2fKwf5nPo4OnZC0Vi+uTyOTwD+Uj61GSabkiuqWPlKFA4qzlS +cchov9LZHc+ZpGxoZDUaSaFuoNh4qK1q6i9vqfn0aZjxErVMwo/r6l+SLgEvFimFrd4R3xM6G3sD +2CvoaIOHpIattsmtrAE9aM+ZDoZoO6WBxEVLgTb4mFdB9rHkm1ZAEONWHjaCrRNAhkQF/77gEeTJ +dzKOBNW9mFvtAgwgAoSMGhhttGELDw4zidS3tJuRdGJzuhZ4g7p3/ENb3aUZHLQrrUplAgFd755k +4ceCvowW/xiVIABKbz9LnZLUgRpwlxreuRc1KkbcT3xifYR2N52LXGti4DNHfNl0IFsJQKWXB0w9 +86ViqiQASFs1XklgFG3wPAyO7ZQK3FcNrCBpe5IBbWsgorsSqVcMHoFSIufa1rIkuQNNOFvIAA1H +d2Az49zbhVpd1NWPisHHEIW8FI9XCLwvSwt0fiCjcD2tnT+dyipgCXKgnYwRzrnQ7FMQ4AzO950M +PnocmJ/BgjMvlMQcctCXoI46tok8JEAHfRfanwySMJETieS6kJCq5ZlKeT57rDyCRZT0N0ufZMeU +8Tetf/ktyqqduIAPorgZ9k0dQwMboumu6F58+lQRyVLb7g3JebhE3NQMZq0RF984//ZipT0VYy8y +YZl2lrSGVSWX8xEvyo0wMoxGT5lNKq2DcLFuUt8YlZuYPNY63ZaAGiV6mNjpKtpSzifxPGLggBiy +nLqd1giD/j3KhSQKmgPwUJtbxkjc1UXLTyUwC3Bh5OD4OcQAMtOkBC4QK6euJBfatVwDf+C7Q5gC +3dBp2C4hWkr1kueDJne+EpCGfTsNuQQ4ljRxXubjK4LjnO6AECqsNQ8Y8cPwYS0IfFtJqhdEGtuF +oVNXr1/j0x6x05yj5ZzgIapuIO07thnVMfKtm1Cye2s8Rt+kgXBnnh6A4K4azLn9hA== + + + fLnM/Tw1ZG7QhGBNgXCFEPYHa1APw0ij/atBVhP8LY+XlDukHmZ28l4uggHT5eTCPbrc+MIsSw6C +5Oo8YMuQJvHyKpdRqQJDjJ4YVMIjympYkFEcwhzv4sUnYtL2V0F23sdhb05lU/8apQKolS4xt38M +SN5MQA7MKYooUSv1auSYjpf6TdrBkkgXUzHfXQmnb79q0Bw0Wx0HwiKZGrxT6EtkVie5ev3msyL0 +EmtxRBnBGPLcjXREon1nCopDMctPaC0yMap4cBIrUnFvqdrCzT9S/X4tpG2ikjypj/8mHMnRBIoM +ji3Ogn9twohhRK1TdXtq/I5EhIFLlfBAr6bI031acy2SWlfLUp5WrJBayfIl7FszpBB3N+aKCIx+ +GPJ62UMBuZ+MW3piNFiopVvvVbl0884ONnvoZDs5sd73s9e9vVut04w6ZSrahFsp7BU7vOtgYWb1 +6H6zRw+t6oalByVfF3X0pJIa3ITKVwufcR70W1hISiZT4yyKWI1s1D+v9TnEsptLLowe1O+gAV1R +5nfGM8efq1n04FsAgH3LgnzA02OflmZV0RDi2kgpcgWS5NhUbCiW/BG2luLLWWVlEl3G7yCda4+m +foS1Sg+C0TSPNPlMPcSmrHSEIhp6AQQv8r3TOKFBYvJ+B6RJuvhE2a9fgyAd/GPqafLc1j3AOHr6 +6bx20qdCPkLawfxFiPJDRIUg8DQuQbwmT7NiejoWOfzCJvmYQs+ddM63hvfiZ948jsw49Vw9uVq6 +BOBqhzXQFvlDmkrllAlrBu0LMlK7gQJfeJjWxMuY5biiOKMU321FUfItyJ8Xo/Mznpne11AyNCH9 +Mqq/VxBjrJB9Lb7heEyFUBPACw8L7ojkPrf0zJKMITzqaydYB6taxF2GPHpXgIE2eWLs1uNW7K8D +suSqh2QQxzzTcoGWq3lH9dAbZ+vs6kYo1hWiErij8ErRyJQPn7Qo4YC6plHd4s1l8xvxJOSTnpSg +7LnoNbswZVk0LX5keZKsVwnsWtKk5NhpLDi5WIF5LBySxNA6ioklZbQslOYxqcIhoNy42wJm+dEl +WKYAQiAHaLgpBIbw2pYHc4E1uM0DwKkCenUVgECM5M0iO/5KNIdUelaxVUo3TZbgPNvh55ll9ifs +NaOw7MhVzTCB23ZWnVWOz/pZQz1xdmp6AfjiaWanmPHsHE/NEHaSvB7jylPz9C9XrbJbRSyLkrag +dYHnPxpWNk8fzJHOJ0qBJJ8dZ12Nm/AcCw2ymsf2aIt1SDrVjtCsOe3j8UxsWuMUZmnBJM5/mlBp +LvHWN1KcdSI1NJ+wzqED7qYkNjiT/jGEXQg0hRHdLYdTGQsQR0L6yDQ6aouzFGhnYHM1EbnE9lE9 +DT0S25zSywVL2zjNssxLCROH9sxRAGYDZs+ugS+ADOGECwEJUl5ciQsQ7ktf2IhUrFmpvDnXGB0M +ZPxV6dj1eQsfOWhHfwts35q2Rta6TDtliZ7BYjLtu0S+xFVsV5Km6HSAv0tM1F2O4ccbZJgXAw1T +c2P4ulWplEGxQAywPtRCPIm4dMrDUyVp5so1TK50u1QwauMdH6ZNlGQpydxPvsM3doc+YWejsIHL +zkivFOKkFsUBdgF4I4xuiofjB5jH3X0IH/lv312w3IAz7dn0gFfYmx6vjqzbDC/K4I0aCR/EW97I +AfeeFS24m1fsKiDN0KRSyUDKGDLgSTxLN6HMhFwYtQcgaApVrhuUgtxTG43ekZZeF9/qC4aWvFox +VySJL8Gro/MYhLQ4icvTco/OiI9n8UJAa3OepWBBU1JkW+AP/4lBegAfo2oFxRnjK5qOEaKWdgsv +7bhNG15yXTVtI24y4WxTIxOgFOhIRf0nwEdF7Cz/bx4ghtgfJgAeqHABGqC8OQNT9PIA1TUBf/Sd +4MbDX+OmDhG4SvQHYpwDJzG/qxAaSe4JL7grSGOOF7E28LWW4NXIxBZyKrVM2d4atAJmiE2iUZCp +YQrWRzyw/lzFX1jLuInlDljePg0fYvU1smYo6y19Pqm3voxm3LLaxlRZl+B72Nhh/hDwqvbwdErQ +ij+oWxlALNaN2DlBJgUJtLh+UuCgnAF4np6GTjdJz8ozQpZDMP9gX0oBlPjzdIeT8IT8HOIGv9VQ +3l83iQmE1DaTt/E532udopgcNLS3PqR9rGSvcqqx9XHsIPJjOLWnfwzp5eqaZ14/dptf4x4ev9eZ +Xax+nBi8trj3HehC3I8VPvYZZLMoIHH3XUA0P4YzSRM6XemGh+wfidd5WkgE5nPu/T7T2gqAd3hz +wmUM8wjIiSeZ4ZuNFjHP/UcW+vniaVjQzDxrVg/0QUq09O3x9GUOKGIh7c71Bx/CxhOWlgOJCxQY +JhbWa/cFYEhSoYnLJC/lCPFkEpGH2TXWm4wI5UH3yg0qvg00xvQfayOmA1J/k+TTSfWG/PntwCrq +cA5LXPQzy3LddAwDC3ybeGamg2O4UArxs+srpzjWuhlpW0RqceZQ8nxK2fnwOVHLVIA3KmBIm+nL +zBelCHVA3eRf7DWnxJ2gGTeatLRksrikyqe+6K+Hwe1kWM/VoWv9Y6w5FL/fEblPp9sajqSgC8Nd +SYbtWjdNxZDMtFQHi3a4IK7qQ+Jg58SzUXK6TDwQMvTj5ymxtrsc607QMHskjCgIYNPDEdNzl/vk +YdQLTblMWfBD1PSYWXGs8DhHXFEdT6ikQ8NVu/AgbjEkTZerrwBOjn1IpQJejdK7iP6TGqbDdAG0 +iw58EnP64wRHmSDgDcYAbkESfEh7futj2IrW+vAhQglb5hpvyDPapF6COeVUUlRzG4A2fw+C1+GA ++DvvFm86WKLnPo7Ar7aIaoTz6c+JJ76odxXzYF7Vf4m+ZjoiSaTvbyrp374xxeH+HTeIHuvFroKS +LguYmFfs38IWdDQ2KBQ1ygla4//gzD0V6JZPsIUxkL8STEcpCIFkLQaVBxbSKVv7XzrqHotIJ9r/ +AUszOqXnrfY1+tNmRnAgwOqBvauSl2ySVIAMcUTfhpOlebrR4Qb4bR1aLcXKCOZX3AQxD/AtZ+vo +WJsYHFX32K1d+VvSSGP05iXKKytnGLPkxbPaaeDVO7wp1UKYw7NJHRLdARhf/NBEpiLiG9Jl+3jb +rqVFyn2FpuqRbrrwip6UczF7Isq4nfPo0mJjBD3hzOCCmymov1bI8ZU2bCQOC7raCxEXnBpBl/Hl ++TDmkJRnTq8a95AVc5ym60RIuURW0Tk3I7Hm/f9A+8ZAH3ZV4ucPg8joIuIJ3J4YRP2T83pOOKZu +vQxncHXDdf7LjjSP1t6+C8IsDpcdp8rwKUmRogDkuBfeGjgr1EEtalF1Ah1JkbQ20KO2t1XUTzL6 +lMqtRRQtTGiEZ3XCcrt4o8ktJyOQf4c1ZEvqCoAOxZNQGqLlu3kwRlPVW4/ELpBMRjRbcceIgYUG +3Z2S03tRxkek7w6r8Iemog/6npGv3HWq0TOQjd6lBOhyRgcCfDk/Af7nKPYhYOGl1xJ0nz61tTEv +yJgcV/ZwFrx2IL37fZEFBW7Hgu6RbGX4eAVE8EUO0zmdu86Ps0KbZnM3yni42qNTt7XqbdCOFPVc +PtF5I28CIupcmmBZoz1k1h6Q6YlkFOFupAIo1Lr5Zhm3EHVpIbmyECY2a7k4CODDDLja0HPRB6E1 +0OT8gZ8CQKD/QnMvcnHcgeBI0uMZ0X+mYCzfumSvKiykLJbgAoJSBjCKKOKHZlxt78+pIcdsQ2Da +qr+fdequT4cQaOvQY5grDiuNr3LrYVipYb2y4I2RBz0aJBT+qG8CZ4b7vKfRbivRS8Xi18MiTvyT +UCa9s7zKDtfWzszAaa4Scgt7dK2Ca3t9E85LnwqN49PWk6Nv8a4LF4crwhpejwc8p7KCNdTNbUBb +buEaWbh3WGNHO6Jc0IO4iF/o9nZzWQoY2+W2Hguq1W8qWkHOP/yzx9lHhPwAFyiVzKNU/VnSIWTL +BjNAHIuFK+p0dUdMhYu41Zwl8pFjtxgsUbsjE4mb80ita391A9FADnHqbIyCbUk941kNKNbEyMM6 +AeswCmzU/cRK5P3Vlj78ilosSORL9Atn4AarwI41ISgfkTX9Nv7revRVrHBcJIQ/mCfR1lEBuYmD +N0QpXN11KtofeGMvXhzEP0JKQvBW8qb4IFlvFP2cW4uiIZVzoY2vCbzC70dybl2peYb7wUW8E4j8 +cg1ZiMhdmFPkPDOWpXP1t2Az9rHXeHSkM1bid1TXx883u1W7oRWQ9cfU23Do29EgP6M6ocVuCUWB +YHL7IZwzW2XFDeuXM9NJTn6NFh7Z6tThSNUutzES4+8+Hv4gGVrFZamagYJp6Nghvk1KkRtlPULw +7BsS4ECbXEsmWdU5FGvCdUnXA1RjH8znN7FwDUkrRI+bYA8xh5Cmv9l8yGOkvXaLmK6cHLtNWMzn +GSJExal1M9FnEI2iA/0JamkvRA6jKQXXRpRVCvKkK6570OAFj6cChXkog06EEUSQ/7jZA645GOs3 +NQnXbWHaHWYJlVf3end2I+5c4A99TZRXx3yYs8C+faBJSkVsmY2zGa5AdaCMhM2gzUTbTijYUaXa +9jxenYlWTV1oVQkPgzdUsaH/JQibuXBAUqCwobhdOw6BULPj8q3iJNNAc850tcOUsWLEx5qB/yJj +lT27ItzG2wYw2iKK1XY4qeYMjSVmYCk0avsaGdLz3+mfEbc2DuDHtNcsJCyByh17yJtqjcpyo0/r +GoluCwzzA/2w1c5FIFTXLSuK2F7lFemxjEn5NhmAhuhUvVLqpuqC6VgPVw2r4a9cnUlGHo9o6Yr8 +pAINfcmUcMGmyrhkuJVo2jIh/WhtvJ8GJ8R+D0aNFKAHVzFf5wZ4SxlRi842BI41kgghl4q1CEdG +GCqwmPlLbzN6wm7PYGH8S2ECwVMcAiOg+0JoH5IniDoZm7bohA+pcsGRIKCrRuwqeZEYuhojDowN +nVktg+rQ0VpsXebvDM/sVhjW00jZGGJvcAkmBLKMCSpVGBuWO2tYittKO0mvis19UhqUkUHOKaAN +SDTSB51eEsQnBMUlyyBFKiZqwIXgZY3n63MLdE0Ksk5LxPosoJISJVzzrT+pqFLQuXTsf0vxCgnP +txiGYvoHeC3II0qhNzCAsCSuR8h+mvTr0rWMQNBDuSVcKR372IkSFMGrBoN9UU6OddnhieyrimLr +0QUVxV0YcHd6KbPoD1tJFD1QI1W4fDLTbaRob1Si8LlD75YYFLJbJQ7r+7jkoEwlGhugh+pK2mYh +4rnalus4BsOBV2jP6jaIMCpjbOp+e3Bu/plCVeojrjDyWkeY1bKhzc1I7rmhvrwC1pHKD/3YtaGy +cbqAfvLqvKVl7+Al0NIlLXMOYIv5FJH70JxRd+6gdrDGFYqMIDWMBXx0N6PQ7/mxECz4Olq5cfia +SyCbKNvzlzEvjEielBQ4Hbj9/7Q3FQDHoNXv6FNJStIoB3pf5TqoMI/EXg9hciEYLg== + + + t0QofqiKnFk9IZ8/WUYBNcdAVqoFdZbnOM6rOd6lfmxJ2Vxc1u23jzO0tvEk883pw19U8tRejGyS +atZLzqvnf24tXePpaJUc2CxuHKbSctIAIkTOmc4wdQLxY9n7ZFHIIeooNa0UcCaMYlCZNpvhxL/V +Ch3WJPTmEAlMX2/mKQ0vvV6HRG2xxY9kM4gCwzEoXNkWvwq9sKOIOPcrWn8vu2KlJhhLRB0MDz7l +Eo7Kq6h2MahQSylaF6wO5bVI+w37WIEqyfaiCTpuGYTO8XmamMik0eJyebfwJcbhbd+GVIiGXos4 +5ii78+xkMxyJvtchuMXCo20szzbEGZv3WYIH4bQMeN2U86aiHDv7UVLqYyiTQZR9BLuKow7Kqbgr +44XwTI9CkiAo+ZTlqCzevyR2Iok3BVGdxJeb9cRCHKPCEjpjDGw9jpsxyAJRIs7v1+IE18ljonuJ +Ebam4yoXMjUS/cpFy/kbDpdi+uEV2vUboGB3KH37oSCw+MllmOhxYBGdUpPGrZhMOKvtZauYdmMd +DrA3ipMas3Bvi1NqQsLKxDQKvns56P5Y2y1IMjBVcnXyvRHrxm+lBZ7S1RO62dgMlN7CcH+GKUg/ +TEFvuCsmfo2vsGG67Oz57kxP8i0sxAJ6IS+MsGzt4URMWeDJ5HGtPMAlqiQVN0W8MTfkmVl+T7zi +xvT0eOEG+Qe6Q1ZssYX/XxWPN/6Stz+VQTq5SvCQHGO3sVmNN94JaNZySnSixkB8XFRjIQN7j+li +FcCU/AuzUtH7P8vM23SqX5XE0rripksxNikdq7IVsUyZ0hDg5le3s5jvKi7qCsd+1GnJhFt8I6Wz +CXSev3MZRM6EQ7xfEcp53EIveia49m0Fo9hTcEhPUEx9kMfVahbbiSPNW/G58JBC3sTxtFWZFj5Z +u9yNSNWf9O35azxsZh4z1D44eDEwaTV+XlCiaPV5Kz7HdFC4spnvJNwmiZWc1BAsVX8R1VUWJWlo +y0BMfnScXA3G+f/ZxwENHlsLVnFxpjLSuF59JDbovGEVHwwODMH0ZB5LLXRA3TOdhLXgRLXs/kF7 +SWPr2KuVQnSMeg8cBijTUZGkgld5pN1YEC4ELhj4FsaHIttVRYIFlJVXtBKmEQ4G6Bx1RdL2uArh +GcnJS4oE5lIctEmwAmRahVgmMUK5jzA7DZfawxhlFr1deUHSS2r5tBfKEaNQqmxh86phmLvUtOAa +bXbr3kILqD9TMQIQM3/w8pCS1rcq0VEAGem9/IT/BadH5ooCf8/fGvL2jLu1vIAy/wcJfNIg+Zn8 +KA7PpD5J8NZzHxHyssPnTB3MnrsO8cjnQL1cne4p6n/BfoEjCSRXlTpCtu6VMVc0I1+bUCv+ZlzD +5DSsEgX4JvUdnYG9qdRtwqpQIfAxTAWwDGaWtjJnxv1hykgdJNIuNx/47FTV3ZmqTAZTdfdj/e0K +JWq1IyNisqGYmg8Sn6wjyJKetyfFhXfAENEtJomke6UBPWpuzxoXqExDAhcDtcXbG1jXYiS9eYb5 +CZCvGHuC5cC6JCAlEwH1r/X22sWnyEZf4C75GCX4GprF00l8TJVfBbjT5GUCcPGOG7s0Ywjj7XxU +bQ8dgd2kdBXpHhAZeaDylljmZK8BONH6Dqq2IMO1xovL4sivnNKWgBwcV5QgBjveoCuR6BH43NEt +dGc6IjmUrcsZWrO4FhGDsRvJgRWzs3FGXbGluT03MjAJkGYGAnXgEcf6ZaZ20VD0abCIoAQbKPpE +jN4KgaFLMYZlkE+qYFtrB5vRQKowdIJxQzgxd9AkmQIlkU+GcSWQ1RybgwAy2f7D9Az5i5wAu4m6 +pHIr9MULNUOUxM2FX5+k4gkVqb+S3tSl3jMXe6r9u67u+XMtjYkDK4x4pHBOdBAjNOiYZVKSvzxI +Ogvaqhgm/7artOJOlk608eCWkT1NbFwnrZCFpmZvm4yFzF3fb8c8HoAKbGpzzRkkUGr6IZniYiGY +0beXfFsymZaT0O9Nq3A7oBl3iVfGg0ILRIA1Or+xzo4FHjBAzZ2pjyixBgDtwQ/mxlhb8A2yqwIG +bCoTomMlzXei+0bskm3U4K5CSotS/Nk5tygnjbWEZyWeStTQKzwI2OQfatmRaRZ24JVBpjE9U1Ha +bxONvFNnuVdg+O2Lkb9c8A5z17vUeq17jyCj0VZfgrZGmmYgmjiDtkKb10XU7dnzWlPJEtt9BQNu +8kS8EOdBT65D2i2FWRjm0nwuX/S6LGDaHj8eT0lRLHc/G1TAFhlnQfVJpxtmFto95/jzstqgWscc +gJyHwtuKBGMLv9brZpH2bl0oyIn2UwmhRw0CcPTQwWkS1cc/bVdFZYhHUZVocsQ717E3FvL6ZnkU +XXqnBnJM93nD8e5qNn4fMWCWRsi0WiXNnjtDUaKUm/xt39TxCXInuhtAaFmDewjBl7SlIu7raKiT +iYYifhx/0mtbIHCOVcWncXFWOflNOLKOVccw66aEbJIuelDOfisx4pkkBUoaJGNXt4lI8U6v3VC/ +acwPH9VLKaToRdgIoWbLgpdY2tm50q2thDVPH8E4+x1/zQDSbg5GkzkKDU6UndYnrplbY/fQooV+ +a49QS25zRLAQKHn0bC0mLL9FlXgGGSPG3EUUJfeWDImgG6yl3w8JuYAwpSnReXMybAZqFNrkSQYk +XKRVmYh1vwLtusebFJzsZ4fKv1+FVa36HYLGrFf94pb0tVALGXS88+GoDq10Mn0d0t6Q33CFK/Qz +qxNTiabWjiXPGjiLVLo0kOZKnsYk6y76eWOhpk0p29hy4RBUtf0UV8mCTc8XhWVJzkbllmH9NEf3 +rwi4qz9I8aZHskR6G0MQW+R2jwUV+A2OR0XrN5RN5fgE+kgf67ftwLwMfQCpZmzMLsW/eN7CNpvo +Q/c8ZYEBvwvV/kGWWETmogmNCUHUxRXKmIKbjrIs+lioE2/0OqClaIeZ4FQe2uMTxqrV/1dR3KAm +P1g4pDpC1Plkl7s7cdvWJkogE9pQL7UI5Vd1DdyGHFn6oYeli9oVJQkSSuxlrNvP6g69rgZjKJhD +nj/bsEf1h4DhqUN1D51nh+ZFixhW8UXxYsv4/w25c7XImb1d4dULc8ANQeMuIalWT6AxvvVKfaAP +dTQlXohWNDJNTHuLnggET2QMXOwevTRjYj25okc2z/cEy4od/xd7B8NoH7ZnvzbcfB3Xw8P+lqCy +fCJ6XDT54XNDD2JIgZuhZz6/bHBJg0LIpcu1XLXouXKGxNbppxDptS9Aaqyl5P9e58i5p4DbwKkG +RMzWBnwhwBYNb9aMwQZWMvej5diG3QlOXChor32CjnCRTPTX4g6UaQTLCs4OkSyQa3VaPhBgGjWX +MvHpAC/pW8JSaVYxZM2yFQOvh+GQfYlZqKvev0ZmaOgoJrgCFIg6SG9PTTfZkNpesrRDN6mGsfok +pcMuE2A+l2f8++XaRS8KDR6ODF820L/BTPFeHkBGAb4OxzQC1+aIlKO182CxSk/W8bFTN6uRa01H +ccBqn8zfau39p+aOI3Hqn6ncOAWCnJ3wYIQHAT/2iUekOU2glscBoS7QvV7Z2hQgbIcgUHoYAyZg +Jy2kXWXvDIgaiyrhIe5k7PHg7sI5JB8oFXlX1E8ZxmjK2f5semFzwLISFiRlbGkde7BRG6u/Nwmf +RNQJaQ7NOMbZEokg00jDIfaVu3Z0/9DSB0wzYhwsOq+azLJoT/JyUlRG+noND3Be/GGhg35/DvNO +DnubRwzxSBvuQLhw+J3nci87GwJBjvW+EVouN21zpK+7smCgCNwqM7bjGw7n2RLq/l6kJ9jBy8Mr +IxSvDhglGlKmux6VxbBuTP2Uw75GPEiGsZ4vII6OXR5UhLKQpqvThtdQLLVIDcGCm0bya/M4d97X +/SFT3SIad/bHKzxmHWhB+TmcM0fQGndyTDyaczods0/q34OGQkH5nEggNA7nuLvLDZh1ky+jEwF0 +d7ms1O4mJs3r+EuVLCU0aPg7IHlZu4ggn2A2+QEDZPyigIm26UiPOxVuq3MNRy2LoXRIlyI5OxZE +2F+Hi0Lh8GBJhpxN6tTWahVxifeG6OhMecR4yOCLFyyhZdBdsUgpQsN4UWj3rlzwTpyNd4HjgbgG +bDUMtO1acDVOXAfv1TN66TG/AJEBYAyNfmN68jbVNBgVCOPidpWMTPeUaRFv77k1F/BBye3zL69V +VznkZftWh4AfaOCj0EPFrNCS/8FZIrIFmytEAGKYosdCOFpDf7qMB05Xyy3yEOwSQ7+A3kC+4iED ++/mPgt9b0O8DRPDMXbBPI1EOnvMXu4V6LWpbvEckTMJoBQj8S2OOdZkOXWagB2xxqDd08yGslrQs +QEMT6OaHf6tCU/8SNvzsf1SkBY+WfScOKMYYwOiXr23nCwhJgkB6f1ePd+et0Q0mmVsTAKoduFBH +K2T5tYRTTmMA/4zTexu/cDq8A+rXfNP5JYCysJ4TToyMaMCbN3zrnbpeb0zdm0VG1X12l31HtZaM +3syrq5CsfscUNg+U0/12cgR2BWqI4r+tJOGbYRmdVxiuQ+wsLnVtQKeVf0XQ1UOvXZx6faP7s0P/ +RGtChzj3BDg5KrbojtMivtoQXqSF3JBdlIU9SDIW5bPUEgCntp7GPDrqlV4BjWHSlFQBMabAyg5n +kpDEonmADRRvMkdTrQAfu2fl2plWQR4nKEHqxYP7Hu+ByXtu/gQ6tJbccPCOKVpc40TjHIR6RHbQ +SGMYxR0KYc7Spkyz02lIYBGMCcd1WcbZ3uvRCPlOg0nKXEhpSbd4YWS8pHmyfOhgeqx2eP9PlFTD +oWYVFE38YIrKL30jxCv4gIrMyFaXiKUg6FcSgipgULAAWV6KuaNGP7+9TMgpedDLl4gJbkGx4aPP +eHidKsPuW37vZJHDNL/96DsKGZRPmGQXuQY5KC/yeiwfxEsFNb6dOqr0++GaUo3SjtZ86zo+UQwI +8tmJViog3gKa37w1v3gZ2BY+Uika2vLT+4Q67lt+zGFJSJ28IXluqKpGoWh26Al4kkpO3IIh3uLw +ThnuguKVBY42/A3QWhIv03LM5E4/ax63DSVcgMnKAnE5eGO7eXD/bhCfQhxykAZ6/gm6wqQapofl +nDi7ffwktrUQ3d9N0c/Y+YK76IghXM+F6H0hd5Er4TMy/HggXkUvQT6QWvw9JzcekNtsGCyRFwMt +m+zCQI2+2kySleLsxnnz0lxZxHB5kHa3Q7cLRg7WwVNIRwP6v38EHiCGW6m9tXTuBvJA552/y/Dd +ohFsI9tNkOIBRJT+MkC2UcO3ZIBYsh4iHG+X1Q8R1XjTeyntePzbv/+0IFaDLyIY3fSqUOBjaZw4 +nVGts3Mg4lYEN2ne8NQUSsPvRVPL0LgJfK6RaE1Qp/Z/E2JcU595qFPTJ+r27ZBAJVPrqyilXcN3 +RJy6+EBd6zu0nDef9Dr+DGVa47ibe9QABJe98kcadzm9oZVyBFoUCBAUkDtvoWsYog== + + + VI4T9Y92gPxDpb+X3bdwPozgMt5F/NqTwBCDQoUZn2/wtTxVWSs3c03uh33i6BruM7TP33/hbzqH +KuqE97C8ECb9d3XLHaET/K6PGfVTOBJNUxKyXi1I+G4d/92TvWlzFbNfL/fJKxfokKkbs1tSXKTP +RH0B8bj1qMWc0cjX9Ar+Qvz8HX3Q3fdr40z5y1xjmMwCbCrxD7vBsAdpsIcae06xttFmBLNnAhZM +427fNinUzeMmjJsO787EpTp1p/D3ZbMZ1uvnxb4CR5p3iTiySBybqGGVmoI+am0kZbWSvKglcTDt +sjnaSUaClcCqgDM6hPVOjcO1mVc5wnhj50x6jhEKSteJYBEKu79Cl54kynBkfxrMKUfLpEAaVa1H +jL+A46ssNce6Lfhh/Srb7287n9duPwv2PlVjMyCwWgqvlPrplVcLimN2MbUhlWWGqm4DP1nCPyOI +Y+j08+F0LxOmFdrZYPS+tPvtXIBC0IJ2fpccoekuVVss/ugLgzA7L6O2xSEiTFqEhVXpqNC+iKao +s7RenUBCCAeiwVjcuZXdNa8qn/lL03eB8P6izChWRqYtqkqIRX8kKBw2HKEhfj2EM9JgDICfaj2w +CoNlr5ENJyxiANtbrKNkbQ8loax8sh1wJse9HGrLrUQ4pRCmxI4IFXonMFCxThB9QuT4IhDChwjE +YDiLd8OkyvCYP17euFuzo5i5Q+SZW4QdzZcevmKfBgr0doXNcocAmiEDMyDOsRbNAKmYBHYk1eBc +Lf50E3T1HH7oHGT4GciPAueJZLowNQ4XqwvVKZVeTNBaSIQDaKRVM8Vtc9rmiyi6FwTBK5F6xSZd +cbSGDBlHJPXDLpBcQ/UFHC4V+kZgIByXA+kHIMB4XP9wrJwrcXwnhItFj8CSpuPk5Uw1WLNnW6aV +xoeOKc/mNMK0b2S25D9YXG33N/e4n5iRH2Vu75cLhzzdpq4Uc0uQ1vjXH2Vsq8keJS2CkeraC9hW +AUa4/Afhvj0S5JY1GiwJeWEmI9sCaV8RgBskZVhoMjG4bPFuSrhlQ3PvkN/BDwzoUC60ZPnuCuXP +2YMJTZVLj9AMJA9BD5qTpEG43iowkrvajGRsuYJ6di/nYGCQwJVJK6boVDKD5/rQ7RMX0IyKna+D +PAsIHO21+Pok9PY/t6Tr/hmXINWT2H5A9bfqMm9X4nuCiS9YTlqXG5Ukp0OWhBOf6UlZFsPnj5rg +QFrRzU8l6/t6f695Z2EvNxqu8EAlnCKRxZSXOtKvoa+cx2X081NPjjg57yGzqKFkKevUD9GiVBzx +mVUJ69JinwEsbtCkSBF4ZnGFcbeV9ygEPHuqrJJb0lbZNAP0Ikt0ZoSI/OXwfOWTfUQufBUty8xZ +Ir9EoWuAiug1iaeQ1+PzrrpL7FpbRkU2qvPTTFwEffntagNbvLZJm35F5v1/ecS77HLTwmKceLkp +DYnbTY1nPOg2Dmc/p+N+9ZX4xgCxB0cXIOYkiIn208hGO0rMZk+cUfuyOG4j58h/YC8f9mI8coR/ +DaPgcm/QTYSasLWsSubEpM7mHPw5x9IDUgwSWBpv3gCtVMK1pJOTtUu4i5sAdT5pQiVRuSCpkmbv +fQbDONEk6N4l/aGuyVa1o4s1xqHMEERG/M0+zboTJtCKZYAXnLk4iTPnnm9TN/sNPTxu7cSoq85K +jGec/nri82BEYDevdC/iRrCsfFqr+gYeJN9ESd/DHrirPfAPpZ1m1uQRSP52krsN2eb/ER9rW5BP +yOGez1oBtpI8x3rqY/7DK0P+Fc5LuU/SNUXNiMZGq39mggP6rTkCJaGaBRongBAvMJCGb08rNECQ +QgtJD0eQz08uxW1Y0NGqFSRUs9YFzZ+XzSCdj3zjdJUGaQ43WnHghsaigsywnehrWnoKIF4arpTs +KPYH3Nsm1gDrGqEvvY7OByd8RxBHcCfPbuZq/EjkYEKmG75gYygwxzcqmDjMmvNOqhzgNOTIxx/L +78jZpHzJymapwcHavkCStKWTO5ZfnNJ3HpMK/GYQp0Kqo1g7YWz/J733a7wwrXG1mQ87L2tl/JK7 +1qclJrX4XQRz3tx/OYEnxqeQrK4ZmwoGVD5PjLoHiTaaApv2HZEZ4JxKj2asSz0w/1afy5NKzAwV +sVaiUk9RVHJOaUaj062WhpcB+wZzFFDXeWx2q52sbihXrfeXuIEEH1VBlDwXrr78DHLHw5uidj0l +MtWq4+yXlImENXpTndSGRx4+4ZpKJ+sjWFdOzTFkJLaD53tTsKWY21WSq/aYJLrdEZZx5TJLDKGv +/YxGnIMGyei/wZVacqMXiEDTkQKl03JQI5h4FdVMtKBWl1OP7MkilVo7qchUDdbxN6FFwT6/MIou ++LQ3ZO9IKYVUmvzH7SQ7ogG5OFmL3lWBOlNvt5tc1NIcMDNCSwxo/MPlhtoUZ1h/G1C3qwC+CFZF +50tOpOGL4GCLrNJUjw1Hi1xyVaz3Gf+7ZN6LLIfcZ5ahxLr/RbVMdL8XCS8dg/0VDqKvb1+HlF/h +2uwNWr2F32ADwF8eyqCrEVQUn7PR+QljpOqvmE2axhQfu7kU/jd+zOlLBf99vRgmBJoeZRdeogvJ +gS46WHlUHy4t8+Amx9M+wkLwUtSfXhgOC8OxKrZZ+tP5O2SoJNhGG9nIa3lELPgjXnZDSiidIBdL +yTnIg1cmCOvWRx9PgfRFQb55BMrGVtBZU3b56BzziT6XeNQVUTo6Nxw1JU4et7KyEVfcC5xxJYKE +EXDw63G5qN+U4jWEYWS32ML5zF7IvwRW6OkskguEROgtbqUnRR/UGUQ3BJ4FB53t8paix4r5gftT +pIFm/BOwLu1YOyQOrFka1peKS1PbZ0+EWTgpuMMEBWUJSOWJyH9t2nnGsDJOSA3VFFUqZUHVrGwT +WKmQNG0dEP+uK+V7ulIEo4srliu19WcdmgEXcCB7pOzPwPpl+3SMVkirePqtCqD1m1fWCJ+SEOtS +SWiDlITjOYrFIbEa/IB3SdhHEQkm9FpkUq1OZaMzNpPQLmQSDioxCb0GB1GkJqY2wgOhovAraAJq +IzJLDPO33+2C9t9LC/h3WHuTS4rc+pZNTICm90oJ6Q6mX21kXv3Wi9kEKx3bNxy8WIVK77pFXgEB +1KBVi4+chzsfdJWEnfuo/QX3yYBsFqnnd6fo03V/YM188m418b3cWKCFKvXz97FwitPFrAu5XX1p +lSiWl8bTL/WTtk1BAVXptW6+Qtf06LS7USFGjc/OtqX1D/InuONkc+RPS2TKGaXumOEmB8I+JefD +Y0IKtMooqrSpbeXtjqrriNVWEn06O+HMrhLLEEUlhRAhY3sfhV5pM5ymlOQTxLSBbHX+Y9es1hOR +zTcQUVX//ikK+3MEZhymO6UGGitZSOD1R8YryRnjQkH1nPY//vS6iXU8HXcCzJMuMm+ZwUCYqyrh +2Rorl5xJPJCIYPaXrLD2hefvvzUJ1QfGTFhKnGA/47+QYkeJBYQWKXqqdoX+bX5NCMreOWbNeV9a +mhRtjEiKQ+OuRQvfrAY6BNeZb3pZdVW1B7bOAzrG3Iq4rhbFUVM1dDuTZqiP+MAF/qxiR7z7Hq4h +iug389H3vsRP3QN0An9XIuPr1pfln29ZHIjouPwRiGThD18lPbsKTdBiYbDcMvxdsJ5qmSo/Pc/F +5ix1JNxyoIjfl6DgzYOidH74dWSpQMZZIbzvRDtZlPhx3fMK4PGyanyyLM7ITpo+wSjIA5dw6YIm +8Q/EMu6yAWqp1Ls1I9VgxcihBKxF4L/K6eNcUZoOOczOfoZfY4FCYvvd3BesHumpD0JIOBOfQUBB +JmfA5uGGo+25Y+XjcxIz/QBfR/D46nszSIWMGC8ymAuS750S24R4F3uyhMMl5m+KQ3D3pPfjHTEG +ukxoWEZOt89GRegL5V7U2yZupwgX3C7RjEBQzLdYoHhjKTr/TWPCh82QQ8NyXlvVoeOFIXI5sIEX +Xbg9fwD7EFSQVYC0/dm7y+tMHsCbGujqz5kh/icCS6vPVHHqL+taQgxF7P9Y2mFinEJh8gR2d2va +OBFrsDtdzkOTh9xdPP/bTLLTaf0EH2BUkhF2C/3zU77vYJhNKGC8Z08gyq+XkUKZOJl1Z9wtxJyW +IEXsoBZzcBcb/yABsgM6BI1LLlcIovTuNas3Vm9y8ozEhp+6NIbMq3VV4NHEU+2DOZQYE25pmG+q +dQrrlptLbs4XpIxPC4eOW/7C8ut6XvNb/t9bJO0qdV85zpLyH9XPxFRTRU5dzJCPmrYwXxNoZyGs +Yp/OJJXu2KrS9pfMR751y0KGd7d0bNWmXTV0ndYzeQHkzLzIMmLZefITVmsRdTbvEXgEEqwchPDM +tJ39+gc7+yl+3KEYs17mDVqZYEOA9movugj25VMNS8AamFM+0B1BXUalAWws2sz7poIpvnDHJQM6 +YvTYHJzsUA7HCjEmFprjsPBc180g8l6jC9yjj4qoSUOGkVfnmDBN70F1UCY3NFj6csfo4gaQE41g +3RfhM7mtoHKWj+9XGylGXx3zrtbmsQJcGmIfPkJWQaF18Ob6YIvEzPWvjGJ/UsWq3NwInuUjzivZ +GgmCOqwTAClb/setUlYASJ8cseFK+7KFIU4aGfsxZuXenh81ZGYwIlxrBlgjzSopZvuN2GcZXn/f +t/i3eKVyL6Nw/rR7dBOdo6LKp2Dm1m4JmWVOL3B2gYTHFzoR3dyCE0OalCC29iO7QzjoiLrIxJmW +j5TCD5NN1HQKIriJVrItkc7NEYIl8NQeYqHbsHFoX6ShKfqu2GmWu77Ou5Cu1YUcZGlwLs8Z9Y3a +jo2BKryQ11PWRgkhaHpWEFc9gNxeuKHdUP9IQqwQVHouXTkFFoo1nZOQIwchHNkeXfCok6bgl/Nk +Ghk532jakF/eXwQai0wZmCjSfd4GyqqBnXwsNCScQ+BWa3INnUAaCtUg4biTgLm6AqBHhoAoEH9t +RQ/D1wTroOyyPQOASA9VHZfwQNy+zcXTpv6qDg0n8LEBEJTMMQdVWOLZW1Km9taeRtDk26TZxTeL +/mhGI+zyiAFY3WdR2lP4TaO66s13cl9FyEKqgW5iZQvY+UmFOUp64fT9WP794TQO5x/3uo6deUno +fZ/FEzkVJvTQXtLnvoJmGGgpycwAdGcAaw8mCYpwfGg2OjctDgCDpV8GDmyzfB/QytSJTSXdv1Gi +Yhs7LRnCVdkBdhMY4970NMGDmkZdi8VnzjBWYRIvOAN+Y21mixPaNhXtBb0EeftmXWSkFvsBg7qL +gt/NvnMoOORqX15noM1oi2HBp3gyaliLTlZCaq7Bz+bT2tnpOQbqpEHrhRhUANnpokPX+QLLWFab +iSpwudEMt3LQAsQ9TcCXxF35ImV9nR/+xLJCTk5gMOKrgRFyCzzwCNpUJUz3S1ykeKbrkIAnbFEz +InqteTNCoPFSbbTx8ygrfqHwHXyxWl284OngB2zRFrB1mFYR+x6OavHXvl7NRQ4rJw== + + + jNFT+tDzmJiVTih04A77Ubeg5bQoywh3/w7kNe4s0ewUKXUe6aIjuJY5Qxg5BFvF+QPAES0uaZ03 +DQS5eWJIGzmMzfzh4lnDlxc1bZw0p4UmpDldZxzjKJ+ZaihlLhBCJoihMYMHMSyF+aqwqA8YIoov +9A1IjpcTWZJKHc5AyhaX1SRtBuXvL/4PhULsm6ElKOSNKeBVXkWfJULkApVCQFfxGbj9+yQOherM +p+kpEjxhgyF3Owl/OV3c2Fg2uf6p53c0VA51uNc4fJPcKFEMCZJucx9CAd7yfTrJVX8Qi8vUTXQ/ +TJGiSCGaWtqRbm6802AwzOlZ1GekyZ47/n/D3ech1hxAM2xfK1rRKHDYqlxJulfpxjTnqBYHZCug +kPYa/6Gv+CXUBsmVMURg43AgifszehvHuVuY4kPrdsrWchGHx+uzH+6FZ1OGBnnoOOJB1P8SzBv9 +2IbcXhEVdGu9QBqg7wSzgWT42m61Jm6kfvDt6MkIsgv/eH4DpI14sHM9OB0BjDioQ7KfHqLUoGDU +WaZFAat7aHsFbvirQmGCKArwlJd3sraizj6G2x9AfDwt1t4wC2nKl43K/MZYyMn4WTZmT1eMB2OW +J3iGCEKFG0CM039589Co6Zt8jvmpdrOjqvZcYFjng936Thif2Wfn/fGrTl5cJI7fjE18jE62Qjvv +gdOSPJSeFF9LoPXkFoctSoal691VTltHdbXqrKhpZ5FV3vBEqAKFWZZ0RXMkrgJAyV1A/rmV8xtG +Py0A6VP5jiEcrMwwzxKG5Mf2BkHodcsC6touhiugJJCk22DefCiturr//7uLu4vd6e6bSfm7e9NO +KZMkxLDAbHK8HB2F1zEOrAl9CVwHATFMgUbnYsvpQyDG4bRZQIHExrQWTitx2khHQERBCMRKjNFy +Gmz40mfqiHie08LnQbTAI0/qESqqI3HyWpTL9B6Valv4DjAw5akyvI+fNpD+OCeLaUUOKKHmtMvX +QXEZRUfIxlqc5r2FisNp3ZxWwRnLaZy2D5zGactpldmRYcjhNMppDh0rbysWm2bTyGSXrYThX7dx +/Ou2hVFrtq1w0GybFMFlIcCGZoPQldlOsJhmIwioYDTbJmpO406pzxc0Pja+WEZ3sJPJoeBBUBhc +TEqJPg/JjKA+C4d8fA8TJ06bbISKY4F5VGA2TqseJI5CQYdbAKaB2ThNY7ksWiJOuwiBfBMAo2SE +Eg4onEa5dDjtAqQgAySzUIAh1sbEgAfDcvXF4HTBGspp3engZLaFrsw2kQDSbRwPjstW0dFu03ww +l83juWi2hRVKs8k6V2bjNFMHJ7OdKl63LYgmuq0/mEtq1JrtA12ZzQNdma1GpC6bFMl0vLbhovEe +SgHB5wQIFZaesIWCB2rBLtjkIaO4ibQtfLIAsAvmtIbZQczhORkYpxGsQBl74bRukPlhQgIODZwS +pwVoyPhICPWsMmFoAqTS8QGBYAGS0zhtJfJaTksgcTIWTWiTfa7adGQyCFkpxBNbVRw8MsqIA8Rp +UDPQ4WAFnIRNx4N2IF1FpCcqQAwfKwTyzURMtPEICGwfrM5IdKHGxIUJEctAuA3P4j80ovCoED4g +IQERmedBULVGQgIVFx6PcEEhEw3AGDI8KQtZ+h42WiOhbQjRfAef6YRGqQTX51mY5ktBfB5EvfAD +Kj2IwpjnRBnYeLhvpL+RmqI4yiMA9cU8YChPwSOqNsDmqkW5omohMCwwDqfNRjivExMi/vhKEVZE +OM21FCROZmVQsoxGOE0oM3DqWewguELNzTQwnFbQqtCwRbadBjyuSYe3EAXeijCsGBx1CDwTy8jC +x2kHUsIgZAkwwPBBKFQcPBZeDMTTIbJoiTwiDB0fCPFMiDqCAE7GEmBRWo7CxWsNGOLTnNYxDzF8 +HQUkUmgiJGAa4AMKZ6CTYLF0fDheoo1H4bQJkJx2YY0q3odhgdBrw+MQhb0WB8hTMULRH8oIJzOp +J4epWXOEPuwRGs04PgxCn/fFPMyhKokUOg4GPEwhwho9EEAY6gdY6dKcJoN4jscaeQuiCOG2jQlG +hAhWWi3RSaEUmxvbyMLXIauvAdmDA8O3EcGREc0CLgEWpR2IDCiP0zgBBEocsCvTNzuFfHwyiOdk +QKqAiAKZLATCYazCLCEjJBBDDN+JQAPhCyhpWKMNBGkh2hhEWCNOMygwOXheDrNdKnDhYDRkLAdR +4G334eKchOlU2kEW4UfD0RgZKAUcUIAwFATqiPMBdbTQKYsPhRkyPJym8Po8iAw0r4DQJhRC2aQC +UhafD4EsfR4pS19FqSg2U6Mjk1E6Qip6QQ/yCVDeokNOFQqeKmLf08FIhJr0SVn0R6P0WokQhEWD +dKRCOk6TM8sOQMt+WDQvBG9Z00G0nJYAEWWyjTXyViJFCzKiGGcgs9WTw48UwuoSZTIRBcoakWW6 +lEx2qSCw2NjIOiynxU0CaU8cIaMNJZhGu+kCiPaz8RjIRIhPt50CbGi22WxigThYhmc1eBpYBCCf +yCyCc4FooeBhWgcbDLMISA+nnQI6CZ6GCwKQjy1OAfXkcCBkYibzAohEO6kMKomLn13IioCZwQOd +yTjNUi1kMgWKJO2BK2O0H9NntJ6KE2QcYhq9eSoycHNYYGjglDaviZAoEbAxcjEwkMjgJMniApVO +6mFLSRCPjItNVgzE0nmFrAg8Nh0mBYZJAE4Lxcv3IJDxsjjEPvVi2HiQqAWMTkOHwscikk6/yaAJ +rkYo6orwpwRER+wVYggoSmmAPuexGIkFOEZrYpOfkVjAl9Io7Sf2qVw+OgumIaFSeHBGBxsy57QI +k3B5G4hloQEHJSCQkshsBxszhgqHEz+ENho8FggHjg/WogsuaZBSHreRcLGn8/D5CENDwwoOroxf +MKaCDKdJixDVcy6o0YSIPxIrUuVw2oIqPbuQsUgdBZUGBWwUVPqioNKglYxFkjUUVBoEeqAIvOKE +ecIZG5sggSqaWCWDNKMQaWKVDE2skgGDcFg5rBwMJkTNaSEOIQ6clgFZIGFeAV77CvBayyvAaz9U +pA8VaWElUmBRWtDGorSgWLQoLWhhxTV03AQzcQ0d3xI2poSNm2CmhE1n4xo6LqLadA4+VgX8oAo4 +hTcCbmI/+JhsBLxFQpaOgUgoI0LRnBabUbSBQYCOtfq0lzRYq0+pxGm8UnF4W0dkhCMS44hwRF4k +kYjTRBWiBoSJeMpYTgtJDGQGPgxXVKoPwyMUFSck8UFRpT4OuA7WiGwrQJi8AhAwRlJ01nGDhicy +VoliMJpoNoIGGTCxBRxozGSbJbUuHLwOrkQx2tUYTWYQEBGGefBgNj7V4DGQUfAk0I2gRB1CRiL9 +RqoIkAjyM9quYjSZuMQOBYELy8bDQgQqs/VUdMZplo2gI6SAMztW3j7LpMJgaTb5MWA2hoUKB832 +oBDSbDxgwiS4OD43fR5IHCD7/kJiIR2eEQOFymMgqqg8BMyA8mSwCFYnBKg+71gjGARlLARlrENQ +xoIgVpy26h5iE7EJLTbxcDFpMWjCGfuwuljANjQhAoEqGTAIGAQJgsRx0MQqmFglYzvTMXt5Ax+G +YafBdMxeG+JAcgdSiAOncZz2oSJxPlQkDklk0uIaOm6CmbiGjrsJZtk0dLySsOmYYBnTijB0/ODj +IMaqwMgBH3wcWEx8QIEbAQETHxx8QJEXiZMxAJV6xhHoiDBoOBlmKGl0SQNDIpFIGhJGZpQhTVow +mAaCI6oQdaEJEcM0EBxRB+GiCg0EJ5MAooHgdEgoFAqhqLTTh2GKSgYKgSrfBmOxC3KvADMi6wR6 +1CASrYNJoUQjAhJIUoA0mXEaC8IilIpcgGyNJjOKS/SQ6FguG++c1q+6bAQa8MKgwmkNEQEkh40m +swkIiovCFOC0AMkbixHZ6hIhJEAbTokqdFIUVQmwKC3GaGKlImU6IZmxCClgWMh0QgsHr4DQw4H3 +AXFHiKGAVVAhE50+Ip5nwWEUEZoZEhmz9B4QsgteDXQSPJymMm2YFsmMoD6DyOIPRomhPEzFCzbq +YM4P4eJCfR5qRtEDMoMJEX8yHgRl7OwCghNZfRoE6lh9GgShmV3MKlaf7iBWn66spGUjY8lYMhZb +Nhnr3YQ5LTZB4mQoDg4rUCWjkhGrZCwMAgaaEGE4EyKu7MCHYU7zNKxCHBpWXjIYyqsMdBI8s0B1 +sCMqAtNCaESWzupbTUAPooFMJ+SoU8SAioAgeh6+43NOS2BIWXSKBVPwViMyiotMIop/FSDTyj46 +rK54OE7ssaxGGxcFp3Eaqh5024AHx2XzUGYlgc1GwwkZ9OMyAg/FoQ3ptSHtSXnebjYYxjA5aE7j +RBjz2xgsSEyp/DxZjMgG6IigIcOj4KUsPt4NHiQJkdZI6LLcTk7bOAUZpkyJS1M4HQ/PCJ0pb6Kx +Gjln81w6tsHZ+CanDzZoBoR0HaHi4LTRJlJw2rbqLKeFRHDah5q1CroyG8IKpdmghIBlU+hot8Uy +pCVggkh8urhQHBquhDjUN1qRUt52vMETj8LFHA2BEgdMCVYHCDynyWAgHwvv45YBFcVN/vHakYTV +yCcJFZXHVImhPBOGlbGwjs97KLDMQVsgVLMjk3Eap/UD5DRH6Gi3DUwSMhQBNjRbxcJpzuEgn8gB +xwWL1NTnAlzFwROAMMr4wMhCYgSTt+A1wFojHwH5vMerUDJULZCGOY3TOC3EaZzGaSdSayREINIR +ECSIHhA8ESTWxlNxMZD6OpkMlJd5PWw8HZt3bEjAU+IUxeRzTYLB/D5iBCEdp3kSrGGSszKW0ygc +dWJCxGkcG7CZ51mJ31TIRBoXFVVPqUWfhdABBUi2cRoGI756RGOj4Rg0obwEiZjKAyOQabCsVJBx +Um1FTwkzL60xQQA5jdM4zUJlHaYCpuGJREHGKwofbAON7mBDFZyUd5rBLhgGIbtgFEdifpw2CmAx +rcPrZLlYOK3hwkG+Ci7AxqPwIYH6QGIBHh4EDefg6QhVVB6DkybljTAsGZtQcosujRo6/oGZ+MVt +BB2cgpJLiFYjN6U+Ko8C1YAtYDHBOacFdAxSXhOcNti0cniPqQ3mN7LxCvVq47SgIOHyFkPC5c1g +rBmGzUACidM+nwTXF9ExigiRQuBnbsHFw0PIKPUKqKOUrEWfjal+OKPxYLGwhYco2I52m0Nnodvg +Ylg2ToyU2Q4sEZmtBRHaaPAsaMTe06CwYNBbxULySSXW4AG1BEJdYnUL3oKX4OHhNNJHhYYjYhaO +75Sh6Y8zIKB4AGXxB2JQoeClRgcbzGmWEwnk63hYw51WBYlXr9PrJRuFYIA0DGgaicYZwNep52Qq +Hh5MH6c9a+Qtp3EaBL0MgjJWc0HQbCXoymwRHe22iHrQbRua0nMy3ivAC4PBYDAYVMZbTMWsEyZC +le0ycVlNXC6cdpm4XCYuEBSWCXgxo6hUIC4gEPFiIVRaC4UFE2UykI5Nh9MsFJYVpw== + + + WSoUnKbwMZCg0ZyGQnDxSHcgzA42BJhAitKbLh+ZjNNmB9yZbRA6LU7TrBAkRiYWZiECjcqLFu4J +qBtFYha3baRlMhEFUpy0eEIC4iOTibyQbTV5IXhLEaJ6TisEwmH8xYyiM5MOTKx16Vh5uxoVJLa8 +ELydn49LV1gjb39BwsBDngIRG2YfEAXbQUdQtpjqYoSzQI3IWEC8YAD1g4lAJgO9KC4M0UJBxpIx +ighRFAjUEcugwzBCoAcUoAANHJmM0zKcruMqLvokS5w6kby9jEjewkATIp6WBhKzAslLYQpIFYzA +8XZDCA5CC4JpoOk5mY7p4tcz4Hir8RBsKkRs2WwsFoyFEKtPWyLHW06jXNbgvdGbSCsEUuVA0Hvb +lTQFz2mY0nMymo7Zay2l52Qgq/Xaluih4/sfhruNGUVrFgoqjXkheAuCeorXoSGBDQEW02wHFa/b +DghoSGALdXAym0PF67aYIrhsFMuqczGnVTIfCCsB4Rr5Bqc52JEVJ+UJxOnikIjVyD0w3gaPRBMI +6xmnmIPCwOcuSfGczGdIBztnLIpXDmUxQk06hznAuWBGDiIfA4h4y2kxhYJKNwa3RLy1eJjEWyHi +gisRb0ESFRpAPT4II7kByrhUvAbkRwcXQ1m0SeLCGrF8q3CMDs6pU+kLruhYiQ5v1eEt1FAwtlPo +8DZieOvC25A2qJyuuJC42NWF13DhLadpAixK2yFcVJFWaVsPD6YvtiACWB6XbgZeQXiLYRBieFU8 +IxKtCfTgAgKZtLieOmFFClAB0dhQCFpeqIuwOEF4+wEpGBuQYXhOxjsWUJ5LqLwV+agCjgmwKC03 +qLzV/IdhD0HlrQxh0mJ66lmkFwUc3uc1IWLMSOUtC+NRectpI1tDxzP/YfhPssQfFBUns6n3Us/J +7AZGYoPUczIuWEHKpFqTE4lTGwYCncmg0xDx6Q5UABJoMUWmgOPtAIMwTPHwYPo47TI53tZYh0v0 +sVHRsMGWnpOhqBaNvBEEvabgvYUZTFqMme+thd+rwBdhPScDLSLeyiCeo/FQcTIWDw+mr7RyEGVY +Dw8VF5ssfRMrBw8SB+QUMVDhngeRqiOgjgYwZp5nggFKyZUCiQK0eo0iQiMgTnJKIqNOgsdjFmK+ +fCqL3iwKLua0UEV3sB+bEJSHQkC9h8NAZNzgRDrYiHqqoDYWKGiBMoE2Ao4B4jSIAtCoC0yvbhtF +j4wMsKGRUBQjZTaJABuaTYThdLDBlQqEkS+cUO8Z8bhQ3+aZgE06kGB1Q0hB4eM0gViJ05rTOG2j +VLxuM1itKl53wmBpNvfguGycBtEtwHZwkFD4TBUG/XkaQBe8QQsFD2I2G1wAEyixCaRVK3ACwWgB +AVNzGqdx2shDFMlsOLw6nMZpnDYT+NJ3QCDieSgyFgIRRAjRfCcZyuKzWUImIaEOYFHHBnBcqM+D +9f1N5va5Z4agvNSGwh5QEHmt59oWPg2ncRqncdrFReO0WefKbKNJQmZTGLVm8wSQbpOAxTTb5aNj +2RA5vwWM1cgp3IBpP76KysNpsAGDlCfA8bnY0xJ5LULBwQZfAsRXT6zpW2PwQrYVp3VNwdiNiDUL +8AGCylyagrEOrw6niTaclslgnbzSHJnU0Sp2GEabh0UfkS1E83Ea6Dc2HgRNAupL8eU9nY1FwwE0 +ogvuxBCUJxBFzCIMKmMzFdKrLwMGFMzowfv4gAEFw2nbqrOcZqlsQLJLx6kQfK6JtSgKttkoMyHi +AC2Pb4Tx6GCNvi7AorQxh+doBioCNDB8ExiFzubUs7hAYZB4+PiZB2MvirkBEnlVeDlNJrH6PEgO +gsxFYuMAWSqcNv3rVvWg22SViMx2gMHSbKPokdk8lojMllIIaVQmBRdPNDCVB+VR2WCDRm08nDba +uKj2W1VYGiYBU/Am8IPVIhcZKg+mA1E4SJwSBihjZQGVfTLc5yip5JWUYZxRQmW3v5wfvZPEf55U +Qjqj5iGZUfpWSSOVDvm9++qwaZzuHzl+13apnSSTn9L4kXqMNUaPPiWVDuOc7VVCn3G6fP/Kcbnl +dlOetHrT3c3QXBK6LqNTGr3zyls5VsjVJXXucu/7XIb7O7sllNMrZUppfZ7Qf2M3pNUls7323JYU ++lOWVU5an5395y5Tplv9d7k5vsd3hrXS7a+T/sP5678OeaOEOp2+VP6M3jPC3ah5SJijlM/1aW0Y +pXcSGiuzlHJSZjir79daff5WyB87yZS06UMpWzvN+TK2dJbUYyeRvbJ6c3s3rN9T7uTtWRvy0+cI +KfX5G3tSnlufTt+eIgeFBhDrU6k+E2vBgFVi+FSyv/JSrtHpzuizsqRbq6RfKZUu3yP7PjPXbZ77 +z3T9u/KkMFIpn3b77kbIMW77w9lRO0lc1uoLp8ed25VO95OkPdLqEXJkDSR5/q1No0faneRnzxgl +3b2z8jp3jZpLEuM2U/nOkTLXGvm/Z6R1Zfyts2PT7iQ0cn2O8D1qrdX8l1JynduRch05tZTsP19S +l8+z/Set75SZP/bsSvdrjbE296QvH8qeEq7Lcbfy1AAw6TP7nDKeavwY22VrEBKW8r9+pdx1zrhc ++X9Onh4deqxzKftTh5XOTiLrnFISZex2p7zvTeHy1FyUI206Zdc4adPqvfXnQq/Td0ooVwN97Ka0 +k0Q6v6PDuXR5zoWRTs01fedKlzBufY9bOwn7d5xVfuyvHXUquWonie/Sp53EK/d0Crln7e3muvGh +c+0kk/JOSe3ptWn8+BLKrp2ko5zyqb+/pHZPZrpf5dRckvhRevfP3V13X8q+O19GKrnWSeUzrQCQ +/DPHOuVL5nOkH9Vl17hSO0UJ6c/KLV87+XPTSSWUNVKv+/zzIZ2vfUyvS1c6XCllxknSfjojrDNG +j7K/enVY+UPy77zc8KPsJB6Zp6ywxiiR7fO9Ze9KKnej1yk99kpIZ431nyvXfkqXvtw5J1PfnbBG +106Sd47VvdIYeXa9UjaNDev0OBs6z05C65yyp/w4Gy51SeV3WZfO3jgj5fmyRl/IleWkv9Fn/JUe +MfR3ZZ0zflcoK8uOtbLDnrOTzLrt73N9xgg9Thkh1/reD1nKbhnl/0uGsX7PSGmtLTv2jE6p14W0 +/saV8aPLKZm31pbLFG6d3eSH/83bX+EvjbR7xugMfbYksoxy0kp3F1KmneQp16YRTtos4+yPVMJf +365y/suG33RrnZ2k+tytXXkrhd++GBbH4lgci2NxLI5lU285o4yS9q/ukc66D/udzqfaSTJrt4z0 +Z0sNJKekcU4qo6xwUllp09pzp9Rcs5nnc8N+SZk3esOVktmZHTaVGkhzzfheYXU5eR/6S+3j+7dd +ck/ZzOJYHItjcSyOxbHzwvhTQiVlrpNW2u+RNVDT/Z+0m65P79lwxqm5JDR2T+n7Vb475ac+eeu7 +nOy0cpy7NbqkcKNHlpSfZfwpm71595l7o5TbrH1Ifmdsn5NOlpGdI5w+l8V9uFjcjBvpen0YmdYa +f6kG0lxz+2vl9/oUSjo/1o7sHuvUPmqUcanm0ly145ySI0NKp3Zi//p0V/qEcan2IX1rpSvZKYxO +l8WxOO2DxWkuFsfiWJz28S9Ya2OBRXJYcMVIneXpt+fOSGe/BuL5c+lO2bRCSSW/MvZPp625mOe3 +lLD+dxKuy1thpE+lbDq9uSvs+tpH9Ib8IQlroKYf4+zpsLLUXJJIa/zvX+aF1SWRmzb9dV/p/3HO +5m6n//R5zv6lEvb8n5UpdcpQ0tdO9bfOdnY6J+yV2ofkveM2rPU7iVyuPilsl/vaCIZZok+yGshJ +cmGJdnGSrGRfshINA0TEYtY4A5hxGqd58ZRRgZH49J96FgMcaLRApZQsfRGwQiaK2HQYRhwKHJmM +wbvborcbdpzWnNb+HFnJm73lNA96ncbzVuNpOsyFvQunqTAeyESazAJka1ij0WigxUbAdRuXi8VG +wGE4bQNz8SBQCK4BWcjSCYmBOgKYCowI0GWDNxcuk8hwWhe0KiKs2cRzMs6aUTR0WH3aQxXAChJr +QpMWs8QAxbuBCRF3hBR4kCwcn2q18n7y2tJoNAkhdTiTiUNUS5dEHQFQ5uIw+UATT4KAV8wwZhT9 ++josQCWH6W1gJOa0VAWJOY3TKKOThjFeyKW3B5FpPRwo+CNpkFKeCITsgmEOItPKOgqKvUkxP4mL +U0GG07oAi5LGaSMBZhSdmVh9GqOhYCw0IBWABFoaEKmigFSB8GkMCDinUayByCaeOssmYzOl52Qy +sUrGlp6TwbwCWFit13rQsnDS4XE0NDQMWwhRsVijTFNorJWaJGQ4zWsImd4zaci8umFiZOSgjw6r +P1YaCl6qmy4uKWyoPAKeR38LHrLPL5iPQsty8VAZbzOwyGmwAk4DPaAsPgUHmwTSKJXgkgyiiJD8 ++NIn8o3JIwEyigiJbJyHYn4IqQcNB3gWDPpAEli0TMFC4pDaCEHEcRynvTRasACEbMwkL1mIyOwl +05C8NFqwl0hL8gJAa6ahyV4eHC0ZQ9edONKdW2n7UjlllBNWp/W/a4zrXWN16b7+G59bbt05qdyN +9b9GSZQuWdK53BslXLp0dtM5J2XpXhfO720pu+n2/J/Pz/6+7TDuS1zS345MY3eTPy6d1UMiO/p3 +J6mySupcZ42S4dMocWeuUPrs+lzjbsNmWpnO6ZPdI5xUtteu7fyuuZzKuN1L/2ekcde3TvhRTuqS +0m3oTmv1706y7PwP44weY5WwvzuW/tEseWXHyXTlyodcI9NZm9effvvS+d+yZZXR3Sm7pJAjf7fc +dZbucm7XKZEyslMaqXymcCX7fq3eH2nTOVd61Fz0e2UvlN6y/fejZNZfnz6XwiqjpH7HWCOckkYZ +IZVR85B85Erpc6TTpawSRhn3I/XYX5nl5P6msieVTefHCHfKKl/y7KZ0UsqSlyettL9OGeeMs+dk +nw+ff+Ws9efkfp7s0/3lwtpRIjd+5RnjpE3n3AjX63Oc1d/9feVkWePLSmf1yLPd44wL50da67pk +j7HyjE2rc4WR0o1LWc7olZ9OunIp05VycpUea7uvs2Qu7Rop7NidxLlGWhnW7ncqu/Ov0Gf38jql +HH3Kj1LKpz7h9DnnQukvoV/jrJG97tP6u5Uh5fZtWLv9NQ/Jf+3p/7+SXWouSYx12/0lzP0cnUo6 +O77D2i9xGns6beZ2KLurv8+Odcb5XqWc/9UrXSl7skfY/RJ+Kb07yTvcfkmVcspI44zdSSLlylJC +7tc8lp9ddt04KW/sbqmc3JJ3q8eODPE9ZUPvuku7N0pKf0YqJZW1NpWT5dPZT1fuS3w+7W24dOfk +9+kSyv1tjisppFxpx4XMTp3O+rWbNVd3ko7b/dxT8kPnl8SNcylX6u21aaUt4fNLam2O/3L6y9c8 +JNUj7dj+MXb1JW3KD5efOU74UzJ12pPrfBppT+iTO8nTpfVbRo+8kfkj/Rr/K6SzKQ== + + + pZR+XY8f53bRZc+m0X/Sncvu0flZMpUtY7/cupB2fFnr1t/aWdh98sZIJ3fkntxO3SeNkZvhPlPv +rtKjhM+7PLv1IQtJWXyjpAzlczt39Mnus9LN5gUTAIMGCMfr4rNsNrP6PjeFc7N5eWiAtERcL4Uo +54zwJc2R+sPYv/tNn1/yPiXTSpv+Q+/uJJOppM3we36V7nGbRu/dOmHl7iTLXzc2nPIl0uXLuHNy +L5TcLd+Zp4zfxSnnvuYxZfevuSQzwo2V0gk5RkmskrmTcGTalMLp0T1Gji9h9coxPnu3O8f3f7oc +uyP0yDPKWHlGKSOdcUZKO0qqbJ/V5ZxfIf/POde5veF61Dzqy96dC+NTd5+RdiepD+W/7OWBAdIq +XT5aspZqs3kBgOM00JJhtEYSPFocIhwgBiKylsgCBojoxaGadFeVK7O7pEs5AtDhCvEAlb7f50oI +2UsE5AXabF4zGIeHh2iz4Wg1rVNzzcqzu9bIEdKVRHfWXHPGnrA5OvUZKXXVp8sdK0f3nrv+/vNn +/JA0y+r+zJC+N6TyvekznTy3zqU+KZ/WY+V+f+rhIZG8tHqdcoIkkzm29N5Z2T+2f0OnUeIfv86X +cUZJjXNu15fev/BnpNTljCxjf50rY2/8yHXObacb2WmlFfa/rEx9m+FyV6cba/wKkvDsOX+/91t6 +rVxhzyiJVcr+5in3KUsq49OOXSntyhuplHLj+svm+P7eseVkh73Sg2VP6cuVKW06Oz6d9WGt3Ukq +97pTGKtLKo2x9qRPYyeJLLs2ZVp9a6Sxwlq9d33CZY7OcfKUdGnD5Vq5TjirSyR03hmXzuqS3rlz +OUo5/X8hV2/v5/m7deVKOd/hpK6dJLTrrLtzY8/J1OeMXLmjpD2nhwaSxJdLJztln7NlpZLWunIl +LuNTjl5rT5br3x2b65yTW0bqsj71rr8rO/ZshnG25LoxziiR9Sn93SijhHOeYmRn6h8/KUsZPZSh +nbhj7J77NHqk8D3KWb1WSFmyb3v9jrWr3KfwY9RO7z9nrQxb+py7k6uM/1D+d5K5zh05RumUxn9a +JeyO2mnOKp3pQ5axk/Ty989Yud2nM5wf60tfpnLXJ4zxK/92baZVLvWWctYaK42S1ijrfOixY5xM +ez7t+LNG6S0n15a7/j670trv9CX775zVoctIlx3209j9klvSltXZfbpPyN1NuSVPurDy/s5+l/0h +obXWf4bv3cV/KqVsl2T55TJLSZlGCaXz6y6zXAnne1y5TGmNsEqXkkpf51oprVPKl76Ud8av3VNO +Gmm3d//k+vSnP4U84/KzpHVK3o8zSpcBlHSoZHRVkkxPkowxhWaIIAzQADMSCABQIBYOCiWT0TJW +GnwUAAJtPiIyMDwiIBYYD0ej8VggDgdE4jCMAiEIglgUxaiyLGsCyKXfg4rgrPgtw3I2c1KkodZn +duXHg86uW7cCFgzC42JfpO27X6xHSi12V6FxzLy89krazgvExu8ke2ksLnamKNr7BSxVgEfw0Hlr +gjdc2u7IpjrBBJm+TxgSM43FHsFSo7TVQN1EoswxgZ5hp/0EO8CsN0ZXo2oAA/xfnvO37vyj3mAE +uGClJLuPrgtjgz7Pxyr9XvN2rRoXyLUitZ0jz2FhzBDCtdmu14HgX7pcZ/SiNrCwJYK7j4d0pCv7 +a02njZHOECYXLDqQhyGul7wklfOzOxul34sOjmP9YsvnvK7uBD5+cL5sFk/vhgQbsWpAUqoWZMM1 +z8upIavIvoM2EfcCnsR7pktEvsG8UlLDfbkpLM9p97dV6cYRUYhLEXlUKy9xXpWALA29oWwLASrt +D+p/gcw3knFgXG1HozsdHdv4pEEAsL12/Ra6GV3Owp5Q2VYZS40FdffKmgb/Hck20Izoe0k4ILPN +NpTOB7gFWyok3xndq1jmNiNMMVyOD3xMv41TliCNBf9gOIbhFxjlavIMWPRan2Zk2k7mp7JvZ41o +I7TSRXumMpk7Oad20D7q+MXuzWYlZF1vo6J4mxUJ2brciIWM36yq0HVzAFwadWJFzVboIWQFFzQZ +C3jEwjZw/JSws5M7VeFKkiq2I5UcABRmMUdw7g/buON8zEKKSUOiTZfYB5nfuPZ0s4cC0hVtNBN1 +r/FH9Pd2liqNMuFs/BgNq2UoJ5uubzPRhnY9Xx3xNsD/3s5YrZaBytB5qzKubZ9oT9ri4j+IFf3Y +7WsiyEFk3dJaKlHS/SKZnU87Ph0BujsZVGuS1yT2LrJyY8KTc93RthycXl5rkVAvTmte6ax5Ae7x +OloX3YhuA6JWvQc1l9QhR2BbWr1s7mH98/S0JkHKpI3bOGPGtuay0yassdZ/gl1WfWk24tZlJXKW +4SmSHN8mjjdhvRlwJQrq4j3weqQQI8Iy1r7CriYybQqRvpS7OfObRZDHJHuYiavH0pu2vkYEs3FY +kHS91+YoJTqoZVhOwK9oe3BX3tr00Xg/nCxb0zlK8LFopNO1XXi+puuWGZflu0btneuvhv+/tUEM +3RorkXLYiomU0ADb9sPHCRkJDInxTNGkdSQxDJr6Yy5Zitbe5MPNxsB0ZkhbERWY/GvrQ1J/XtOW +F1m6fikS8yCNdVniKIxsHB9yRCxLFB/Ew4yYbhWnV3OwZsxuF6l92l6VVaii6fz013yDtTGB1qW8 +VcK2D9o4x0eHooCRmyjYPokrcg88q+34wja9zCIWpYZRmQzbpxMY9DF7zty6bROTf1wjm6nunn7X +sTyxRwsO4cU0gXwCjFmrS+2+plPc6Ess+v9NOyH91DrR4pkdvKhS+UJwbhMZEi1wb1U95e8AfHJv +yBoR4RB57J/JNKQx/D0Pl8mLfgM99HmEXZC9sVYNa4dH8QxSBckTLYLkCxMiaso11JJ7Vm4+5p7H +tkadCqQlrKXYN/bKVcdiNKRLBq4PszfdR4XylaQEyFbdQ4nnK4gcnQ9zFDWjnk0t+Po48c5QVg5T +3mBSnxnAb7TArClEHA13QeRDP7aYKkJwAA4HZx5zd8l5I5a98AzwKE2C2hAi3iGneCkuyOkhqYs0 +A39KHgw+jFP5D1nFDLyL8U1S3hudURw7rDWjgDzq2z9/mVZHGAlPyoNqmhrhhb6lwoTaqxPSVyNX +/yS7KJ+FHGiw9GmiymKHFZEEdya96SiFLfML33lX807VWEyj0Kow2hJ0g4MikLc7AiJk0sJN8d8L +1VLaS9YNq2bDwM+/rfASpN7PDbTJPJE+WoRhavkbuWlbzYoeC+2vY0YbumAxsvKFZ1SDbzLBxoQy +h/ZBLNo5rCA2AUseiFwKJYDwVMJMQ1cva87eeMAssJH0JrPrrxW268Gb3I2hpHHMiD3idhytDIu/ +8VlXUsxBzMMoX7ipjzHdTAFD9ddKE2AjhA8GxzAY4b9wkNhzzo3RgzXTHjJU09bZqkxVI+meXYuM +0hATmNrYZvOxEfay/c4wd/lFoWzxpqoiKUZMtHVXj5hn0bfqcew2kGqSGFx6K/pU7sYxv0HDKHqY +wBL3Nd5UIRXGdbqynHOipVaPAGKk4oDLPa0LobiylCQDwdav35QYGEi6O3DG8QTEdR1bvL+m6lz4 +DkWGUq1jatl2q8Lln45u3XT4A8Mu9BuTGiTe7LWZsgVzNqZdfDe7GlIydpWQO6ImQqavLpybudVr +YeVbW3WrAYt/szPGzQxCLl2QjoBANJJh5MhYB4Am/cVNWuVE2FSrwLazw7tWJ96kPVlUdb9ExhQA +05vcRjBfdU0GTZaFMyKp4fFSaTV9qy0qBQ9+8HSLC5a9rm4xxV77VGM0Se0Q4rzEeUDrnDF5LL8U +L0S6/rpN3rKrg3lUGMi1/NNWNtjRcCdyVIROPE4yrHZbo/MDXEz/tHnF6u/LtuIg5EZEfBtblG67 +zOnRzCV1gifp8dSO7RJ15PRwoTkS3d+SWp4aG/uTryNvCAXJNWO0uv1f+O0DWyQpwG4dD9O/D/9x +Zo3FXUpc0rEkmKFcC5HFhTZjDBXOof6Rm/fGKC8dmsuk+mbfNuJRCVZIXpICAtVIM31uB7yIMdrZ +owmf8y6158iw2KND+urlktKsVjUGxdeZ687rcX3ddk5HF/JFvuUUe0yfvh1J9v8xSK8FGZqey5Xj +5i9tyCzJu8Lt1cv4AHDZ1GfBbyw39dA4IgEnl4MOylkEuf7lz4BVhthKCBAcl4TTItVQMCWyojSe +mIKY7S8+OiTf8y69WtvaC96h8sJcaSafMc1xz5HLZGKOuzvB3zPm7XtQHFcqSLdPADgh4hlYLzXA +YWhYTMMleQ5PEHSg3OXHqPQqpvzCeD4rjHYXajCYTXtxVn61JscKjO2xVRiWE75CNdGM8RFonwZ9 +e8GBzQLoLXOq4qBJ9FtgZ2v/YGyiUzXqY1JdrepIIcdmm0MOnCFoC0mcK9bvKvIXYSqrs2JdY+0N +9Mk5CTKULmU0OD2y+C+NeVD5ildh00m9uFcxdAyJ/XeqQF6CNZSQP+yEXpfiRw77isqrEVTbjgQa +ibHNh6K9ZOiVFVliuNllad9up78Uqpmm/bKu8u9bnjoINb0glqzVmR984XUhZNHS/zwKVTMv1MPA +/FQ2ukpqgToEYJzLI/lMs6PPSpvQ9oYIWTX4hpabv3J4KTjhLKRoXMo0h6X/u3Rb1xK1Pxzd7jhC +9Nst1rER3zZiVFJBGunrcGn6h6OKf+iMLulovvzxTK+97fC2niQV30QHu1IXnSHWs3seJx0duXvW +4smZbjMsctEfj0rYXk7u1vqWfjpcHFRbL5kzXh80EWi/QCCsYqeFZ41pSQnaU838gL0T4U+GeM0q +68h9uClDOau0JH9j95m9xwhZ/sGhwFwGjImyW362Op0LmooMH/E+lpONlykrFqu1jI+ADeQtJuVg +SDRoTs7eA3EoKLwUHLJR3SCkrjIcA6eOIyk31WvdEynLMBGFSnB9UiOoEz62WbE2CvVLnAwaCWRQ +Tvdo1O00rWdMYRuylE12QRbLdLOd/jGE1AK6ICrI79ZRmTi+SiBO2YgPlKKTtm8gSR0b/60xNINP +o194sFZS2lulYsc54xGnEWqN6swFp9B70c1RB4tTw8ZJBh67HZkExeoLMDIgISu07kXjlMLg67kf +FwYKaovxI/qR75WEyz8UpdCT5rkRUJG4QVcfsluP0yKxjv+ZpRmhzd9+Xx4Bn/X8fBaMoV9TyzwL +owtBzNOAw5KDa8ksMCcMtMlPNDxFglwBdGZw1OCxcUI/zLl16W+5+SvXcSrhXRl4XSTGmb5MM/n8 +FMfGre4nwp+tG4hAQUhkjtcqAyU5I/IMnzVbqFYgwsj0LcpYzKJHLuHqxWv333NNNFkHi8YrwyMC +hF5pIvq2XsQ0D9LjaTSa2+zZQydnpiLjN4w1jhuAmcwjM0wX1LalZhnxoK5NSpYiKoa7WjyqO8Ng +2Y4p/tUxCpF6dd+RBPHqehjYAx5p8QeZxSpbMIeLqGg/MjdPl5aJsSj/KMXK6PO00g== + + + 5ioQ+F5m9RSWD76XlTSTVH+EIxA63MCOiAohAxipExZIAxKuemUgYdyeeEcP7aTmWeZp2AJJ/ZBw +z3LNpiGsNNrt7Ast9YkpBBWMgpRbIFoGR1NQeQXLZYpxA284DdOMzmHGHPWd3Owf+ZMna4wua15M +G8TcQEEqQw2jmVTaq9sqf428DZ2sIlUf3CcbmIcLaqmPGrZ1GP1N1lq425RXwigZ5OgkfAohxPwm +xsvcsLQoyf4MF9yfqOz8i1JNHUx2jK7eCxlXwq71J8blr7Qi+GS6bYy+xCFUYNRETuBEusQ7qggV +xcCu5lDDSsBj9xBjeq7IKJJHrHzFob7io3Ktpm3d1S0D0NNd1qvnYg+fmWjaiN2SZIu/ygvieTtb +yCc4GXiS5YOR0bQMG4uXHVM7hiVzFo0M7NiovpC+yopcy2Q7K0zsUlwrv0V3dmPxk97kCmUK3vvC +QbvmZRm0gws+Ce2L4zvY3o8Zb4TzbIcYpfpwCfjaEb2oH8tA+rwUygfdAOL8CY2Yr34pJwsb0ITc +99K4VGWnky/jNjtRQoibyAg/ShWMi7MvvZgs2X0LL7lVLpnAKlvZgRczV452AMuqqD5IbifyFury +mcM+gnIYRvkbyRJiBxpD2i5c4hCR7Kw7GP8LUK22lFWIY/mlS0ZWEC3eivRGiFxI4B/6N7F6efqz +9Y2F02iYbdAairZTpqolNVGzOJMsCWMbnZesI7WukiqRCN3P1pTjkCTM7ArveKJYlA7ivLTcRKSM +W6GmcrTK00h/s8SLipK01NZcI7wcggte9LHP+RgpZXgXEpKgDoc0tjKjlQtdvJ4qrvgQcVVC0HKW +kJA/N8jY+odW/jS80GL0QTggQ7+cjnZ6eSoLj3CE0CwxB1lZw75E1Py4sM2ypZmTEYrCY0E5zzor +TY04SKapq9GYukBtdrVG5o+4Gdwkh+tk2oRmibn9QZOOwnw2Kh4oNE3Jz0J8FHZyMsJmoBI+5ZwX +f0LSZefpsDrljBCRoMpjA0pqDNkU7L8GLCGDGWaGuo9SpPFYx3hNF1/rp6bR32qkashZSmOAqd66 +UrMo4NzRfRADTHSgNbleRCusFT57LdDxvv2XDFCnqiS4FYY/wpl4O1rJYffafwd78zga/ZVJYMaT +Q8N0/9UBPhSKz2jFy/1L8kunxVbJgHN6JjkskxuBXyOTJeV7pkDoBLqXUAd8YogvAl8vybpFJPT4 +T0arSiXFIvurBIQhA9MeRmNlsyQbW5J8oSOCShB40PbBDzWPIJbt66YEreTWXacs+2IHSRYL9S6z +uQZNEDj1gCyC1XhMAlmlKomzpk4WEvcObzGS5VjbJjcd8I6HNQJwpIXkGJhPd9MarN6IWlE/8QaQ +zmmIi9cZSM8BRxlIguBAg0jvtsc8lZWAlQXIjognpiqbAnQefNjRAN2ldJzMOnUaS3HpwbJ3P0mM +8rtT5XHhKyqOjfP0PWaYTiLK+d8FVElnU6R9XfMm7GKQsX9gqZRAt0AV625Cxi0VAFOOzLH+fF7U +ZCzhenuEXgYMl/YYkyWBpcIAZ0zRNFksBoLv4+LfMZC9CYxJ2Tjg+LsQm7Y+Is2nkPb7tAa0YXWG +Wwgl0JamGY+CT1r9NBAFRqLZTpp/9eml5iUHKYMUzKLu90nV0uu6AFEku3iSgWWy0CNaYFRzbG5N +ciIlgKoWrRVLX9IyKaNQK0c3kPFfospJV76vte5R0bJWmJbqCzpFmDXeaQl2Znaxj+du8Z3e+IFc +jw5JArjjwz+rUmsxKYzXhhEdMkzme4VE1XGxxan/rX3eof6xEjpriajapf4gdQ9ke6BsqcIMFJ9B +2xW5RqW3nFnMSK/gUW3eNaWSVc+55o/WDm/rErfm6DdkIAE8o4aQvaGxHLiU2pyZVoK91lCMvKEO +VgLEFG2EVEPG8oZIthKw5ydKH7j8JbhiZ5XagZtTS/hT6r0jBvkrT46AnvhOlX2zIgYW2UKRnlqX +p1UJags98XljlilGKPN1Jr0+eoFPeGg61OiSMwl4vdatp+CwiajCYtOOcBITskVToYSD640JDBHX +Ci2VyPnAJWnyXj1MPk41swcyAvJefR2IT1QJbN1GZlGt8UH9pjFl7Z+g4Y0e8RVWx7gf1mgdTkxE +pcNr6rfpv5Ulx5EWOhUPHxrTky1CanQIV7a/RhtNKZoDn0WyzVf1w52RIcy0Afu6by5MrFQSraKC +qNzzHq+VYFn305R5ZhsZHYkON/JCH+UsjQ6dQvppszFIMp7VTmzJebJG1I4Sd/HGnoM4RICrOqwF +izhraKvveV4YIeYE9Nc2qiRismrKX8umTsUcJTZVanNtLJMhx7u/VNpVkY8JVTGOzXYnlu0gjtc7 +Lwic+j66PappjCDpfrUOTuKhBPFpvoiFkDd8X/2axjl5UGeSTc03xPnW1llDTFgsFQbdRmBaJYo2 +/VL1Jghp9gIgEKKQBp2ORpr0Z99ikigb2Y/htHl30YuyRRyQ1UZcyfYNbFZelCG5A0O9EwQQl6mk +mPNPz2MjEr1x+nITSOhXYDS9C7Q0gfxvB57cRwaQX+UMQftusu432qOEZbxv4EqxkEtwQNpjWG3O +EtssRG8EZEs6FAhpzdLC+P3kDAelxWyUQgEJp66np8vkXx22qpft4+zXlJfbGy770iEBINlIKHYW +W5syb05f92gGEDeuzjqtiCuy3N8J4pJPxA3/pdUU5BhT1TXInhRxcyWI2zIRV7EhRqsHPWMgLi49 +11aLuMJiJWaREYqR5VXELYvCZhbZuTGy1EXcp57Uscgsw8iCJ8giLo79wVlk58bIUiviXmvVUppF +lgwjKyTiJlAJp3OXq1xmS85tipFJY1GaVBE3AovsqR37GJnhRdzATvaYRUYoRpbziK2VeAAYPZvk +Y/a8tlKeYB/yw0zi1nO0l5Y12VU9zLuGVsSFBsTtX+HEyPaJuN8bXtmJ7CWs6qz/cW6XmLG4ZKDo +ffAegnx0T0Tu/1ecFLL3KchT6jjU95NIhPIXkEzDq21elfxg00s1X9eJphfuZT5MNDE6L8M30Ywg +H75/OyZVz/TcJtrI0fZ0iIrJp0/rBU+gxKjZMqWywXRYDwIqHFNNMFpUsfF8aBpMH2khQ8ky11Dl +hCNmo9Z+zf0dsyybDR0gJsyDYBchfzeWXJwAbI0E6nAKvDeaK7J1JEi/Zh6E7HnDFqVqrC4Tg7D4 +CEtUVY1q+i13qEn9WuI+bYulMhrwNalqaMP7JcatKW/MrBM+yPzjWrcRbpjjiC0KqeZUyAyd1B1g +FsQpjiiO43OnuyfdfE0aPPgdwcJCIAevq9x9AVrpaO+ABjR046R0/lixr5/ta7+I3NroSPSeWetq +IvbYeXeXMhSgyDLw9hIPdfdmaRZni/LTk/Llzfryb/D2r3Ajg2r+pp/tCyUA3jqJ6Lf8groOzMMV +zDl0d9WBdxzOFUx3d8+g3oQqlgQiJGHS8O5M4lAmCGOMJI0nRdrdsYxxkGztkTiwuTvsZcFdeVXq +UQUIzu61wnL3pGYB3W0yCW9eiAJNA7QLOIVl0vagP2Cua11mD1qMXepNswRD27r/49YO1mp8h3Zl +1V6kZk+Hmqz3ig61XXz7vh0aMjbX3qy1InAFp2vbAEt1+C/ApVP3VRE8Q20XitthuQaqaHv1B2Xs +ekFqBtxItnADwJvsdQZURDknIAj0IJJsR+Ks8BhhD+964fWgbbCum2oSwp6YpRj145MmnqAxVZTr +Ecd2YdMj08063g+ioc0V2wAgONcsIq/So1r48elsGDAmZ5+IvZXKpFUJ7wMs1R+/JrzjEgIgQch7 +myLb6kMofZ1B5QrM3meZRVyA98r2vYqIwgrigGgdqpYE7ySGn1h6OVInldQJnh2mZPvDJxw+Ora1 +Ay2dpcDDCx6yzLvs9Xv5BFmWbxghYivJbOxBXfADlxInXBGnsfPkGLfkiwn0mrH4ESpe2el518yE +0JfTgmG6NhOhSM4blAUWgyp0QHHJgq0dWsvK//XxCZjAHSEh2I4cD5YVBBpUXS99yR66gl+XY1Ic +AK1DfzmCEhwJ5Ct9QTBZndCXcV8gWVnV6jUDSLaVfoggsmtWLvWa8UtmJvQlr/R1s/vh+B0tZX5N +LWu+QvrKnm/ICH2FZaWvNjlm77GppzTSOxc8JB0yN2fkenkqkWuOiYKwy26Ngd9q1JNDGIdsv/tX +lupqVt0fdP/8JsrRGi2Unnew3snfn049bND/V70agLEFtX1+xYuEMFQzctMJbT9AwVo5kDfqyMLk +xu4gCH6Tk4r230jIVL934lxL52QFYiRCiH8TGVwBGygNLFwBIWOsFNwr/kORSilAtu/m1c5PsAJx +Y2pNrJpK+B62aUoZD9+DHsh1oPw7Z7YOMRV9NikB1YNwHk8cJpgJSoh/OhZiY2rFNv2LZ+01/MII +8k00OsdIorsTIcGy5XK0MUEJz+BnaKZj2UlIinDYGrTTUg9gdtH4PkeR8GqDZwhxJZ0QFPJpsGqv +kVLQPQPifi/gWjOi3icRt9jHxvVtEHq9Y7DLDxocctwisnPuodPNtn8OpA2d0jZUzkuMLH/TRzX6 +WEtsk/jupoMPZ55l+8bgM8JG7icPAgArXraS5VSCl4JiYB0sMmUGv5sBz7zoutqBWeprht5+LHCP +6XfXmAnVjdHEe0UHUa9rn9Ayx5/lI3FJxGCrIlib298ReRNrDt82DTuz41wOG3ngM8+00Okzalp0 +icaMWhHxwninD9aSbtXwrV83019oQ+uLalKTpGijnE83MPv39TdJ5WM76+wGEjYl0ANxPkBEDYRW +lQLwl1eR9tYn4VDrCSvOze6NJarUKLhfLbRlVwnFrgwrrfWsx1JMhjnMuVFup/18aTBDZZlp35GV +uSvncySNYcHFNeYEJH+i19vJr/RvR7QjAMu5GUdhKbjOkZM7HORn3m68Kz91j+e60/3gP7/xqlnK +nXZeLa2xFimAaiANhlApIXwCS7aBOmm7sYVhdfUZrikYuLjzFR0/7XxqdXBN2iBulooQE++kZbMw +s5z1Acl/47XO8WcZSKLGq/xenbM+RvLcHssSvIIVfYMWXWj/4dg0mKNQMvUlihiGNecjB+gIziN7 +rLTTPL0hVTh9g6f5FH7YCxuLvcr461xA49Rjifuv9W8iBo91y38b0LiJu7IGg4+D2JWpFIXNENd8 +lcH6EpmEuOQHLhGuP/jow7qN0PQn7Zj2LsP6Uhwl+8dM8mKUbOZVXioDK+DKi2j5ozTpwq1mzZYy +TJkWL1o5OZhbYRKe6VK9SE7R1uB5gRe8FpNhD3R/cfPxpmKb4YCJjZ/b2hbIeVWehOg90W+EhPX2 +4NkXdf71RRXpSArEElwCnKVXBLHD6++DdhKK/C28ShAZisROlLkummBEAkX2al8STp2GMnGhaMaG +QsqelfMNYjdU/4XaWBuqFFIcFgpHa6iJSw74QlXWhkI4L5TlLvFMDYWKmmYLJWBtqA== + + + PqQmLFSBsqH4QgrLQm1vDQVCNhe8UCnDhnL+8kQLtdo1FHCpcnahcMfhDEsC00mXhLGpF6zjbqXr +KWUMDLga2JJNl629pDJsWNOLY4UfhjVqZzLsonlRoksKVhdTdtzA8aJ1J/Lr+bTydoUHTLuJLCU4 +jUmfy2ib+xSMOyA0ITpeYscfoU6P1Hpe7o4EYGPU1wwiGSt/iLQAcVKnCiWZGtIwBDLEOOjLqdQw +VDefpT6OzDfeh6H+TaVuQnKk8o/ULwM1Ps+1jH0vAPBGtjmTJztVlZ30peMGxkkIAiFntiWUet7j +AQ19EJkFBuwMRqMiCWU2EpvZnEFHYqIVlfocpZm42Iq3vJloKAMe4tcOaFDUyim7EcbIVMF8JhCn +Ho2sdqUGg7EsAjrgWROr5WRLC/3CtzEuvnRPcA4q1RuOIgddwMjRiC/CUcuyZ7xwK5Lzx/Kh21/E +1E6DESALL9xMVNxFj40RPpE++sU8TFAlF6nE4TUG3lbGienbXzcRmtggnSHkIBngRsaj9GveOeb9 +bccIVxfTORfv2ABDz8CFhnYqM/o99EDoggUlUgGoQRFOtJ1Wi9Cd35YzelOXsucjMqgr7wAVoAhV +U/BuhDPJE1bNkDFReqCTT3Czt3vtpxNxEaCyUB59Y3pYXAR7iJ260o9qLZnl6FAl7HkTn3k0+qkG +ZFDhYNCaEpZcOoqyJtwjUSm6qlzaUhJlRPUBQXuVAXAzXGfnHq2ADZNEFmS+GV1iUMkhHdCdo8NY +XuM6MkacQ4fBCIctyTwXACKC7ZjYN1pjiuDomhXLB/FgDRNby6inm1CsFhJIaBr5S2pC4NexkqUH +35HW/2O3M3gfWqKmjyXKQn78ISIUQX/UjfW6jtNZgVgovCc7NpVExfIUUJ2Do8kc0YNw+hNrLaqk +w4qXlc5TZVCig73XPaYwEEBpS9UD7eZHpkwaM5BHMzEmEj6G0T+icjVc5vKxwLgqhI/OGOqrlDsd +x+9+jLw2Ty+75qs4CPbgKvQlOeilxtP5/4kG4Sx3uAmANniHG12HSyy3qANttTO7bd12z7154Ljp +L9P/BPHXo2PsQ3ChjuBdKPKA5l9t42eiRhkmuRremfFeA0TqM/Ja9nOcxDXGLztzEgXPp6kmZd4U +NpQIZt/mpNqXkVSRvHDJa4XjwsAgJkncNvJs049KCvRJ2xEpq6cQXUGYF08UlzPqhShBp+WkdlVB +mJVmI0AaolGgVyGFBzm+HCfekcN/7A8Tz2II8bNCn6XYXTsCk/rh3l5AVg/lCckgwzCrB6ln/Kgh +HBVjRszyITWP/YdidMe+7gMV7spWRZ0hYAuPPxA/+xqCwDR8nNFAS4R16oxI9q+PCO84UGb4dCaQ +BU5T6I/RtUEA3KPabYql1wemNdmJfrIP+R08m8o0eEs8U7lU8hGpFCvB5rZr2MS0u+YRfv8WXrWJ +Ybw2GpCXMwVVgbzOUFV+fCi4kw9HyvxtKQgL/+72GK97Krd1S7SOSeQZPMsD+oSjxL3Ew57+PVia +NAWDyGu1lv7R9iioJYomCjQTNIJLFYBWJN6/WF7O5guagYERuT7G/YJ5SHuPA1qrMSWqKos7orQ4 +uQeWaiPB7VIpFLcO2X1LmG7mN5p0a4AsFwJqdPOTMIC+pAJVW91YpBiTZnwdDannsWqoDJJN2tuw +dcBXhSpj16Go23I490WT2U//gEkeiZ//wWXmwSBt7x81b5HuFZ7CtJ8tZN1IqQOY6aiHeVN68hlw +spl+QxvZY7ePEMWs3tDbd9FDBa1nHjZBGRPN+P4xXW+F+1LURJsGpLhdit37KcIJtc9MiLqiJeqN +jDETFkCtyMZ2LG3JD3kDtyoymtOz4HD6GII2YJVTaYGdoUbuhXc6jUtcZwdkHi6XA+WHLjeZzKQa +YnvN71a3P3Mi0GxQkaFSgMe+39WfeHaAbEeCvupbeuzBgMoOzPFpEIDPMnqrEBkx7vWobgazuwFL +JSpYa13EPUjNZv+4+7A7P5x8pfDCWwC6exbekIaa7Xxn5NkU3i7KDsTIpnc35vANZPgj4Q3dXX54 +x84bR7ayJCi6u8qcGqwscQ5QhKoX+bDi4ndXAsGJLYvMNruDrXrCewV3A7P3zOUS+Xliwd5UhDaB +RncDLrSHKU9bR5nn0DO1LalE1uc2ae6a34u2z6rux7A285zafrP+oAtfAZ3bCe8G+T3qdAkBYm2H +Fjib1/XKZaftfHcz59QihUesd5JOrEoVC4K2GxwTlMK6Pl/5Lm2HRLFX6TiCBVAmt2tltKttkipA +9Nwuv17f1jYs77kA9kNwav99SttapnwOmLAuk0SZlWt7YkuBk6YeRxI2/fZDW8ztCUnSdvZ+CQ5g +QorwCU7+0GWeC3A9zp4Xp4UfXNvMdiKu5dizL63yy833sIMRp00ipADt+JqJfdgk0nf1R4TpiAWK +0lrUdbdrHPiKpEmLanmfKehM7yNjrjfFm/RN+ho8S9Vh9ZBLAO3IPg+exSGFie0BS+mjygfeq+mA +zhD4LdN4NlKOGp5qq7ZFz84o2G4u2vosbO9omE4cZntH7oGXPraS32fnnMz2j4VVZdC2P55gIjLr +YWbzGWdb5WPDRF48Cb8ZM816LJtP/GB0qFeTQaLN8jaqh8E9APCHXrlG/YhxBVvV5t/c/aQVKdGQ +mvGODbxqI3Hqk5Gj/TboAfhAQ7Yp16g9YvY7+n6+l4lDf3QQkGxMu1qUb2n5e0lZ8Kyh0ZKW9fYS +oQsXGGOStahim+HGNU3TQ8afPDYjNgMNeR2XLKJTABDehfzFkCzoZ9vELrYQXv1v5qid4SkA9GLw +soYMZZoqM29NWGvoeOtmCDmtEwstiMxe+vtBf9QnY/H5PlOsQzi6fupN3EemjF40YwjHzkNydO2v +IUOjgxxE6QfcX2mQKKCQIlejJtbELtYpfI1G+JV3bX/erY3q25hWNQZIWCigatYgI4c8pu5T6IXV +2LDBRXTqnVgdvqNMhn3XYf8wv+14m2OIc3BznPH1O823k6Uypw6m43AHQgoYdWOnsQanBVAlEGd5 +1HWMU4dvmu1qeN8Ivus6Zz5LOiNhpPQgG2LboxPAyW/coHP4hVgVFNuDNub4S/07GSVF05EdLF6C +YsaqpylqKhcofYYbzwBr2TsVHmJIkfhuNBnaF8Uic2hH2qrdpBNGsWasNsKH+3WMbjqWg3vVcpvc +Va6URvXw6CT+K0HlCOzJ4m3RbhibAiK2Sbc7SXfnHu/u1Pi5HdUdV5brwjnSdQ4U6uwllDVvl1gO +oKWfwoID3n6qYjAIBgCJ00q0lMKZuTheqj8DtQNA0MYCCYbljw2EEXL7gwIjY4TR70CxCQnX0+AZ +KaUFgSz9+n6rnUElPveam7X9fpdQ7hFLdcSX+sWY2CStxu9fPVKEwh+sbtcTYFHE9TMFItXt/az/ +4Nyr327i8JTWYEVsTaOigt2a2Ta3+g9tvT2TPnYHYR829mPHcYXAr4fOqlqsi3/KB4O5pkS3nm1E +4yFL82xal98GNhDzfvOlU0phdvPpx4fBg4DrarU99m0PaYSY9n1IbRU5fpR1FqZK4fzZn22Ctio4 +V+E+lQlKzEMSMTWUi/lvh5GdfzI9btBEGIQLzX7i9Y8Rlq3f1dSynoizWA3rDPdj54xnQHDY+M3r +2Nq4ewZFSmwwnjPwNCgcgqZI2M+hyhz5DkMdULwXUyp6hpi27ZFFruF7gNc6zk7Nuc5GEvZH+x3y +GTJL1YIWGSExyKH1MzOE5Q9h+bQv1eHtWBO5g0gluJxhaX8fCkE2J+rq+c6M10D8trJ4bW86IGt6 +MrbNkmMRP2pUXZROvVoS1DHRRxVABJL1ntf7GjWivmQN1s0oTCOBjOoLSUGDj/jclwtk2VpGusUy +ZVyWm/rQsfsIadQM4c6AMs4EmyVVRs8wrGBx9NiIbApMTBKD6T33okrm8HJwCXGtLnMgvC+F+BmE +d4kHefkmrTMpDeYlOPcW74tTA7p8Y9kHg81Rll4NR5YC99UvjxhZATp4z+yfvE5ro9br8ECpcTXW +kr7D8HLTEiyk5elsx2hF8gJHiDq+p/qhVgYO9v6OHj3MnG7w4Py0wRF02CqXYuwV5txhVlWKZylW +jeZIcy2sVVPXPmoWxdabeOixHA0DHapRoAfFL0hV0aIVA8n3/OOXuBDfl7Ugib14bHXYULDPw6/G +fjxDOI0RuFHGFwwLRNlyHiM8wYkZTFk3YyWMu1D9OGNZJKiS3RgJz5b//QqQY1TbD1OQ4CmfmJ+2 +LTJb+GeteKBtkFwJ88wgts4LTEia7xnfvQvXjOjxIlpvOYgvbErekIUTDyHp6PvIVt+YEEQYFjAY +rEcykp8QEU+TEQXydKFsZBYslinQbq4xzFA8Obn11a4HQ5OUecUThhTI9GQJJeIpuatCx62CqpuD +RjzNwImeWp55xVNy5aB1vxNxAEmKixRPCHpVQpcO32G3rYq+xtjyUEEH77kCTC2BF4w1MSHxUHan +WtZWdr/OsDZCBHESSSvEJvApNKcdp2ZIIIJ/ac3nuzRrJrOBpy5qDV7JWuEm3Ru7YgUWHm1XUmOv +3v7B8mnzHTdBa2uA0pLi3wPqNHctBgKqeMyttmHx/mCiwvPSMcFbccf2qmR+x5G+JB0TPjlAE4xX +Hp8/fwz7aJ5lYuLqaJxKjhipPqyymF65RiGr5bmKpB31GGmlix64h2nNps8FY6Rope3Iv0+cWs2N +bEaYHni+BHSkk4oihB5PdwYMdeSVSOuqcMOIJkXyJzE7skjqViLJXXJzbg0HuQ1ToJfzgfCOLIOm +eOTHs6YtpHBF96TaY2/o5+lrehlGjb+dHBs6P1sHcZGX3uqVz0/AJsPsAQsb18lqPsQcKBRbTAJl +RtyVVIwXaUxE4bX62VEcK2jdwYbYGeQ8nt6m2H+4VDXikRU7hCct58/2eIrWRSsx8UVGV5xfJI8n +RCJw+Vi6N57gFdz09njCLrkdlBD9qYt/PHHniJM+46PG06/D445dPBz/P4mdxxNm41LI03j6rh5u +L4mVbzzNiizJA4pHinZWFQVRVtmThrVIpYkEyIKbYNUfTggUqrySDRGg2XoMyyMaUr9Yv1lDpAjb +XAljy0BBWOAq9l44LI4Ib0FEEAs0tqzLQIHmY6l/hW5kGe1JbWZSYXvEESuIGL6XlVpixtjNbytj +IfU3rVXksKbG57F3tN+qS554JtpR/dHhyxvzkN8OGDLM2uKWzXb93ODqap3Ve9kdmVLX/oG1+Vw0 +T0sSqlXwS/m6BC63mWlkyEGwoPG+6z1pjWB5xgF+MqFIF3TlXfOPD/H73/Ip2wu/elWA3EQFMPTH +V1+Dcn7nUfgsFVd4y/EXoCDWtl/Etj//uhwztKY1hf6ON5iJIUTEnNKiX1MEoGMluRdgWk5dLayA +cZt1P7fxdAVzbjsaB2Uk5gtJ90cOKZaDeLDGb5UhCDyvMOnxxX19ThUNlOAeZYhYsg== + + + y+SKMCeiYkFkIkMq7DHcAZj4F+4jHKze/7YaMIOXLGyRIULW6x6vhfP9NYkhU5wUJoWr75PXa5fl +5TPrDugkz9G7qhjMG6IjeQKT7ll1q9jkmd2Hl+jOAqydZZo1+s9mCu660pufscuC6hhRW+Z1Am+z +MLzV6YXE8bAFAYWI1wZkTWF1N0YB9XQg6Bi/8tT650+cg3ZTBlyBoP4WcNs6TX/P9KThX0BfEsiz +aAYlbA6b/n6ypgKiI5dYpFYCkqAwhaY7Rd7qk4sLoMQIPHRcTB8n+MlnnAYdCxG8XJHAyu4Blh1U +O9Xbt/LlkwzLB5pqcm+KfA3JSSKjy66fV8376ivnw3oYJAUscMxUe8EzkpKAW6ILbX5wKV8CyOzv +Myi6h8bEnZwexmUOqrVtDnhx6YjWHk+P/3zEcsqJf+5JAKetdeKRlRN01DyUr//LoAoRAETowToY +FUMoMCwHhS4NgMnKsGzjfqsmjFxTAv8WDL3mg9IPVz72oHrVvfQvP0yYbA3/kgWYyvasyVExPuLf +J4dwmP6t6lkwbq4a5ibuBnDvzEqxAP8+QTevEEWP14PryLXITU4Lc1P4GZtoSwY3N23uH/QC/oVC +HGu9/B56ozoL8OYZSdMkRXNTQhxCLQZWiH9f618rfWD4vi8D+Hd8ktCQVQVe/JtZNzdBe7YZYnlc +k6yHMtYx/q1IREf9i6yg/9k7Bgly7Sjg30fxgb5UewDXVuKoyjz1XpgK/vWpfFCJg0fqX5MuFltz +cDdpnBygKyomwk4dOVKah48UpPUvj4v30MLpkmL2Sz+ALOMb/tW0z6at7M67aGguvMWHgX+71Pvg +3hLjg8r4dxRZEFdPmzFYej5HF+iizcHbj/X7Z1u/e9YlbCkABs1MRsTsWzWDg4zGvpGxfj3MICEA +6TY1nXDKZn1/vyVM7ZaZjmunGYAVA5gWfCMq7KQatgMgxXiyK9Q1xc5hUIUzOEQwZsb+qDS68qrx +ELY0StpW+QDlNJpqtdyd1ORo7LE0KlpTYlQJHwdl8NDCUaLwYhD4sEjt0KdFvharkOsrVdgL4sHm +N4kP7JV0u6QjWToz/NbWtRdHW/CE9yy/eC2JvSpRWQl2qsFcqiv+9tJvqLHUZ/vvunF0tCmY4kTL +GP8LgvxbvbiUqhJ7y8Z71vlA+ejtQ3nqOv7t5ykgVR/BRGoBmxVT5MkX5GKDqxMGWvIiozfa8mBi +ofcDtxOyTieKvDPOpWUpVGikTXD2/2xT9u236iLc1go3I8nmb8Jk8iUokMb+eIrfgKaoFDvfvLzB +ZBbiFaI3Vgx2KjyIe8iKC6mrgM/Ei7PN2ovSUc41XvMIDq637b8ohw1R+sDH8RMyuDRTJoBSYSX9 +wQRGuOeDwwEpwjJArFdCCcELBsFXzIL4cWBvHNKch3o7LZJTbRz6GqgXqd9A6gUKCq+0nK/uFaFe +xoKJL+3WbKj3sibqkdSrJ57MJiYonkHMNQ0G6jUDAcZ7er5UVmM+1AsLwCgpUq/sSpLS6XGO8Q1K +PfC4Sr3zs08qBNHMUO81zxOYLYOtmJTd4Vd84npOwG7D12sLvMZpz9LQfNiqtq1YgA0gJuoSKqXC +Fb2484IhvJ6P+NgWAUpLOwZpCi3LvTMiNmrJf4jQfh7RRl/2SM9IzyoVp4E6Wk520xlP1fEFh03a +UNRl0Jy5byYqvj8qbWDLLhuH6jnOKJEGvkdlSBFlaFgQGP4L1AWzdGdKK3Yl5OSTIzdKdAyG+CE0 +ltKX1OCWzU7OjmFPOQsp9P1aMQXxJlrLzrjJGJ+wV2zsLoLCbcemYjAlHWUa3yUNnJn8kMFTa/78 +aS/sH7F3FHMyHexNGZsRtMpbwhWPGyIVdN9PdBrAPrftrFvCiMuUDVUSC9k9FlmCxtMstM8KsIHC +5hV8drWDUVuQXbywJZbirp3VsbOZGrrsPJwjMZni16TaGO3b8HaTnskbbsK9NSITPBycp26uh7bb +sKCQysOG9n/7rt5dMq+99I5VJZCR8SHFsqt37wVFDKpeNy/ALotGR1urXjq7jKV0Y1dT9SZ0U8oh +ePbVK4rzzImUYXXSVuQK70YltF8RHwvPeDmDFXaIKbq9myUUW28pVy8QeW5RWR/vVL26Hc7VC/EM +HOpGp/kCjLEGBOVz9doiYzoSZ8SqXsrTNTfHPL1MZdUr1FDDGttijVHeBYXkbjS698YGrATRV6v7 +WS5XSK50JBBiZ4JOY5AzFl3VHLCOLBTXWlkqPNAe9/KNR5t/hNHH5TPUlQP9p3HufuHBEi0yyNAz +q6HiyNE1pXruSvsRxghfFh/9aV1bJxV0wEePN8HH7iFEhpFZxptmFUL99nG/qHZTyKgmwPol4nUl +buJqwcbDzpAaf4p4MZpP2KdKBUZFkIsIiOHflFxaYrmopeRlb9IwbiFFcTmfVswiQ3FoaMpge4cv +X/gInJX05BHDLOKiQX9YYf8tM1iPUzh4ggk8Aq2V/FF3IOPkCJhYbvRBChlzzRq9fHd9AP/xQsKz +epiKGoRADJvvXbneGhSx6thdN4HL5F0xfwUfLBPTE0Fr1X3TFfVLOPzk0ARW8+0AHZHKMuriOSYU +i0FFHR3sJBmRUv3lU5YonVhAycjiT8Bg493HagB5dzU7PxYuFzxxKrTkrEHKhbQfSIJP+3Nw6wQB +rhWFpvtSLKyD55BQ7BO9EyCw1WndOEcylXkfDSJSPhiib028KuPnu+uLnXslTjBn64h3N/pr2n53 ++f01T+4sasPZD95ddUllQBo9Yg4cMa9eg4NJ9mBB/0pNGnokT+67++xeBXlBO4t3OdnpHNVJPLUl +K77xrlCzINeROR4Dcox348IPr3+p2+8u/EvUYrzragqld1cIFARcGSRM5X2YKoDzf0keUGDXoPOp +QD78MkCzZgR9c5cvjDMWJixszcDiNQRAaMZPZ+hbwwsR4aP/62I3cR+4q0YLTDALvg3BXueLQMs4 +pKyGUxeGowYtEiDcWDWkNUpTTgPh99MMTWt1zdPnUiuseyKd6cp3kbQ/k9wrBYK+fToxrCVLR3am +Chjatar5T3Tyl+Mclenr+8c4uzrKJkKl9LcMql5Y5LUYNZYsnfyevpA7uw1cbon6sOt8hXtHVOfE +1+fpM3fCGRX+zI9ZcgqIb80jL+PL5Sg9jWHgHcPs2AoeV8gWNUKKII8rt9dV1Cj7b+i2EmO58NIV +xBaI/CAmrTxv6dB2dshbq4UAOTTgPsYYruMl/m2tCKTQF1VbC9TTcnMUoN2a3MCcs1+WZd9mRg0A +CnhgyL8luRf4fGPBuyX4pA5tK+XIxTP0+gjp9LAEy9Gvp99t1bZZM+gbY3odjg7LPTgkjByF54ft +gxAmzu2hreRH4NB7NzH+3I5S2sRgBni9y/Vovit57+6ZuboNzYetiovUtkUjMC3fkE1g99Nb6Luz +s+uAzvRjFz81Zv/kiSpNUiGGaEj1DdPlq76mrrl8GhfOMryhxMnKFwwVOkQYJ59SiATDHoA3cHKM +dmU4BaXrb/KMDgzXCsTHrSLUrxJTn71Qzb/RPauYtKS6TE97BTmeQ8ggPkMkYdZe+VEHoov4oxUz +QXGtnFqyHa1D5xBI7sYZeWvow8QnpJhEXWj/9PTF+hjpX0N7KqDCo7x65H+ZaugzjYrF+GrjPbob +pgcqumD96DJ1SMNAV/TpBm01VTTk1WMxoFJtpEwyIn2wbf9ti5A7uo0u7mCUEDi6DdKgIkpil6K7 +fNb5tXXElBfK71mffwOZhamjOwKnrE51QNYcXbC6Qt9QBHxr71bn5vnjx8K8S3h85zkf5+/H1aMm +iL+ybODiKYGXFDsuqUfvc7KSJJYsq0BMhCv+Tf4M9uyIySgmWfUVdvGjCvWE4rx3bW/gGzmwELd+ +aWdslmLvLyMu6go3pvi5sN1yvnNKK06VvPdTQBC7FYJIdH2KR3n6gC7cshhLm9cD89JSDGhvmBwq +FHbeJaEovrFZxNEcrJuUChwxxCxDylubkxOuCxwhBfr8oLzoXWfXxR8vOwE= + + + diff --git a/docs/imgs/logo-horizontal.svg b/docs/imgs/logo-horizontal.svg index fb169f58c8b8..9cdd1b594dd9 100644 --- a/docs/imgs/logo-horizontal.svg +++ b/docs/imgs/logo-horizontal.svg @@ -1,32 +1,85 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/imgs/logo-white.svg b/docs/imgs/logo-white.svg index 4aa8d97280ad..f546d23b3358 100644 --- a/docs/imgs/logo-white.svg +++ b/docs/imgs/logo-white.svg @@ -1,42 +1,3124 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + o2fP3CYLc0HTkrm0lY1xu0zMha0ey7rdZNm2T5Y96/OLnNmM862zcbx3fycRz5bhW6t5Hvdqo06v +J7I07En0+z+PgN5I89Au6iz0QpqCHefwrr/YoWlf6u4yGq8bDWQJ2H8s+X7P5F6to8hHG4Ea9iZW +xJ80anj3OPL9nsa8G+db93HAc3YN4ZsnyhS8n1gXccB0P4ZPjXaBs8toAOPqpVPvncCDoz00SWjb +BNr5mT65WqZvrXZJ81uXM+4222bG1RHf2TWEcj1Gj22O2WujY/LcZhk+uJmHUc/3UOb1lzk0mXdZ +m13ryjJ5bH2GD87L4LnVMXhr9Awf24eRS6uzal926c5cl7V5KxPIRuso4vmbwjuap3HP+zzy2TuI +ebeOuK4ro9fmaf7e7CDKP7uo8vATYRLaS6Xfe+iS8N8Y3v2awLhvU0jnawTnuk0hndcB49lMpN+b +ysSkXVR5aNMAvnmbwblf5DnodxD1Pgxe2owDnrOJLgftpc/wzQQK7hptFtpKn987qRNs90Dq2TiH +dfYOop59853zM31w9YwfXF20ediVQL3dIUnBblBk4I3zrbNlANtmF7hedsaBw4vezZ0hdKOzbr2M +azFo4BsmfPEtBg38LgMzKwuD+TvTzoTZuDB7atts3B/jaWMduJk2LCaQbcwmMY5rA6aTX+7QymL0 +2LTZt5uM97ENnAyDBl7mdYHXYBiyclyxLF5XzEVuFuMdwwauAcIEPub1lcWzyWL61rQyhG1cmcI2 +7oxh2yxzyLZ1eeNq+Q8D49oLGLgP0+DSNtbBRa1MzAVNHsum+Q5ZN5os60aTuaxtO3C6wwbewcIX +pzdosNlQ52xpaVVhMTlA20O7wITFRMVUxcRVxVTFhMXERcVE9VYzUTFZaTFxaVUx3VRSTFRMVEw/ +R6xmCusdLLCpwfWxXWiQk6FmqmJKEJWTx7anh6Z1cDeVdcWBiSpLC2uqC0trSyqHjokqS2uLqUpr +aw+NjGmt7itHzmnL4UB1NUWFhYWVdTXV1WWllTXVZdVlRVdlZWVlZbWVpUWVtXVVxTWFRdXVxTWF +lUW1lcV1NXVFxXVFtXV1hUVlpTV11aWVZVVF1aVldUU1ZVVFZWXVpaXFRdXVhZXFYYtrK2uLS4uL +qivryoqLiotLy2pqa4tqa2urisqq6upqC+sKq0vrampLyyrrqutqi4PVllbXltXVlpaVllXW1ZWW +FtcVlawgpy3HQlXWlRaWlpVWV1dbjoWrqa2tKq0qrS0urakqrSu1rS0rLjqrC0xVfeuKi2pra4vr +qmqramsrq6tqy2prq6pqi2uL6kprympra8pqi2tqy2pra2vrSmpri2oKa2sLawvrqiprKyvrSuuK +qwsLq6tra0pLa2tra2uryuqKqoprC2tqa2vr6iqLSsvKasuKi2pqa2sLqwurampLK+sKa6tKS2oq +a0tqKitrSwtra+tqS+tqa2vrSmpLa4pqq2pKq2uqS6tLq2uKawuLaypLS6ura0pLS2uLamtKS0tL +S2srS6urKitLa2trKktLayoLCyvrCktrS2tK60rLauqKqmrqSkury8rKwpXVVVZXF9aV1haV1taV +1JWWlZbWlFWWlZVWlpXWFpcWVhXWlJXWlpWWVhYX1RUXFteWFZdWVpXVlhaVFpVWVldWV1dWVlYW +lVUWF1VXVhYXV1ZW1dVWVtVU1laWFVZW1pRWltZV1lbWlFZWFxZXVlfXVBbX1VRW1lYW19YUVpbW +FFYWVlZW1tbVVZdVlpZVVtdWFtcVV1ZWlVYXVxfXVhVX1hYXFtYWldUV1hWW1taVFJZVFlYVVtZU +FdZWVhUWFlYVVhYVFgcqrCuuKSqsriyuKyysqSyuq62tqquqrK4qLq0urKktLSqtrGKYplLmIvWw +BIA08EkClndUxpJ9TJiAKgrZ5EQEcopp6AMHphdHDU1vjgI0D3vA2ETssYpZ6KOG5mGPFpyJOFg3 +xTtSNcM5PmiKb6BuKuoIBZUksugpIgpcJJQqtmKV2B/essRDUrnyK2NkMQscB0BbN06ALMM4FkPS +llAvnAL+KLxcnkngZVsNONOPEw96YeJAfIjn8B1ew214DcfhNzyHB8EQcSchJn6AyABvwOTE4bQU +oJB4gjkYrwDLQkCKDVQJeABj4iEZJmTisAOPaiCYDwhDDVMB8KBhbKwEDBFLAeTQ8BJLSr8mSSr/ +Yo14Xi4hBF/BQv8FQIqs+eJKWiejD0zPRR6gmog7QmiCdYzwVNRBKlo5BHE0cgjjpyJsZydiENJM +Qx4vLgdhb2Aa9tCBaagDh6dYh6smDylndwjo8GtjHTOfAaZw/ZhIhwfjGBqChDRW4HdkWXxCggQc +C8kAn/ph4lA0SJwJhogbZXm40EsOL+I/vIgfcaQeKE5DcPCC2M2QJbQ38F+hAn8yasCNaBRwIc7E +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 +oCQNjTQGKKDGwTHUplKAo/rmQxQFZxKjtfVodPYNVRHDuD6UOTwAXRJZwGhp4Po9h4XVbx/+MDYH +ALfdu9+4/5GZnrSiMBQYXHduBF3M7Do6NEWCeFO+dNSWpqgV80xD7ypIj4tqyRjoUu7ANXodg6bZ +YG8XQxtngXzFdHpzKsAn0NBxFOQ1vQBhylz7zOSbojA2BlOy6GANJPqgkwGWUbrtKp6np4oarXIw +SUE8gpC9YNaIOdYHclFoGNP1ZyAodrNJpuK3qTZhmpfxSTD26e9dlnDLuPf/ia8Qrf7WNUFruosu +cER5x5K8JwhODqCNGLGUQJWG3ykKei73iMJwYsvqoXDWrIkHDmSa0lfjWJA27OL8kOxEHFgYmK// +8air3g2id4SBDBaIG95ECHoUJTDvjz+9DgkJY9YIRS8UgoiKfuZIyJNH2CQEV7AQsKQCvRc/znVk +kfTc7csxZBDUZYUhxK5oAWrx6xQwLVxF3q4SxCP9u8nBa+Qvut1HHrap7h8fwvSQLrK5ZDvsO2OK +Wiqmpo+9zizEMSMImjMhShf6tHtwSMwUh7Isb9tVxfaWLHH0wgjqdulhmHEAay+RLofs/r7mB6tq +4gQ+sdQFcjwEj3DcZ8ybgjV2JV4smKN4INfIkbyRBwAA7Ad8Z3gHZ38H/3CKQaZf3r3e9ZcYqPut +vFZ86LKrF074/WYWY05TxvO4IYhg1sijSbsMVDU7dil7wi7qDeDDNOwJAHQKqDJhZGM5MDU1MC1l +Y2UwLTQxMzctOTFmNC0xN2M0MTVmZWI2ZWVkNTliODUwZC01NjBlLTQzNjgtYmE3NS1iODYyZTBm +YmQ3NDQgNjM4LjI1MjM3MjNkZTBiNTAtYWQ2MS00NzVmLWI0MTYtNDk3NDMwYmExZjgwOTI0OWEz +OTUtNDBiYi00YjVhLTkxZDMtYmMzM2NhNDlhMGUyMy40NjEyNTUwMTMuIEEFyyEiPK/2b5795nSQ +BlCtZhpYq5HmeaC5I+e3mao5IrTNqQTfThDoBqQNOeCvwLpQOYMQgljDWOean5oxmIYH3NoN2gWy +JmrHSno0ph88+OW3c/SY4ADufA/sOhk27tQGjjVXgOc3pyk8mDWj8d9EBOoGFqYB8gMLp2HQf3PP +ES6BCPTmG1hLj9b0g5cK0QU2dIwAxDttMTgzZTQzZjg0LTRmY2QtNDQ1Mi04ZTNmLThkYTE3ZWNi +NjIzODJlZGI4NjVkLTg1M2MtNDk4YS1hZjMyLWE2NzZlMWUzOWZlNm1sMTBfU1ZHRmlsdGVyDS8g +Og0vWE1MTm9kZSA6DShmeG1sbm9kZS1ub2RlbmFtdmFsdTEgL0ludHR5cC9BcnJheWVUdXJidWxl +bmM7Y2hpbGRyZW4vcmVzdWx0KHR1cmIyYXR0cmlidXRlOyAsc3RpdGNoVGlsZXMobm9TYmFzZUZy +ZXF1ZW5jeTAuMDVudW1PY3RhdjJ0ZmVDb21wb3NpdG9wZXJhdG9yKGluaW5Tb3VyY2VHcmFwaGlj +eDAleGgxMHl3d2lkKUFJX19pZG9iamVjdC9EZWYgOzRmcmFjdGFsTm9pczRHYXVzc2lhbkJsdTFi +MmREZXZpZmVPZmZzZW9kZGRTcGVjdWxhckxpZ2h0aW5nUG9pbnRMLTUwMC16LTJ6c3BlY091c3Vy +ZmFjZXR5bGwtY29sb3I6d2hFeHBvbmVudCgxQ29uc3RhbGl0UGFpYXJpdGhtZXRrazRrM2szMTAx +MjEyTWVyZ05vZC0yMTR5NEJldmVsU2hhZG93TW9ycGhvbG9neWFkaWxhcmFkaXUxLmJibmItZG5i +Mm41RGlzcGxhY2VtZW50TWFwKGJuczN4Q2hhbm5lbFNlbGVjUnlBQ29sb3JNYXRyaTQ0MW1hbmlt +YWNjdW11KG5vbmNhbGNNKGxpbmVhZDVmcm9tdG81dG9yZXN0YXJhbHdheWZpbGxmcmVlemVOZGRp +dHJlYmVnMHM1NTRuY2M4Y2NjY2NjYzhjY2MxY2NjbmIoLTU0MUNvb2xCRF82NmVyRXJvZDY2NF8o +N3JlcGVhdEQoaW5kZWZpbnNwbGkxcmVtb3ZSMSAxOzIwIDE1OzIwMCAyMDA7IDE1IDIwOzEgMSBj +blBpeGVsUGxheTUwIDU7MjAgMjA7RGlmZnVzZTV5ZWxsb3c7Z3JlZW47Ymx1ZTtpbmRpZ287dmlv +bGV0O3JlZDtvcmFuRGlhemltdWVsZXY2ZDExbDFyZWQ1MDEwMTAxMjJucmVkNjg4LTEzNDIwLjAu +MTVudGE4eDU0ZGRvbkZsb29mbG9vZGJsYWNrOyBvcGFjaXR5OnNDbjM1bjFuMDEwMUdyYXkoME94 +LUNvbXBCbHVyVDFuZW50VHJhbnNmRnVuY3RhYmxlVjJGdW5jRy43IDBCMUNvbXBYZmVyRmlyZUEt +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 +yoYSYWyu/bml55/3q1drZU967z91a298mv+p36cST3pv41sf9/QqrRW9Wvzu9srb1/btee2N9336 +W0rrfSqr7TstlfZ6zu/Z1htxvZS6W+yXfq799KesPq3nrrdnz27aM/u8uFaLZb3Y2vpNcX3s9Nqv +Lqm999/OpvhK/JTOt1i6Z4lL2CJh062X0306FRK7ocRtG4ybsSlsUiWn9XO/19u1Ttw/s8+Z7Xe0 +Xj3TOT3T+dPeOyfG7/Lb4n5vb/r/OMvrf2HZljCY+FQIQ40+0WODNK5B6Am/CyhPXEACQBXlUPo8 +ksbE5XKII230eSKtE3oFKrHBLUaEubMdZ/fOVOkz7Y2Ztr1WnJ9v7m7b104rvWNj1IUpDFvRypst +m2u7xBZVwtg6dVFYxqirukVhLa9FXfZWijOV1sJKVdro1U2X2KcBvJHJ+zJzUgy99sZ5LaZ+3YrT +rej3NmUR26c77XyiU9knZpe0Unc8661z1kprpZROCouzUqXu/+7/xtSKl/Y/VZp39pzus7tpd8/p +Ptv7WrHndJ+2r511zlox184PrdKttx/pR2tZirHttForYivSbN1OK1KLwqJbkVbbdlZKq62YKt1W +Sa14q72RUq9uRbditZXCYrWitaxYKYtIrb3RRnspLForWstaF8u2k9b67pfW29k2nRfjx3nmSRvX +tvn+W6+Sjjht22hhlnGPc0ZMo/XGqCtaCrOyW6X8lkVh2aOVtxStx/xUJvYV/y0bf8Z/6or/0b4V +/+NP6Vb8+fktCrOokv0ffdkVw22kfdeM2GPbSOtIKNJIn1bdKcWOrbVivyi2WxYX2y/3imXH7NRG +A4XBxKZITTEiTLy4vhW/9InXWvHfik6FYKLHzlZsp0IYp9fG9rasditeK/q0nF6bc5Y5d2zPH31S +pXijTyoTm0RduS/NFBavFT/+jDV6T4y6onvEb8Wcs2x/mePPeHHG/ZZFYfipUnS38FMhsdupU8On +LfBAnReGJ0z4eSYGmtH2cUK6beM8GVRRT19WbPP/a4y2E0fjQlmnmd6gClTheqdnK5vC/DaW7hSW +JbVKLm2sT2UfTPvSGe3n2HndZRKd6kAVqAJVoApUgSpQBapAFagCVaAKVIEqUAWqQBWoAlWgCgNV +oIoqgSpLjT6xY1MbFIm65sz9nmVX6RTW1BWfzpb1Y63Us7TR5pY02r+19sunLvoR1w== + + + a+O0KIy6flo+rfrWpC2xW9e95XULXytSi7rifKvSOuV9q8ppu+WlRNVl9VinFa1Tor6e+1rZk8I8 +Y2tFmu+UXq+kluxpac4yP4VFay1qRZy/WtHWWSW1dWaKUdfPWiX9+ZhK6j+zpE6JfHZu2Y4prFJY +tPOvdLcsLKsV/eW/FbOVZbtFierPt6xb863rlpyfabfst96isHixW5mtOC2lsr71VLYV8bQidesW +VaKyT/y+1uXMjTHOt+df6qSF2+ctyDZxNLpMKM4LlRpQn7hUo05TeQH+siudsy3F1Ge2uNbG1t6v +ddr2iafbjCv+mfPEtun8Seekd15v+nY+dgsnWuv0J/bum3H+vtUpre304pmpZ3rrbFp95rYV51sp +rbmdTkzbsXv3pG5tZ0vttH2vWzypvRNP2TRX+28tmOjXwokT//RJ37bFNTv+TOvjiW/TS7s6bTtz +nfXxvG0vtmBizhZOrD5l56+12m87H9OMf17aN7eV7RbTpn97VtkxX3qd0q7uFkyk0y2cOKvTKmtt +bDHt6rP+rX3dfWZbL85z4pw74n/6T2vOc16Mc+c87cVPH+N//znnxHTijO2d/W/n4745v1fabm32 +jC/+ip22vbbmPOdn92zBxLZwIq4+61vc1OfFczbuO7N998du3WmlmE7qtfp0bNu7vT6dPqn/9KYY +27fU7eeMsb1N53QLJlZq4cRvl33zxD8rxvi/2+K2+OettSvF2fPnWpvWSm+3WzCxP/fTmSnu/plx +u/1ZLaUWTrT0uuzYten0TNv+bX8672w8K7VZNr233nmz54yxWzBxuv23YKJft3Qmt7oFE7O1862l +95v67HwtxV7/Vir71kq9540Xvzud+O/3Z3rl/fn21mrBRNqNc1PZ8T6tbX++xXXm+e24G9OeGP/s +nC19t9/ubZ9ar9Pefvu3qcWSXgsmOq7z+yXurvbmLCdt/+x5WkuvtWAizm7hxKZ+J+5uWut075mz +7evWM664zu5K/7q722o9+317MXY551s48X/mLPHfd/wZY59Oc7Vgor1ecU8rO1771tb6F+dbqa2W +VkxnTwsmXuoWTrz0LZ1Jlte7cfv9b4uz7Jj98e3uad9O/+6WnS2c6PT63/737qaztsUZ03/P+cqO +dlowEb+FE+/8Ot8942x/fleMu5t+xu10fvZ77cWyv+u3zd+VWjAxTwsnzuyWzqRpvvg//7Utu2Ja +MX18P9Nr570333/8d17P2HoWdlpIZlGrY9nxbWe37fdPHObSn9X2V3zxxDhrcFlLq308+9Z3iS1u +7LXTtI/zn91xtW87/tan9dKet9aaH7vtkdaJGE5nMqGyjwATEQZFBeATwtDCUOMyjFGnAeWJS0Vd +IAi5U0bSMh6hKdY4gMdx4qeFp4v511brjb9eSm21+D97z/k504pztt65PUuvFnv+KaXH9ogU2oKN +Avw0jqh9HknDxFGXmRhoovWOC22ZiROB2UVFW/CBIlFmCsDniYS+bFQpBwzmwdDAUzR5X2bWfwwm +eqay47/Fb6fsSwiSvPt1yrbCLkFp40oiYYYhEmYYEV9cb9uufnG22TruSy+VjbHX3JnWOy+mtlbZ +noa2YAszTuuEdJdMOUSGSRQQ40MkaZ0EoQtOhXKIDPXLOEBQ6y7AUaeZtMynhVop2zKdvSMSsklE +reR9Itetc+L6ld6mjefLjvT+u/+7rZ8ptbZttZjGenPbiaetU3aVPWXn+tUbv//tmbH/pXPKrthO +Kme19XFnenu254krtvPil/PzvD49z8fUXvr/9NavlzqutOIrP9N657Tu/dQ7R5rttfavtV7ppD6/ +5pvne32cKXX79e+3ndNvV6/WI0X0rxdfi6/PS7+zv51OnepoBaJ24jDulgyTLYANoPkCoCEy7ePc +wRvcdbp0UybBT+s+74q3QXi6mIw2sJsIN41KZAhFGomkidqCDYvctqlEBtOWSY+d13XeFp5EGgNN +haIEjDqNw4xGF522QKOBG5RDZDBFBNR6tdKzrfZK94gdLzhu23Dctgm306jzrvDLMCqREhAnkYoP +le+Ce23E+0KPaAMzzIgoCz1caAM3jkrstodY0RZsoUgrZQUqkcHDAT3EbgCvq6hQYO4Zp61RwyYU +g8eOHSuVjh0rN1biTyiGCcUACjNuA7Idq+cCNfiy0IZpXAhuHwY0cYkzVtlxzio70tgTimFCMbyL +gDl2jjXMuE3tOLs9+oRimFAyMlRKmeaJnyYSZhoWK9oppPM0IrgQZpcIePowI24TdRpGtCKXeaIv +E7liRQQUEZ08jTDjNlGGpljbJ5QVGSqj7uR1ogxNccZKZPi00XcRPy0k6zKLKAKePkykLrot5MRh +YM+1OohZGKUGiNRSDT6yQczCKo1V3ovr9JxlXz62Tq/XOp3df7GVTXXAk8gjgTLtu4QMNI2/bi+u +jnHXt0p0zqazJ52z6bxyLl3M7a6y4vvzZ7bqW9VfUgqT7Z+tKu3Tx7VaOd+K86WHstD6Mkwo0/iu +V85Y6Vt5RXfiv95PleqV9EXf1lrpjykRzVRWt7CFffTO+OIqvSTbLSzSx06VppxWxF8xiVGnStJa +iyp1pNhW6ZRoOoXlnKX9t+hL9+i00o/Z2pY2v6zTstOisLZWdiu/dR2r8n/K+/Hzv/TZEjt1ucSy +rSk90kxd9qzyvb39y67oidRM85SXxsf5ykrzuzWhLrez/+Wdcj52ianrfVbs1PXWmlb0SV1uTY9e +5fvMuGWmrvkuaZyz6ZTU5cdvizbO1FZqRZytl9RaS+W0Ys2dXb7lVGluqMtt/Sux5d8v34o00nov +9f+XN0q38sq39nJZY77RShqf2q+y5fXuOWX2SGt9Sl2R0n+ZpfWZ5f2uVVqqlPPFLuu9n+MGCaP1 +RlpffvQ7e94qH1RtcKAKVHGzX16n1sqbva+8L6c7fnldvlvTVpldTite2vPe+BbFRZxxfeoup+XX +nQYODmIsYBDgEPAsKhXdKUFHJNjgOMIByME/FiCCB6lmwGZD4+PiIjnAIV1fR3vjBIbuiqqEOCIu +GC5JHUDCpqwTVEGSs4+CxLpdJancrpKAmDgUCfaxcJCATI7TyRBImCxI+nbVdzMJEo8RyEFSURMH +GRSJgQQiDhKvHxYkDhdFQdJwu0oS3kyCxOsowCC5F0VB0hdFQUKZoAoSAyKQg+Ri8w6SAwsVS/IM +3UBBAJHoEkWFoFgeWum3aEuS+Vg4SCrK83CiSCQJhEFiyhywJAUWKpYEQoooEoSJAYrksnkHSSij +syQl8L8PxEKMTckQQqH4DrcZaQwzNQ/ejL9wQOpfQBCCxQXiQihQsfDAEK8oi48CDAKVBQXM9Egm +KjICYBYUzQnzaRmEBgtBwSAVghJBASIxQ5EISkbCBKkk9NngyA8PUcUKGaDpivUQ3sBoEpG5UCgA +gjkgLwE0f0BCgAESFazIijJ5KgSFocNS6Q0TMki4kY1BUkcgB4nmg8NBgkkgDBKPFFEk2MKWZOKD +w0FCv49BImI7Fso/ZAygb0GpNILJ6S8X9WPiOb6Lke4QRhTXNIB0KggkLPKKKkkkI33isAcCDdmm +MDc6MAvFglQIyqinANfbgFgDDJSsAYsnxswECRIZgoBHYdQQIBcRdCRTISiZDoVRL1hQKl0JcURQ +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 +bnGL2wRlixvNY3XcJ+Cg4xA+b+HmQYbHPWjILBwFlpkkIFAwWoIicDdBShV9ij1KYNw2FkCmb2Zn +Fj4qFcg0j4qUaUqeSmQi0ET1N4UvxqHi5n2Eoi+ekBYAllHqKB+haIZWJm6eS9y6ipD0he5GQP6g +aEbhw2ncs6lxMQsYtwsZpgSKKg+ibhmBAJZMkc0UZdXkMTJW+mJPIWoOxHowlYCAAE4ECiKVT8O3 +mQIFkUrcOFSm4zaRXDgzioeRDIDTIltFEHC0Twfh8QCrF/ipvDDCD+g9VKGWMVSMRUAiwIICCFFB +yFxIT6MJEYWHBlilfVLWirguTq0l8Y7b7AG1abAXAx3lgbvgTCRxuxP0UFnkcTOJQ8eJKEIL96Gv +jtNMHDrOhNCxIKhmIP+IhwuOOAaLywgoJjBuBQ2jPHeBcYEE3aj0SU7yQe7OSF7xOJELECZEwano +2UNWIbDwWD4hwSAyTNxoD4KHy6gncQvFbQPj4UAQS7Wl+HTc5EINgaNM7dOQEjYNngTfqKDfwJ4c +JxQ4AY09V/fp2GVjupFmnm7tnRJj+tYpvp2ttJduHEfu2dnnxNRzdJ70Uoff631/XowlzdRz0G5L +6cyfcct56cX+fbHLm6mXM8Zuq8tqaf2+706p57j0L+4scaUbafb3nbPOWan/xN0Y4/mU9rxva534 +bi9a532/tV6Z88V1dr1/c77veTp11IszfnrvxP82W/mzKf1L8ZyVdrazYluf0mlnrV4r9Smb1ov7 +ev0qba4ezlVeWh3f16+dNbe9M3emV+a2MMf1624fX4o9TGungs78GGP5dl73bF92xdVim6nTaq/X +mmetG8lx7Td+69R+y6b1Wktz55642pf/7k+r/M7Uf17sVmKvG8mR+yd+Sen1tjT7zyvzvdLOiy29 ++D3X7yzvnbZSO7H8n5dOSm29PeXbeS+mnbFjnGl/lfn/5um5c/2Zp8Xv8j693Y5xbc+BJ661f1aJ +56x/qcwU11np7c+0ZZ7Tc9h6s30qu+L/DLNN67V/pVOca5bT4v5toxLGMIYxjGEM4/9/rZRmb5lz +dXzN9LrtbOXNtXH3pU/xtLS/v97pluLG9Fp3K9/a++3U/lfpXe3snO/Es96J8b3YWultN5bjs89L +3W3bS6vb6Vh6W8fT7PZmbGdtaTHN3jV/bitr22xnpvVr04un2+3loO23dsY+b0tcq+fAndtefH9i +KrNbp3XmO92ppE0903wvxhvJ4V0/2695fn68wRz23eLqOSrOuWfGtG0YwxjGMIYxjGFkOWidk3a9 +tVbPcak3rVZaSx2eZa3Voz0rfVsl/WznnbNpnk2rz3/7+GKf2d/il2/r41vnzT5r5+vVSnwptZ/b +XjunU4e1uFba/bNKbKvnmJS+Xyr/r3ul1l3aWz0Hzdbalo7p9pq49mfPMt/qOWbfSt2z41onprht +04olxbctnflJtmK31HM4rvZS+fQ3GK5Z3lor/uzW0jCGMYxhDOMG8zAgLHBC8HQCR2FCQRhSAE8+ +P0/61H7Oful9pxbjOi9mOWr1mWudtF6ZZ3XM2hPn2p/nvT+rw+t0+nnep00xvtX652u/biSH46/Z +6dss86wbyfEZu81/u+uUs59e+jhntxLPp279ykqp58Buc/WXs1aH55ndZtzzNrX/T6e8tG4sB3bv +aTGltm+u9O/1jCduWmu1tVaca/VKPUe2M7vLptVDD+joLYPkoLhjmyA52tHV0Y6NIsMTum+YAdDi +FrePkiokKg+br6Sn0QAiixUnZLIh0EFKzDwOl4zC5wIBM5spzP9Xff9LL24ft58VMwvN96/j9snP +s3xfWz6LV6H4R4nbqfJxRqAA2sO+xS0Wi0WquIHouSgUFTcQK3FzVShfqmTAEph1JpmYjJOBVCQo +HDgUl18m5uyhi9sTrCS1kAZRMd0MaREvGVCb/0oEUgLklk7Ayv1BIDI9AQiPY8QIXqDJBXhCob4a +0OrQ5xMQA2UwAQEzlScf8mQgnI7CEAByAjQHkClBo6BFfAvEUHFCDPe7aIA8biYJkMctbpEPyeKV +L0Z5rsEz6hdDhIMgC5Dpq6VmE67B4Bn1zIuU/LsRF3yYIBF0cfMeqtAWt40AtIjvIFCbr1giFC0L +QAQcyMrCAUkQgCQMQAsByIxbRBfULpTkTS4V3YUqputkkooOVUxXaQWYhKtWf3LSMgDjw1hYWFwj +IXYKw0/3ESxbmQIOurh9C51R1QQsdK1fgNj4TA4sEz4MZYHwmbzL8hCC66SBfK8HE14zcFIqG4TV +hPKVuq87DRo3DYK4cRpKqg2B6HIA+pgOWFbB49CxsBoCPfMy0jxkfBw6Na7VwpRAjoKg9aMKmoVb +0JSoRVY1edBjpc8hQTJoZDLz0siA1UUTsXgmGRSICuA0eGynihEIdJnOLJEcBBYuMixAg0po8bgV +jAIw+rVggfD1xrWguRjUWk3rNkrgvUxAfmBAu0mjmNrnwoqIW9xKWeRxAq8LCqeJ0EKT0f1c7oFI +lp80oYObB5DpM0Xc5QEmHg/GDYa6jFrhIaPgH1z1klQbMwH8GVio0CB8JtVm/sIL9FBbbXQoHfvG +zSKZ6GbC6co0OCqUvpOE7KTRaD0ONAIX1OqIDC0O0gAx7x1OF3H7XGhE3DhUpuMWc4gbWKL9SbI6 +zgBVsnDyATLhEDzscbIK+1VoaGjkJMmP2+lidNJIwFgCNwUY0zd5gSzHaD0eHD0yBxqOISXqWkGq +cZtpZGwaVJEZEzQl0EPCaHWsscs7EE34nBsrfZE/eGlKJYduSgym51Op083MZnGL2zfIuE0DD3uc +QMBBFxHAZeEkk7hFOk8NgQGp/lRBs/AYzAv5DCUx+RwVSh+m4CTqAo2QqD9JpOK04lg8bnGLAdvH +wBNjjFvLYqURgJiL5mjNYjVaa2bhaFmsNFq1laMFgBXNYpu1XhermYLnkcIYxjCGMYzUUk+559ry +zsYYN33p+HP93E2r55yt/fk2f37anR2Xvn9feutTeZt6DvsUX2vdqXXQauek9O2teMpM/17vjGm/ +9c5X4vxeJ30qP0/P4dhW68D+/7Pi7jslxdbzvLcxpRb79May8ZwUY3mpnZnaOt8nfetV1reOv/Sz +ldS+20yt15butuektKd9+/ennLf6/SpvW0d1/65W5js9B3XvOTOduObcTzFu6pheefH0HPQ6tf/S +tt1eDr+X0mo7W5/S8/Qctimltsp3Sz3/xNlWLGfTz1nSacMYxjCG0Tt/rrSztDlfp7POfDF+em+t +lDq2NNfG+a/s23jWnp4tvhdfn//5Uge10u9tXOv1O6etMtufFv+dt6XPmWlXS/va7HLmWZ9aSXN1 +XNs9sbR1evn9vleH0/v9dOJ6r8R01kmzrLluL9wvK825273aW2XGudbcXmfNk9r8mN6bZfbpOWq9 +9doqKa355sbTw48tzpR+vtdpvpXSfK91iuul71bin//+ts6ab5Z04jvrzPhSl5POimlLt/Pev+7f +Ntfa3hLPusEy9UltxV/DGMYwhjGMYQyj9Upr27cV98SN86RtvU78tPu+xe4/vzO9ubo79nq7uk/P +9K+kd3q11knnrBXja6ltK23f7eXoWt9604kt/ffOLa3jtrbWia/LxjZTTOdfmfur9/uljoyxtdIf +T7c540ul+71uu+KJM64by1Hv/ezX0m6XmM72+/PdZe3ruDhfn5V2buuebXX8/Wkf53ylvf6Ob6We +rexst5fja7X4vu1J88a63bPO252v/Xd5sXW4rfVpT5+zylyn53N6nrXKia2j+r3uVV6LreM7+x/L +ii2u1NJ577Uwx2Oabb3U3eJ6uz+HMYxhDKNbb1y/731KvauVtuY77bxNcZ2O57X/+M7aN/djmat/ +255dHRN7Z+y4Tjnr9NxO2rZiarvtxPlWz1Ria7eX42Z887RPu9KN5ahYUjrbtvyL6XR7bZ31Pb+V +9VoHrvQ2tj9n5+rdbqec12Ls2O2d80r707uV2klzltbajdW5LW6v0i2+c9Zpr73WG2fs/+0v277n +sG27P+f+9p7u3/hajO2t0tr37sS5G+Ovk2b596+dFeNq781ZNn7Pkb1Wij1XSfF7OHvOs94859OM +r8y0rZ21b9swhjGMYQxjGMPY2Zv4rX2vO/aMvb78z3d6vvNi/NjaOzOV9rvp/faKc/0VbBYzTebj +i+W0/9Pfel8uLQ0BKGzEEFoT4GReLnZmfLm0XhYZqxqrhXC5XKweT3svldVz7e6mktLpObKDVjpd +Pp1exY7d7ctc7/Zy3Glp9af40o3lsO9f7ZV15nfcvvV+vvln7jyl289OJ6VT+s/Pt9v23F4Oime2 +tt5a75XXf1K3edqNRe/T+tdKr7TtbEprdXzf2S5xtjRbb9z3JaXVcTs7zt7Zr+fw2/MztdX6S+s5 +d3WKu/GlVv60tdp5pa3f1158L83W4vy1v3qOx7Va+//Vcb9rzk+pbdqY+qVT+qzby+HTXq+5/99z +5M//+eI76wZzOJ393fTp9X/bsymWlN4w0lnrRZGxClFgq9nqdLm0NFauhBYALkgCqxnFauPgtbqo +XWQU1GarWgJFhqd1ccLZ2llro9pp4zmz44sAYLBiL07IP+PP1z9bmZq1ahktzuXSomlcvF6ey+Vi +Ra/jjVVx9a6yYuq4dGb8U35vrFtn+6z2Su9qnVLL8nt9urvXpjPbe6f9jF+6rY5Mq2dq8ddvWemc +l2I53y2etumtVOJbK2EMYxjDGMYwhvEVRlgYwxjGMIYxjGEMYxjDCLu3MZ349XJMfKf7Y/yVzqbW +rzfGn2W/dcxbZ/0qr79j+7St4+JaZ/vseVtez+25/mzal1o5m+aeE2NK/85ccX08sw== + + + 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 +sZWZn4SSBvdvaZYgKg== + + + diff --git a/docs/imgs/logo.png b/docs/imgs/logo.png index 3048e8ce67f2a77e0e4534d110885b106cf67152..08943b5accaaddbf584857f8e146cd16a9ab839a 100644 GIT binary patch literal 26755 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

    *^n#=h3)8pV1#e^0W*HlyjTvDK!wV_ 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 literal 50574 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 From f6be42b71d340aa8df34d54c06b3fccb4c7452b4 Mon Sep 17 00:00:00 2001 From: Anais Urlichs <33576047+AnaisUrlichs@users.noreply.github.com> Date: Tue, 23 Jan 2024 08:29:09 +0000 Subject: [PATCH 099/108] docs: Update troubleshooting guide with image not found error (#5983) Signed-off-by: AnaisUrlichs Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/references/troubleshooting.md | 55 +++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/docs/references/troubleshooting.md b/docs/docs/references/troubleshooting.md index 9fc67f8caf4c..fcdb97bb8a61 100644 --- a/docs/docs/references/troubleshooting.md +++ b/docs/docs/references/troubleshooting.md @@ -12,6 +12,61 @@ Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as `--timeout 15m`. +### Unable to initialize an image scanner + +!!! error + ```bash + $ trivy image ... + ... + 2024-01-19T08:15:33.288Z FATAL image scan error: scan error: unable to initialize a scanner: unable to initialize an image scanner: 4 errors occurred: + * docker error: unable to inspect the image (ContainerImageName): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? + * containerd error: containerd socket not found: /run/containerd/containerd.sock + * podman error: unable to initialize Podman client: no podman socket found: stat podman/podman.sock: no such file or directory + * remote error: GET https://index.docker.io/v2/ContainerImageName: MANIFEST_UNKNOWN: manifest unknown; unknown tag=0.1 + ``` + +It means Trivy is unable to find the container image in the following places: + +* Docker Engine +* containerd +* Podman +* A remote registry + +Please see error messages for details of each error. + +Common mistakes include the following, depending on where you are pulling images from: + +#### Common +- Typos in the image name + - Common mistake :) +- Forgetting to specify the registry + - By default, it is considered to be Docker Hub ( `index.docker.io` ). + +#### Docker Engine +- Incorrect Docker host + - If the Docker daemon's socket path is not `/var/run/docker.sock`, you need to specify the `--docker-host` flag or the `DOCKER_HOST` environment variable. + The same applies when using TCP; you must specify the correct host address. + +#### containerd +- Incorrect containerd address + - If you are using a non-default path, you need to specify the `CONTAINERD_ADDRESS` environment variable. + Please refer to [this documentation](../target/container_image.md#containerd). +- Incorrect namespace + - If you are using a non-default namespace, you need to specify the `CONTAINERD_NAMESPACE` environment variable. + Please refer to [this documentation](../target/container_image.md#containerd). + - +#### Podman +- Podman socket configuration + - You need to enable the Podman socket. Please refer to [this documentation](../target/container_image.md#podman). + +#### Container Registry +- Unauthenticated + - If you are using a private container registry, you need to authenticate. Please refer to [this documentation](../advanced/private-registries/index.md). +- Using a proxy + - If you are using a proxy within your network, you need to correctly set the `HTTP_PROXY`, `HTTPS_PROXY`, etc., environment variables. +- Use of a self-signed certificate in the registry + - Because certificate verification will fail, you need to either trust that certificate or use the `--insecure` flag (not recommended in production). + ### Certification !!! error From fb36c4ed09efc3fc241d02713c4cc864b6c6a2c8 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:59:48 +0600 Subject: [PATCH 100/108] refactor(sbom): use new `metadata.tools` struct for CycloneDX (#5981) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/supply-chain/sbom.md | 17 ++-- go.mod | 2 +- go.sum | 4 +- .../testdata/conda-cyclonedx.json.golden | 17 ++-- ...fluentd-multiple-lockfiles.cdx.json.golden | 17 ++-- .../testdata/pom-cyclonedx.json.golden | 17 ++-- pkg/fanal/analyzer/sbom/testdata/cdx.json | 17 ++-- pkg/fanal/artifact/sbom/testdata/bom.json | 17 ++-- .../artifact/sbom/testdata/os-only-bom.json | 17 ++-- pkg/rekortest/server.go | 26 ++++--- pkg/sbom/cyclonedx/core/cyclonedx.go | 24 ++++-- pkg/sbom/cyclonedx/core/cyclonedx_test.go | 13 ++-- pkg/sbom/cyclonedx/marshal_test.go | 78 ++++++++++++------- pkg/sbom/cyclonedx/testdata/happy/bom.json | 17 ++-- .../happy/empty-metadata-component-bom.json | 17 ++-- .../testdata/happy/group-in-name.json | 17 ++-- .../happy/independent-library-bom.json | 17 ++-- .../testdata/happy/infinite-loop-bom.json | 17 ++-- pkg/sbom/cyclonedx/testdata/happy/kbom.json | 17 ++-- .../cyclonedx/testdata/happy/os-only-bom.json | 17 ++-- .../testdata/happy/unrelated-bom.json | 17 ++-- .../cyclonedx/testdata/sad/invalid-purl.json | 17 ++-- 22 files changed, 253 insertions(+), 166 deletions(-) diff --git a/docs/docs/supply-chain/sbom.md b/docs/docs/supply-chain/sbom.md index 7091eb6ed2ba..cb3a68c9d8f3 100644 --- a/docs/docs/supply-chain/sbom.md +++ b/docs/docs/supply-chain/sbom.md @@ -217,13 +217,16 @@ $ cat result.json | jq . "version": 1, "metadata": { "timestamp": "2022-02-22T15:11:40.270597Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64", "type": "container", diff --git a/go.mod b/go.mod index 877dfd73665b..420f5e748bde 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/BurntSushi/toml v1.3.2 - github.com/CycloneDX/cyclonedx-go v0.7.2 + github.com/CycloneDX/cyclonedx-go v0.8.0 github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible github.com/Masterminds/sprig/v3 v3.2.3 github.com/NYTimes/gziphandler v1.1.1 diff --git a/go.sum b/go.sum index 4f43615c6d4e..6364a132f996 100644 --- a/go.sum +++ b/go.sum @@ -237,8 +237,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBIdfux8gnQ= -github.com/CycloneDX/cyclonedx-go v0.7.2/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= +github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= +github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= diff --git a/integration/testdata/conda-cyclonedx.json.golden b/integration/testdata/conda-cyclonedx.json.golden index e449defa008a..30e0321b52a5 100644 --- a/integration/testdata/conda-cyclonedx.json.golden +++ b/integration/testdata/conda-cyclonedx.json.golden @@ -6,13 +6,16 @@ "version": 1, "metadata": { "timestamp": "2021-08-25T12:20:30+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "3ff14136-e09f-4df9-80ea-000000000002", "type": "application", diff --git a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden index c3e5903d5b79..aab59a6cf47f 100644 --- a/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden +++ b/integration/testdata/fluentd-multiple-lockfiles.cdx.json.golden @@ -6,13 +6,16 @@ "version": 1, "metadata": { "timestamp": "2021-08-25T12:20:30+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "3ff14136-e09f-4df9-80ea-000000000002", "type": "container", diff --git a/integration/testdata/pom-cyclonedx.json.golden b/integration/testdata/pom-cyclonedx.json.golden index a77c75eb1f65..5487c239e2da 100644 --- a/integration/testdata/pom-cyclonedx.json.golden +++ b/integration/testdata/pom-cyclonedx.json.golden @@ -6,13 +6,16 @@ "version": 1, "metadata": { "timestamp": "2021-08-25T12:20:30+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "3ff14136-e09f-4df9-80ea-000000000002", "type": "application", diff --git a/pkg/fanal/analyzer/sbom/testdata/cdx.json b/pkg/fanal/analyzer/sbom/testdata/cdx.json index 639677780faf..a006bf7053e2 100644 --- a/pkg/fanal/analyzer/sbom/testdata/cdx.json +++ b/pkg/fanal/analyzer/sbom/testdata/cdx.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2023-06-01T13:10:23+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "0.41.0-80-g1c03982fe" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "0.41.0-80-g1c03982fe" + } + ] + }, "component": { "bom-ref": "pkg:oci/elasticsearch@sha256:d4b68b602eb3d92ea3256886761752ae1159dc01fd391f4c4a87ebf6ba9d3895?repository_url=index.docker.io%2Fbitnami%2Felasticsearch\u0026arch=arm64", "type": "container", diff --git a/pkg/fanal/artifact/sbom/testdata/bom.json b/pkg/fanal/artifact/sbom/testdata/bom.json index 2244d48334e2..f8fd55ea6add 100644 --- a/pkg/fanal/artifact/sbom/testdata/bom.json +++ b/pkg/fanal/artifact/sbom/testdata/bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "container", diff --git a/pkg/fanal/artifact/sbom/testdata/os-only-bom.json b/pkg/fanal/artifact/sbom/testdata/os-only-bom.json index 820057006668..837c16754211 100644 --- a/pkg/fanal/artifact/sbom/testdata/os-only-bom.json +++ b/pkg/fanal/artifact/sbom/testdata/os-only-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "container", diff --git a/pkg/rekortest/server.go b/pkg/rekortest/server.go index 72a9e6ef7c71..e5eb7dbd7858 100644 --- a/pkg/rekortest/server.go +++ b/pkg/rekortest/server.go @@ -54,11 +54,14 @@ var ( Version: 1, Metadata: &cyclonedx.Metadata{ Timestamp: "2022-09-15T13:53:49+00:00", - Tools: &[]cyclonedx.Tool{ - { - Vendor: "aquasecurity", - Name: "trivy", - Version: "dev", + Tools: &cyclonedx.ToolsChoice{ + Components: &[]cyclonedx.Component{ + { + Type: cyclonedx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cyclonedx.Component{ @@ -175,11 +178,14 @@ var ( Version: 1, Metadata: &cyclonedx.Metadata{ Timestamp: "2022-10-21T09:50:08+00:00", - Tools: &[]cyclonedx.Tool{ - { - Vendor: "aquasecurity", - Name: "trivy", - Version: "dev", + Tools: &cyclonedx.ToolsChoice{ + Components: &[]cyclonedx.Component{ + { + Type: cyclonedx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cyclonedx.Component{ diff --git a/pkg/sbom/cyclonedx/core/cyclonedx.go b/pkg/sbom/cyclonedx/core/cyclonedx.go index 7477a559262c..023e1c18d7b1 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx.go @@ -184,11 +184,14 @@ func (c *CycloneDX) BOMRef(component *Component) string { func (c *CycloneDX) Metadata(ctx context.Context) *cdx.Metadata { return &cdx.Metadata{ Timestamp: clock.Now(ctx).UTC().Format(timeLayout), - Tools: &[]cdx.Tool{ - { - Vendor: ToolVendor, - Name: ToolName, - Version: c.appVersion, + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Group: ToolVendor, + Name: ToolName, + Version: c.appVersion, + }, }, }, } @@ -313,11 +316,20 @@ func IsTrivySBOM(c *cdx.BOM) bool { return false } - for _, tool := range *c.Metadata.Tools { + for _, component := range lo.FromPtr(c.Metadata.Tools.Components) { + if component.Group == ToolVendor && component.Name == ToolName { + return true + } + } + + // Metadata.Tools array is deprecated (as of CycloneDX v1.5). We check this field for backward compatibility. + // cf. https://github.com/CycloneDX/cyclonedx-go/blob/b9654ae9b4705645152d20eb9872b5f3d73eac49/cyclonedx.go#L988 + for _, tool := range lo.FromPtr(c.Metadata.Tools.Tools) { if tool.Vendor == ToolVendor && tool.Name == ToolName { return true } } + return false } diff --git a/pkg/sbom/cyclonedx/core/cyclonedx_test.go b/pkg/sbom/cyclonedx/core/cyclonedx_test.go index 60ad12864520..87d5a589f9bf 100644 --- a/pkg/sbom/cyclonedx/core/cyclonedx_test.go +++ b/pkg/sbom/cyclonedx/core/cyclonedx_test.go @@ -182,11 +182,14 @@ func TestMarshaler_CoreComponent(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 9d1f2d33aab0..a016e5b1e20a 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -242,11 +242,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ @@ -874,11 +877,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ @@ -1255,11 +1261,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ @@ -1545,11 +1554,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ @@ -1728,11 +1740,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ @@ -1813,11 +1828,14 @@ func TestMarshaler_Marshal(t *testing.T) { Version: 1, Metadata: &cdx.Metadata{ Timestamp: "2021-08-25T12:20:30+00:00", - Tools: &[]cdx.Tool{ - { - Name: "trivy", - Vendor: "aquasecurity", - Version: "dev", + Tools: &cdx.ToolsChoice{ + Components: &[]cdx.Component{ + { + Type: cdx.ComponentTypeApplication, + Name: "trivy", + Group: "aquasecurity", + Version: "dev", + }, }, }, Component: &cdx.Component{ diff --git a/pkg/sbom/cyclonedx/testdata/happy/bom.json b/pkg/sbom/cyclonedx/testdata/happy/bom.json index ada1488b8cbc..a7a1a474b8bd 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "container", diff --git a/pkg/sbom/cyclonedx/testdata/happy/empty-metadata-component-bom.json b/pkg/sbom/cyclonedx/testdata/happy/empty-metadata-component-bom.json index 63109c739206..2fb29d2647af 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/empty-metadata-component-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/empty-metadata-component-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ] + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + } }, "dependencies": [] } \ No newline at end of file diff --git a/pkg/sbom/cyclonedx/testdata/happy/group-in-name.json b/pkg/sbom/cyclonedx/testdata/happy/group-in-name.json index e42790df19ca..f7e7e44dc437 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/group-in-name.json +++ b/pkg/sbom/cyclonedx/testdata/happy/group-in-name.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2023-06-20T04:32:10+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "0.42.1" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "b0ae8323-eb7b-4be5-bc5c-4849fd795ec0", "type": "application", diff --git a/pkg/sbom/cyclonedx/testdata/happy/independent-library-bom.json b/pkg/sbom/cyclonedx/testdata/happy/independent-library-bom.json index 0a1b337820c2..164eed844166 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/independent-library-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/independent-library-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "application", diff --git a/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json b/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json index b3d039379709..d1080b4de92a 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/infinite-loop-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2023-04-06T05:41:44+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "pkg:oci/ubuntu@sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21?repository_url=index.docker.io%2Flibrary%2Fubuntu\u0026arch=amd64", "type": "container", diff --git a/pkg/sbom/cyclonedx/testdata/happy/kbom.json b/pkg/sbom/cyclonedx/testdata/happy/kbom.json index a843dbdfd212..3219cf7efaf6 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/kbom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/kbom.json @@ -6,13 +6,16 @@ "version": 1, "metadata": { "timestamp": "2023-09-29T06:25:00+00:00", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "0.45.1-15-g7bbd0d097" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "pkg:k8s/k8s.io%2Fkubernetes@1.27.4", "type": "platform", diff --git a/pkg/sbom/cyclonedx/testdata/happy/os-only-bom.json b/pkg/sbom/cyclonedx/testdata/happy/os-only-bom.json index 820057006668..837c16754211 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/os-only-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/os-only-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "container", diff --git a/pkg/sbom/cyclonedx/testdata/happy/unrelated-bom.json b/pkg/sbom/cyclonedx/testdata/happy/unrelated-bom.json index 5d9231de109d..aecf8e05abfb 100644 --- a/pkg/sbom/cyclonedx/testdata/happy/unrelated-bom.json +++ b/pkg/sbom/cyclonedx/testdata/happy/unrelated-bom.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "application", diff --git a/pkg/sbom/cyclonedx/testdata/sad/invalid-purl.json b/pkg/sbom/cyclonedx/testdata/sad/invalid-purl.json index 58c9e14c8fff..070da15fbb05 100644 --- a/pkg/sbom/cyclonedx/testdata/sad/invalid-purl.json +++ b/pkg/sbom/cyclonedx/testdata/sad/invalid-purl.json @@ -5,13 +5,16 @@ "version": 1, "metadata": { "timestamp": "2022-05-28T10:20:03.79527Z", - "tools": [ - { - "vendor": "aquasecurity", - "name": "trivy", - "version": "dev" - } - ], + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, "component": { "bom-ref": "0f585d64-4815-4b72-92c5-97dae191fa4a", "type": "application", From b4b90cfe202138844a27110e9136859cbc20285c Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:25:38 +0600 Subject: [PATCH 101/108] feat(java): add support for line numbers for pom.xml files (#5991) --- docs/docs/coverage/language/java.md | 13 ++++---- go.mod | 2 +- go.sum | 4 +-- .../analyzer/language/java/pom/pom_test.go | 31 +++++++++++++++++++ .../language/java/pom/testdata/happy/pom.xml | 8 +++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/docs/docs/coverage/language/java.md b/docs/docs/coverage/language/java.md index cf76d1ca5471..4043fc7e188f 100644 --- a/docs/docs/coverage/language/java.md +++ b/docs/docs/coverage/language/java.md @@ -11,11 +11,11 @@ Each artifact supports the following scanners: The following table provides an outline of the features Trivy offers. -| Artifact | Internet access | Dev dependencies | [Dependency graph][dependency-graph] | -|------------------|:---------------------:|:----------------:|:------------------------------------:| -| JAR/WAR/PAR/EAR | Trivy Java DB | Include | - | -| pom.xml | Maven repository [^1] | Exclude | ✓ | -| *gradle.lockfile | - | Exclude | - | +| Artifact | Internet access | Dev dependencies | [Dependency graph][dependency-graph] | Position | +|------------------|:---------------------:|:----------------:|:------------------------------------:|:--------:| +| JAR/WAR/PAR/EAR | Trivy Java DB | Include | - | - | +| pom.xml | Maven repository [^1] | Exclude | ✓ | ✓[^7] | +| *gradle.lockfile | - | Exclude | - | - | These may be enabled or disabled depending on the target. See [here](./index.md) for the detail. @@ -46,7 +46,7 @@ If your machine doesn't have the necessary files - Trivy tries to find the infor !!! Note Trivy only takes information about packages. We don't take a list of vulnerabilities for packages from the `maven repository`. - Information about data sources for Java you can see [here](../../scanner/vulnerability.md#data-sources_1). + Information about data sources for Java you can see [here](../../scanner/vulnerability.md#data-sources-1). You can disable connecting to the maven repository with the `--offline-scan` flag. The `--offline-scan` flag does not affect the Trivy database. @@ -67,5 +67,6 @@ It doesn't require the internet access. [^4]: e.g. when parent pom.xml file has `../pom.xml` path [^5]: When you use dependency path in `relativePath` field in pom.xml file [^6]: `/Users//.m2/repository` (for Linux and Mac) and `C:/Users//.m2/repository` (for Windows) by default +[^7]: To avoid confusion, Trivy only finds locations for direct dependencies from the base pom.xml file. [dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies \ No newline at end of file diff --git a/go.mod b/go.mod index 420f5e748bde..e36c08e265dc 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.31.0 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.94.1 - github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 + github.com/aquasecurity/go-dep-parser v0.0.0-20240124102329-7be7d210a3d4 github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 diff --git a/go.sum b/go.sum index 6364a132f996..362a05d16330 100644 --- a/go.sum +++ b/go.sum @@ -328,8 +328,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.94.1 h1:lk44bfUltm0f0Dw4DbO3Ka9d/bf3N8cWclSdHXMyKF4= github.com/aquasecurity/defsec v0.94.1/go.mod h1:wiX9BX0SOG0ZWjVIPYGPl46fyO3Gu8lJnk4rmhFR7IA= -github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562 h1:jdymGFJpArgx1ZZW7yqgCV8Tt+sEZ4jKxjQufPYRSXE= -github.com/aquasecurity/go-dep-parser v0.0.0-20231229070651-5f0903175562/go.mod h1:B+gSaiuXV258CtyfBwFvG87+GE/FOh6W4N+LMuQxvVA= +github.com/aquasecurity/go-dep-parser v0.0.0-20240124102329-7be7d210a3d4 h1:Ex+YahhZPTu0WF9IKngLr/oRWgW5TN9ed0n4Twsq2Hw= +github.com/aquasecurity/go-dep-parser v0.0.0-20240124102329-7be7d210a3d4/go.mod h1:P0PmelcN1ABKJrDzRbPnn6hK7RvgI+xmjiV/9uPaNnY= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20240109054747-49e4b5da33cb h1:dNxUB2bSbiLGNYcXkbBKrrfuY96+dXhA9FahEFZ4THQ= diff --git a/pkg/fanal/analyzer/language/java/pom/pom_test.go b/pkg/fanal/analyzer/language/java/pom/pom_test.go index 9a5214e806e5..10cec453b863 100644 --- a/pkg/fanal/analyzer/language/java/pom/pom_test.go +++ b/pkg/fanal/analyzer/language/java/pom/pom_test.go @@ -29,11 +29,25 @@ func Test_pomAnalyzer_Analyze(t *testing.T) { Type: types.Pom, FilePath: "testdata/happy/pom.xml", Libraries: types.Packages{ + { + ID: "com.example:example-api:2.0.0", + Name: "com.example:example-api", + Version: "2.0.0", + Locations: []types.Location{ + { + StartLine: 28, + EndLine: 32, + }, + }, + }, { ID: "com.example:example:1.0.0", Name: "com.example:example", Version: "1.0.0", Licenses: []string{"Apache-2.0"}, + DependsOn: []string{ + "com.example:example-api:2.0.0", + }, }, }, }, @@ -50,11 +64,25 @@ func Test_pomAnalyzer_Analyze(t *testing.T) { Type: types.Pom, FilePath: "pom.xml", Libraries: types.Packages{ + { + ID: "com.example:example-api:2.0.0", + Name: "com.example:example-api", + Version: "2.0.0", + Locations: []types.Location{ + { + StartLine: 28, + EndLine: 32, + }, + }, + }, { ID: "com.example:example:1.0.0", Name: "com.example:example", Version: "1.0.0", Licenses: []string{"Apache-2.0"}, + DependsOn: []string{ + "com.example:example-api:2.0.0", + }, }, }, }, @@ -104,6 +132,9 @@ func Test_pomAnalyzer_Analyze(t *testing.T) { Dir: tt.inputDir, FilePath: tt.inputFile, Content: f, + Options: analyzer.AnalysisOptions{ + Offline: true, + }, }) if tt.wantErr != "" { require.NotNil(t, err) diff --git a/pkg/fanal/analyzer/language/java/pom/testdata/happy/pom.xml b/pkg/fanal/analyzer/language/java/pom/testdata/happy/pom.xml index c4764b000af2..aa5f1066295c 100644 --- a/pkg/fanal/analyzer/language/java/pom/testdata/happy/pom.xml +++ b/pkg/fanal/analyzer/language/java/pom/testdata/happy/pom.xml @@ -23,4 +23,12 @@ https://github.com/knqyf263 + + + + com.example + example-api + 2.0.0 + + From f9da021315f10f8b35745640a8d3d144e109c47b Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Thu, 25 Jan 2024 17:23:32 +0700 Subject: [PATCH 102/108] docs: update link to data sources (#6000) --- docs/community/contribute/discussion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/contribute/discussion.md b/docs/community/contribute/discussion.md index bfcf2355dc55..b7e1a2d7294d 100644 --- a/docs/community/contribute/discussion.md +++ b/docs/community/contribute/discussion.md @@ -24,7 +24,7 @@ There are 4 categories: If you find any false positives or false negatives, please make sure to report them under the "False Detection" category, not "Bugs". ## False detection -Trivy depends on [multiple data sources](https://aquasecurity.github.io/trivy/latest/docs/vulnerability/detection/data-source/). +Trivy depends on [multiple data sources](https://aquasecurity.github.io/trivy/latest/docs/scanner/vulnerability/#data-sources). Sometime these databases contain mistakes. If Trivy can't detect any CVE-IDs or shows false positive result, at first please follow the next steps: From e2eb70ecb8e06da819c5447aaf51713c605f7f3f Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Thu, 25 Jan 2024 14:34:34 +0400 Subject: [PATCH 103/108] feat(vuln): enable `--vex` for all targets (#5992) Signed-off-by: knqyf263 Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> --- .../configuration/cli/trivy_filesystem.md | 1 + .../configuration/cli/trivy_image.md | 1 + .../configuration/cli/trivy_kubernetes.md | 1 + .../configuration/cli/trivy_repository.md | 1 + .../configuration/cli/trivy_rootfs.md | 1 + .../references/configuration/cli/trivy_vm.md | 1 + docs/docs/supply-chain/vex.md | 119 +++++++++++++----- pkg/flag/sbom_flags.go | 14 +-- pkg/flag/vulnerability_flags.go | 11 ++ 9 files changed, 106 insertions(+), 44 deletions(-) diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index c09c46f69575..c34288188900 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -87,6 +87,7 @@ trivy filesystem [flags] PATH --token-header string specify a header name for token in client/server mode (default "Trivy-Token") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index c08206a51a5b..f016a7fff185 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -106,6 +106,7 @@ trivy image [flags] IMAGE_NAME --token-header string specify a header name for token in client/server mode (default "Trivy-Token") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 3e2c7297e34d..00657886c681 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -97,6 +97,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg: --tolerations strings specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule) --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index 4f2a9f65d30b..b21ffd326db0 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -87,6 +87,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL) --token-header string specify a header name for token in client/server mode (default "Trivy-Token") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index aaa120285021..47e9a434f075 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -88,6 +88,7 @@ trivy rootfs [flags] ROOTDIR --token-header string specify a header name for token in client/server mode (default "Trivy-Token") --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index 2b004b6992e9..3c4d8c06ff7d 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -75,6 +75,7 @@ trivy vm [flags] VM_IMAGE --tf-exclude-downloaded-modules exclude misconfigurations for downloaded terraform modules --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default "Trivy-Token") + --vex string [EXPERIMENTAL] file path to VEX --vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library]) ``` diff --git a/docs/docs/supply-chain/vex.md b/docs/docs/supply-chain/vex.md index a551629943cc..59f3c5b97353 100644 --- a/docs/docs/supply-chain/vex.md +++ b/docs/docs/supply-chain/vex.md @@ -4,7 +4,7 @@ This feature might change without preserving backwards compatibility. Trivy supports filtering detected vulnerabilities using [the Vulnerability Exploitability Exchange (VEX)](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf), a standardized format for sharing and exchanging information about vulnerabilities. -By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status. +By providing VEX during scanning, it is possible to filter vulnerabilities based on their status. Currently, Trivy supports the following three formats: - [CycloneDX](https://cyclonedx.org/capabilities/vex/) @@ -14,6 +14,15 @@ Currently, Trivy supports the following three formats: This is still an experimental implementation, with only minimal functionality added. ## CycloneDX +| Target | Supported | +|:---------------:|:---------:| +| Container Image | | +| Filesystem | | +| Code Repository | | +| VM Image | | +| Kubernetes | | +| SBOM | ✅ | + There are [two VEX formats](https://cyclonedx.org/capabilities/vex/) for CycloneDX: - Independent BOM and VEX BOM @@ -28,7 +37,7 @@ The following steps are required: 2. Create a VEX based on the SBOM generated in step 1 3. Provide the VEX when scanning the CycloneDX SBOM -### Generating the SBOM +### Generate the SBOM You can generate a CycloneDX SBOM with Trivy as follows: ```shell @@ -117,23 +126,24 @@ Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0) CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document. ## OpenVEX +| Target | Supported | +|:---------------:|:---------:| +| Container Image | ✅ | +| Filesystem | ✅ | +| Code Repository | ✅ | +| VM Image | ✅ | +| Kubernetes | ✅ | +| SBOM | ✅ | + Trivy also supports [OpenVEX][openvex] that is designed to be minimal, compliant, interoperable, and embeddable. -Since OpenVEX aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy. +OpenVEX can be used in all Trivy targets, unlike CycloneDX VEX. The following steps are required: -1. Generate a SBOM (CycloneDX or SPDX) -2. Create a VEX based on the SBOM generated in step 1 -3. Provide the VEX when scanning the SBOM +1. Create a VEX document +2. Provide the VEX when scanning your target -### Generating the SBOM -You can generate a CycloneDX or SPDX SBOM with Trivy as follows: - -```shell -$ trivy image --format spdx-json --output debian11.spdx.json debian:11 -``` - -### Create the VEX +### Create the VEX document Please see also [the example](https://github.com/openvex/examples). In Trivy, [the Package URL (PURL)][purl] is used as the product identifier. @@ -167,11 +177,11 @@ In the above example, PURLs, located in `packages.externalRefs.referenceLocator` `pkg:deb/debian/curl@7.50.3-1` in OpenVEX matches `pkg:deb/debian/curl@7.50.3-1?arch=i386`, while `pkg:deb/debian/curl@7.50.3-1?arch=amd64` does not match `pkg:deb/debian/curl@7.50.3-1?arch=i386`. -### Scan SBOM with VEX -Provide the VEX when scanning the SBOM. +### Scan with VEX +Provide the VEX when scanning your target. ``` -$ trivy sbom debian11.spdx.json --vex debian11.openvex +$ trivy image debian:11 --vex debian11.openvex ... 2023-04-26T17:56:05.358+0300 INFO Filtered out the detected vulnerability {"VEX format": "OpenVEX", "vulnerability-id": "CVE-2019-8457", "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path"} @@ -182,25 +192,25 @@ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document. -[openvex]: https://github.com/openvex/spec -[purl]: https://github.com/package-url/purl-spec ## CSAF +| Target | Supported | +|:---------------:|:---------:| +| Container Image | ✅ | +| Filesystem | ✅ | +| Code Repository | ✅ | +| VM Image | ✅ | +| Kubernetes | ✅ | +| SBOM | ✅ | + Trivy also supports [CSAF][csaf] format for VEX. Since CSAF aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy. The following steps are required: -1. Generate a SBOM (CycloneDX or SPDX) -2. Create a CSAF document based on the SBOM generated in step 1 -3. Provide the CSAF document when scanning the SBOM - -### Generating the SBOM -You can generate a CycloneDX or SPDX SBOM with Trivy as follows: +1. Create a CSAF document +2. Provide the CSAF when scanning your target -```shell -$ trivy image --format spdx-json --output debian11.spdx.json debian:11 -``` ### Create the CSAF document Create a CSAF document in JSON format as follows: @@ -303,11 +313,11 @@ $ cat < debian11.vex.csaf EOF ``` -### Scan SBOM with CSAF document -Provide the CSAF document when scanning the SBOM. +### Scan with CSAF VEX +Provide the CSAF document when scanning your target. ```console -$ trivy sbom debian11.spdx.json --vex debian11.vex.csaf +$ trivy image debian:11 --vex debian11.vex.csaf ... 2024-01-02T10:28:26.704+0100 INFO Filtered out the detected vulnerability {"VEX format": "CSAF", "vulnerability-id": "CVE-2019-8457", "status": "not_affected"} @@ -318,4 +328,51 @@ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0) CVE-2019-8457 is no longer shown as it is filtered out according to the given CSAF document. +## Appendix +### PURL matching +In the context of VEX, Package URLs (PURLs) are utilized to identify specific software packages and their versions. +The PURL matching specification outlines how PURLs are interpreted for vulnerability exception processing, ensuring precise identification and broad coverage of software packages. + +!!! note + The following PURL matching rules are not formally defined within the current official PURL specification. + Instead, they represent [a community consensus][purl-matching] on how to interpret PURLs. + +Below are the key aspects of the PURL matching rules: + +#### Matching Without Version +A PURL without a specified version (e.g., `pkg:maven/com.google.guava/guava`) matches all versions of that package. +This rule simplifies the application of vulnerability exceptions to all versions of a package. + +**Example**: `pkg:maven/com.google.guava/guava` matches: + +- All versions of `guava`, such as `com.google.guava:guava:24.1.1`, `com.google.guava:guava:30.0`. + +#### Matching Without Qualifiers +A PURL without any qualifiers (e.g., `pkg:maven/com.google.guava/guava@24.1.1`) matches any variation of that package, irrespective of qualifiers. +This approach ensures broad matching capabilities, covering all architectural or platform-specific variations of a package version. + +**Example**: `pkg:maven/com.google.guava/guava@24.1.1` matches: + +- `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86` +- `pkg:maven/com.google.guava/guava@24.1.1?type=pom` + +#### Matching With Specific Qualifiers +A PURL that includes specific qualifiers (e.g., `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86`) matches only those package versions that include the same qualifiers. + +**Example**: `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86` matches: + +- `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86&type=dll` + - Extra qualifiers (e.g., `type=dll`) are ignored. + +does not match: + +- `pkg:maven/com.google.guava/guava@24.1.1` + - `classifier=x86` is missing. +- `pkg:maven/com.google.guava/guava@24.1.1?classifier=sources` + - `classifier` must have the same value. + + [csaf]: https://oasis-open.github.io/csaf-documentation/specification.html +[openvex]: https://github.com/openvex/spec +[purl]: https://github.com/package-url/purl-spec +[purl-matching]: https://github.com/openvex/spec/issues/27 diff --git a/pkg/flag/sbom_flags.go b/pkg/flag/sbom_flags.go index 5980e9eab59e..5d8c515c1d74 100644 --- a/pkg/flag/sbom_flags.go +++ b/pkg/flag/sbom_flags.go @@ -21,29 +21,20 @@ var ( Usage: "deprecated", Deprecated: true, } - VEXFlag = Flag{ - Name: "vex", - ConfigName: "sbom.vex", - Default: "", - Usage: "[EXPERIMENTAL] file path to VEX", - } ) type SBOMFlagGroup struct { ArtifactType *Flag // deprecated SBOMFormat *Flag // deprecated - VEXPath *Flag } type SBOMOptions struct { - VEXPath string } func NewSBOMFlagGroup() *SBOMFlagGroup { return &SBOMFlagGroup{ ArtifactType: &ArtifactTypeFlag, SBOMFormat: &SBOMFormatFlag, - VEXPath: &VEXFlag, } } @@ -55,7 +46,6 @@ func (f *SBOMFlagGroup) Flags() []*Flag { return []*Flag{ f.ArtifactType, f.SBOMFormat, - f.VEXPath, } } @@ -69,7 +59,5 @@ func (f *SBOMFlagGroup) ToOptions() (SBOMOptions, error) { return SBOMOptions{}, xerrors.New("'--artifact-type' and '--sbom-format' are no longer available") } - return SBOMOptions{ - VEXPath: getString(f.VEXPath), - }, nil + return SBOMOptions{}, nil } diff --git a/pkg/flag/vulnerability_flags.go b/pkg/flag/vulnerability_flags.go index c69ba3273dea..bf476c38fff9 100644 --- a/pkg/flag/vulnerability_flags.go +++ b/pkg/flag/vulnerability_flags.go @@ -35,17 +35,25 @@ var ( Values: dbTypes.Statuses, Usage: "comma-separated list of vulnerability status to ignore", } + VEXFlag = Flag{ + Name: "vex", + ConfigName: "vulnerability.vex", + Default: "", + Usage: "[EXPERIMENTAL] file path to VEX", + } ) type VulnerabilityFlagGroup struct { VulnType *Flag IgnoreUnfixed *Flag IgnoreStatus *Flag + VEXPath *Flag } type VulnerabilityOptions struct { VulnType []string IgnoreStatuses []dbTypes.Status + VEXPath string } func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup { @@ -53,6 +61,7 @@ func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup { VulnType: &VulnTypeFlag, IgnoreUnfixed: &IgnoreUnfixedFlag, IgnoreStatus: &IgnoreStatusFlag, + VEXPath: &VEXFlag, } } @@ -65,6 +74,7 @@ func (f *VulnerabilityFlagGroup) Flags() []*Flag { f.VulnType, f.IgnoreUnfixed, f.IgnoreStatus, + f.VEXPath, } } @@ -95,5 +105,6 @@ func (f *VulnerabilityFlagGroup) ToOptions() VulnerabilityOptions { return VulnerabilityOptions{ VulnType: getStringSlice(f.VulnType), IgnoreStatuses: ignoreStatuses, + VEXPath: getString(f.VEXPath), } } From adfde63d00ec0b7e6a3ceb42aa291bf0d12d13db Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:22:43 +0600 Subject: [PATCH 104/108] feat(misconf): add support of buildkit instructions when building dockerfile from image config (#5990) --- .../analyzer/imgconf/dockerfile/dockerfile.go | 9 ++ .../imgconf/dockerfile/dockerfile_test.go | 86 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go b/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go index 269a6aa86733..8c433499aca7 100644 --- a/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go +++ b/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go @@ -52,6 +52,15 @@ func (a *historyAnalyzer) Analyze(ctx context.Context, input analyzer.ConfigAnal case strings.HasPrefix(h.CreatedBy, "/bin/sh -c"): // RUN instruction createdBy = strings.ReplaceAll(h.CreatedBy, "/bin/sh -c", "RUN") + case strings.HasSuffix(h.CreatedBy, "# buildkit"): + // buildkit instructions + // COPY ./foo /foo # buildkit + // ADD ./foo.txt /foo.txt # buildkit + // RUN /bin/sh -c ls -hl /foo # buildkit + createdBy = strings.TrimSuffix(h.CreatedBy, "# buildkit") + if strings.HasPrefix(h.CreatedBy, "RUN /bin/sh -c") { + createdBy = strings.ReplaceAll(createdBy, "RUN /bin/sh -c", "RUN") + } case strings.HasPrefix(h.CreatedBy, "USER"): // USER instruction createdBy = h.CreatedBy diff --git a/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go b/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go index 2c822ab1ae77..dc165ff39f43 100644 --- a/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go +++ b/pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go @@ -94,6 +94,92 @@ func Test_historyAnalyzer_Analyze(t *testing.T) { }, }, }, + { + name: "happy path with buildkit instructions", + input: analyzer.ConfigAnalysisInput{ + Config: &v1.ConfigFile{ + Config: v1.Config{ + Healthcheck: &v1.HealthConfig{ + Test: []string{"CMD-SHELL", "curl --fail http://localhost:3000 || exit 1"}, + Interval: time.Second * 10, + Timeout: time.Second * 3, + }, + }, + History: []v1.History{ + { + CreatedBy: "/bin/sh -c #(nop) ADD file:289c2fac17119508ced527225d445747cd177111b4a0018a6b04948ecb3b5e29 in / ", + EmptyLayer: false, + }, + { + CreatedBy: "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", + EmptyLayer: true, + }, + { + CreatedBy: "ADD ./foo.txt /foo.txt # buildkit", + EmptyLayer: false, + }, + { + CreatedBy: "COPY ./foo /foo # buildkit", + EmptyLayer: false, + }, + { + CreatedBy: "RUN /bin/sh -c ls -hl /foo # buildkit", + EmptyLayer: false, + }, + { + CreatedBy: "USER foo", + EmptyLayer: true, + }, + { + CreatedBy: `HEALTHCHECK &{["CMD-SHELL" "curl -sS 127.0.0.1 || exit 1"] "10s" "3s" "0s" '\x00'}`, + EmptyLayer: true, + }, + }, + }, + }, + want: &analyzer.ConfigAnalysisResult{ + Misconfiguration: &types.Misconfiguration{ + FileType: "dockerfile", + FilePath: "Dockerfile", + Failures: types.MisconfResults{ + types.MisconfResult{ + Namespace: "builtin.dockerfile.DS005", + Query: "data.builtin.dockerfile.DS005.deny", + Message: "Consider using 'COPY ./foo.txt /foo.txt' command instead of 'ADD ./foo.txt /foo.txt'", + PolicyMetadata: types.PolicyMetadata{ + ID: "DS005", + AVDID: "AVD-DS-0005", + Type: "Dockerfile Security Check", + Title: "ADD instead of COPY", + Description: "You should use COPY instead of ADD unless you want to extract a tar file. Note that an ADD command will extract a tar file, which adds the risk of Zip-based vulnerabilities. Accordingly, it is advised to use a COPY command, which does not extract tar files.", + Severity: "LOW", + RecommendedActions: "Use COPY instead of ADD", + References: []string{"https://docs.docker.com/engine/reference/builder/#add"}, + }, + CauseMetadata: types.CauseMetadata{ + Provider: "Dockerfile", + Service: "general", + StartLine: 1, + EndLine: 1, + Code: types.Code{ + Lines: []types.Line{ + { + Number: 1, + Content: "ADD ./foo.txt /foo.txt", + IsCause: true, + Truncated: false, + Highlighted: "\x1b[38;5;64mADD\x1b[0m ./foo.txt /foo.txt", + FirstCause: true, + LastCause: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, { name: "happy path. Base layer is found", input: analyzer.ConfigAnalysisInput{ From 13f797f885ff007901df7c4b42ecd78604582f5a Mon Sep 17 00:00:00 2001 From: guangwu Date: Fri, 26 Jan 2024 15:57:37 +0800 Subject: [PATCH 105/108] fix: check returned error before deferring f.Close() (#6007) Signed-off-by: guoguangwu --- pkg/fanal/analyzer/pkg/apk/apk_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/fanal/analyzer/pkg/apk/apk_test.go b/pkg/fanal/analyzer/pkg/apk/apk_test.go index f7b308fcbd49..45ce2a77aa74 100644 --- a/pkg/fanal/analyzer/pkg/apk/apk_test.go +++ b/pkg/fanal/analyzer/pkg/apk/apk_test.go @@ -408,8 +408,8 @@ func TestParseApkInfo(t *testing.T) { t.Run(testname, func(t *testing.T) { a := alpinePkgAnalyzer{} f, err := os.Open(tt.path) - defer f.Close() require.NoError(t, err) + defer f.Close() scanner := bufio.NewScanner(f) gotPkgs, gotFiles := a.parseApkInfo(scanner) From 70dd572ef741856502bc369144312e327f947046 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:19:27 +0600 Subject: [PATCH 106/108] fix(report): use `AWS_REGION` env for secrets in `asff` template (#6011) --- contrib/asff.tpl | 4 ++-- integration/testdata/secrets.asff.golden | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/asff.tpl b/contrib/asff.tpl index 4c33de7e0b49..d6833a1d7ff1 100644 --- a/contrib/asff.tpl +++ b/contrib/asff.tpl @@ -128,7 +128,7 @@ { "SchemaVersion": "2018-10-08", "Id": "{{ $target }}", - "ProductArn": "arn:aws:securityhub:{{ env "AWS_DEFAULT_REGION" }}::product/aquasecurity/aquasecurity", + "ProductArn": "arn:aws:securityhub:{{ env "AWS_REGION" }}::product/aquasecurity/aquasecurity", "GeneratorId": "Trivy", "AwsAccountId": "{{ env "AWS_ACCOUNT_ID" }}", "Types": [ "Sensitive Data Identifications" ], @@ -145,7 +145,7 @@ "Type": "Other", "Id": "{{ $target }}", "Partition": "aws", - "Region": "{{ env "AWS_DEFAULT_REGION" }}", + "Region": "{{ env "AWS_REGION" }}", "Details": { "Other": { "Filename": "{{ $target }}" diff --git a/integration/testdata/secrets.asff.golden b/integration/testdata/secrets.asff.golden index 818ad20f8237..b3a7c45fadac 100644 --- a/integration/testdata/secrets.asff.golden +++ b/integration/testdata/secrets.asff.golden @@ -2,7 +2,7 @@ "Findings": [{ "SchemaVersion": "2018-10-08", "Id": "deploy.sh", - "ProductArn": "arn:aws:securityhub:::product/aquasecurity/aquasecurity", + "ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity", "GeneratorId": "Trivy", "AwsAccountId": "123456789012", "Types": [ "Sensitive Data Identifications" ], @@ -19,7 +19,7 @@ "Type": "Other", "Id": "deploy.sh", "Partition": "aws", - "Region": "", + "Region": "test-region", "Details": { "Other": { "Filename": "deploy.sh" @@ -31,7 +31,7 @@ },{ "SchemaVersion": "2018-10-08", "Id": "deploy.sh", - "ProductArn": "arn:aws:securityhub:::product/aquasecurity/aquasecurity", + "ProductArn": "arn:aws:securityhub:test-region::product/aquasecurity/aquasecurity", "GeneratorId": "Trivy", "AwsAccountId": "123456789012", "Types": [ "Sensitive Data Identifications" ], @@ -48,7 +48,7 @@ "Type": "Other", "Id": "deploy.sh", "Partition": "aws", - "Region": "", + "Region": "test-region", "Details": { "Other": { "Filename": "deploy.sh" From 4df9363890ca7268d5c262a5916da0374921148b Mon Sep 17 00:00:00 2001 From: Nikita Pivkin Date: Fri, 26 Jan 2024 17:52:25 +0700 Subject: [PATCH 107/108] docs: add note about Bun (#6001) Signed-off-by: knqyf263 Co-authored-by: knqyf263 --- docs/docs/coverage/language/nodejs.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/docs/coverage/language/nodejs.md b/docs/docs/coverage/language/nodejs.md index 393491b34f46..c371a1117178 100644 --- a/docs/docs/coverage/language/nodejs.md +++ b/docs/docs/coverage/language/nodejs.md @@ -1,14 +1,15 @@ # Node.js -Trivy supports three types of Node.js package managers: `npm`, `Yarn` and `pnpm`. +Trivy supports four types of Node.js package managers: `npm`, `Yarn`, `pnpm` and `Bun`[^1]. The following scanners are supported. -| Artifact | SBOM | Vulnerability | License | -| -------- | :---: | :-----------: | :-----: | -| npm | ✓ | ✓ | ✓ | -| Yarn | ✓ | ✓ | ✓ | -| pnpm | ✓ | ✓ | - | +| Artifact | SBOM | Vulnerability | License | +|----------|:----:|:-------------:|:-------:| +| npm | ✓ | ✓ | ✓ | +| Yarn | ✓ | ✓ | ✓ | +| pnpm | ✓ | ✓ | - | +| Bun | ✓ | ✓ | ✓ | The following table provides an outline of the features Trivy offers. @@ -17,11 +18,12 @@ The following table provides an outline of the features Trivy offers. | npm | package-lock.json | ✓ | [Excluded](#npm) | ✓ | ✓ | | Yarn | yarn.lock | ✓ | [Excluded](#yarn) | ✓ | ✓ | | pnpm | pnpm-lock.yaml | ✓ | Excluded | ✓ | - | +| Bun | yarn.lock | ✓ | [Excluded](#yarn) | ✓ | ✓ | In addition, Trivy scans installed packages with `package.json`. | File | Dependency graph | Position | License | -| ------------ | :--------------: | :------: | :-----: | +|--------------|:----------------:|:--------:|:-------:| | package.json | - | - | ✅ | These may be enabled or disabled depending on the target. @@ -53,6 +55,12 @@ By default, Trivy doesn't report development dependencies. Use the `--include-de ### pnpm Trivy parses `pnpm-lock.yaml`, then finds production dependencies and builds a [tree][dependency-graph] of dependencies with vulnerabilities. +### Bun +Trivy supports scanning `yarn.lock` files generated by [Bun](https://bun.sh/docs/install/lockfile#how-do-i-inspect-bun-s-lockfile). You can use the command `bun install -y` to generate a Yarn-compatible `yarn.lock`. + +!!! note + `bun.lockb` is not supported. + ## Packages Trivy parses the manifest files of installed packages in container image scanning and so on. @@ -60,4 +68,6 @@ Trivy parses the manifest files of installed packages in container image scannin Trivy searches for `package.json` files under `node_modules` and identifies installed packages. It only extracts package names, versions and licenses for those packages. -[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies \ No newline at end of file +[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies + +[^1]: [yarn.lock](#bun) must be generated From 5924c021da7fba7e937cff6332ebf9ca317ebf80 Mon Sep 17 00:00:00 2001 From: Andrey Fedotov Date: Mon, 29 Jan 2024 11:34:43 +0300 Subject: [PATCH 108/108] feat(rust): Support workspace.members parsing for Cargo.toml analysis (#5285) Signed-off-by: knqyf263 Co-authored-by: DmitriyLewen Co-authored-by: knqyf263 --- .../analyzer/language/rust/cargo/cargo.go | 97 +++++++++----- .../language/rust/cargo/cargo_test.go | 126 ++++++++++++++++++ .../toml-workspace-members/Cargo.lock | 86 ++++++++++++ .../toml-workspace-members/Cargo.toml | 10 ++ .../toml-workspace-members/member/Cargo.toml | 7 + .../toml-workspace-members/member2/Cargo.toml | 7 + 6 files changed, 299 insertions(+), 34 deletions(-) create mode 100644 pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.lock create mode 100644 pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.toml create mode 100644 pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member/Cargo.toml create mode 100644 pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member2/Cargo.toml diff --git a/pkg/fanal/analyzer/language/rust/cargo/cargo.go b/pkg/fanal/analyzer/language/rust/cargo/cargo.go index 61b8bacc707f..f94614345f76 100644 --- a/pkg/fanal/analyzer/language/rust/cargo/cargo.go +++ b/pkg/fanal/analyzer/language/rust/cargo/cargo.go @@ -7,6 +7,7 @@ import ( "io" "io/fs" "os" + "path" "path/filepath" "sort" @@ -58,9 +59,9 @@ func (a cargoAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysi return filepath.Base(path) == types.CargoLock } - err := fsutils.WalkDir(input.FS, ".", required, func(path string, d fs.DirEntry, r io.Reader) error { + err := fsutils.WalkDir(input.FS, ".", required, func(filePath string, d fs.DirEntry, r io.Reader) error { // Parse Cargo.lock - app, err := a.parseCargoLock(path, r) + app, err := a.parseCargoLock(filePath, r) if err != nil { return xerrors.Errorf("parse error: %w", err) } else if app == nil { @@ -68,8 +69,8 @@ func (a cargoAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysi } // Parse Cargo.toml alongside Cargo.lock to identify the direct dependencies - if err = a.removeDevDependencies(input.FS, filepath.Dir(path), app); err != nil { - log.Logger.Warnf("Unable to parse %q to identify direct dependencies: %s", filepath.Join(filepath.Dir(path), types.CargoToml), err) + if err = a.removeDevDependencies(input.FS, path.Dir(filePath), app); err != nil { + log.Logger.Warnf("Unable to parse %q to identify direct dependencies: %s", path.Join(path.Dir(filePath), types.CargoToml), err) } sort.Sort(app.Libraries) apps = append(apps, *app) @@ -98,13 +99,13 @@ func (a cargoAnalyzer) Version() int { return version } -func (a cargoAnalyzer) parseCargoLock(path string, r io.Reader) (*types.Application, error) { - return language.Parse(types.Cargo, path, r, a.lockParser) +func (a cargoAnalyzer) parseCargoLock(filePath string, r io.Reader) (*types.Application, error) { + return language.Parse(types.Cargo, filePath, r, a.lockParser) } func (a cargoAnalyzer) removeDevDependencies(fsys fs.FS, dir string, app *types.Application) error { - cargoTOMLPath := filepath.Join(dir, types.CargoToml) - directDeps, err := a.parseCargoTOML(fsys, cargoTOMLPath) + cargoTOMLPath := path.Join(dir, types.CargoToml) + directDeps, err := a.parseRootCargoTOML(fsys, cargoTOMLPath) if errors.Is(err, fs.ErrNotExist) { log.Logger.Debugf("Cargo: %s not found", cargoTOMLPath) return nil @@ -155,40 +156,38 @@ func (a cargoAnalyzer) removeDevDependencies(fsys fs.FS, dir string, app *types. type cargoToml struct { Dependencies Dependencies `toml:"dependencies"` Target map[string]map[string]Dependencies `toml:"target"` - Workspace map[string]Dependencies `toml:"workspace"` + Workspace cargoTomlWorkspace `toml:"workspace"` +} + +type cargoTomlWorkspace struct { + Dependencies Dependencies `toml:"dependencies"` + Members []string `toml:"members"` } type Dependencies map[string]interface{} -func (a cargoAnalyzer) parseCargoTOML(fsys fs.FS, path string) (map[string]string, error) { - // Parse Cargo.json - f, err := fsys.Open(path) +// parseRootCargoTOML parses top-level Cargo.toml and returns dependencies. +// It also parses workspace members and their dependencies. +func (a cargoAnalyzer) parseRootCargoTOML(fsys fs.FS, filePath string) (map[string]string, error) { + dependencies, members, err := parseCargoTOML(fsys, filePath) if err != nil { - return nil, xerrors.Errorf("file open error: %w", err) + return nil, xerrors.Errorf("unable to parse %s: %w", filePath, err) } - defer func() { _ = f.Close() }() - - tomlFile := cargoToml{} - deps := make(map[string]string) - _, err = toml.NewDecoder(f).Decode(&tomlFile) - if err != nil { - return nil, xerrors.Errorf("toml decode error: %w", err) - } - - // There are cases when toml file doesn't include `Dependencies` field (then map will be nil). - // e.g. when only `workspace.Dependencies` are used - // declare `dependencies` to avoid panic - dependencies := Dependencies{} - maps.Copy(dependencies, tomlFile.Dependencies) - - // https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies - for _, target := range tomlFile.Target { - maps.Copy(dependencies, target["dependencies"]) + // According to Cargo workspace RFC, workspaces can't be nested: + // https://github.com/nox/rust-rfcs/blob/master/text/1525-cargo-workspace.md#validating-a-workspace + for _, member := range members { + memberPath := path.Join(path.Dir(filePath), member, types.CargoToml) + memberDeps, _, err := parseCargoTOML(fsys, memberPath) + if err != nil { + log.Logger.Warnf("Unable to parse %q: %s", memberPath, err) + continue + } + // Member dependencies shouldn't overwrite dependencies from root cargo.toml file + maps.Copy(memberDeps, dependencies) + dependencies = memberDeps } - // https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace - maps.Copy(dependencies, tomlFile.Workspace["dependencies"]) - + deps := make(map[string]string) for name, value := range dependencies { switch ver := value.(type) { case string: @@ -250,3 +249,33 @@ func (a cargoAnalyzer) matchVersion(currentVersion, constraint string) (bool, er return c.Check(ver), nil } + +func parseCargoTOML(fsys fs.FS, filePath string) (Dependencies, []string, error) { + // Parse Cargo.toml + f, err := fsys.Open(filePath) + if err != nil { + return nil, nil, xerrors.Errorf("file open error: %w", err) + } + defer func() { _ = f.Close() }() + + var tomlFile cargoToml + // There are cases when toml file doesn't include `Dependencies` field (then map will be nil). + // e.g. when only `workspace.Dependencies` are used + // declare `dependencies` to avoid panic + dependencies := Dependencies{} + if _, err = toml.NewDecoder(f).Decode(&tomlFile); err != nil { + return nil, nil, xerrors.Errorf("toml decode error: %w", err) + } + + maps.Copy(dependencies, tomlFile.Dependencies) + + // https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies + for _, target := range tomlFile.Target { + maps.Copy(dependencies, target["dependencies"]) + } + + // https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#inheriting-a-dependency-from-a-workspace + maps.Copy(dependencies, tomlFile.Workspace.Dependencies) + // https://doc.rust-lang.org/cargo/reference/workspaces.html#the-members-and-exclude-fields + return dependencies, tomlFile.Workspace.Members, nil +} diff --git a/pkg/fanal/analyzer/language/rust/cargo/cargo_test.go b/pkg/fanal/analyzer/language/rust/cargo/cargo_test.go index 8665b5022e1c..ef699f4eff72 100644 --- a/pkg/fanal/analyzer/language/rust/cargo/cargo_test.go +++ b/pkg/fanal/analyzer/language/rust/cargo/cargo_test.go @@ -382,6 +382,132 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) { dir: "testdata/sad", want: &analyzer.AnalysisResult{}, }, + { + name: "workspace members", + dir: "testdata/toml-workspace-members", + want: &analyzer.AnalysisResult{ + Applications: []types.Application{ + { + Type: types.Cargo, + FilePath: "Cargo.lock", + Libraries: types.Packages{ + { + ID: "aho-corasick@1.1.2", + Name: "aho-corasick", + Version: "1.1.2", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 5, + EndLine: 12, + }, + }, + DependsOn: []string{"memchr@2.6.4"}, + }, + { + ID: "gdb-command@0.7.6", + Name: "gdb-command", + Version: "0.7.6", + Indirect: false, + Locations: []types.Location{ + { + StartLine: 14, + EndLine: 22, + }, + }, + DependsOn: []string{ + "regex@1.10.2", + "wait-timeout@0.2.0", + }, + }, + { + ID: "libc@0.2.150", + Name: "libc", + Version: "0.2.150", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 24, + EndLine: 28, + }, + }, + }, + { + ID: "memchr@2.6.4", + Name: "memchr", + Version: "2.6.4", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 44, + EndLine: 48, + }, + }, + }, + { + ID: "regex@1.10.2", + Name: "regex", + Version: "1.10.2", + Locations: []types.Location{ + { + StartLine: 50, + EndLine: 60, + }, + }, + DependsOn: []string{ + "aho-corasick@1.1.2", + "memchr@2.6.4", + "regex-automata@0.4.3", + "regex-syntax@0.8.2", + }, + }, + { + ID: "regex-automata@0.4.3", + Name: "regex-automata", + Version: "0.4.3", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 62, + EndLine: 71, + }, + }, + DependsOn: []string{ + "aho-corasick@1.1.2", + "memchr@2.6.4", + "regex-syntax@0.8.2", + }, + }, + { + ID: "regex-syntax@0.8.2", + Name: "regex-syntax", + Version: "0.8.2", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 73, + EndLine: 77, + }, + }, + }, + { + ID: "wait-timeout@0.2.0", + Name: "wait-timeout", + Version: "0.2.0", + Indirect: true, + Locations: []types.Location{ + { + StartLine: 79, + EndLine: 86, + }, + }, + DependsOn: []string{"libc@0.2.150"}, + }, + }, + }, + }, + }, + }, } for _, tt := range tests { diff --git a/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.lock b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.lock new file mode 100644 index 000000000000..66afdd45c106 --- /dev/null +++ b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.lock @@ -0,0 +1,86 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "gdb-command" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a067c49eb3dfc7c2357d3d37536d2f57c5250ac377672164286b8d5ea94c5d" +dependencies = [ + "regex", + "wait-timeout", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "member" +version = "0.1.0" +dependencies = [ + "gdb-command", +] + +[[package]] +name = "member2" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] diff --git a/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.toml b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.toml new file mode 100644 index 000000000000..0a0b822e61d4 --- /dev/null +++ b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/Cargo.toml @@ -0,0 +1,10 @@ +[workspace.package] +name = "toml-workspace-members" +version = "0.1.0" + +[workspace] +resolver = "2" +members = ["member", "member2"] + +[workspace.dependencies] +regex = "1" diff --git a/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member/Cargo.toml b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member/Cargo.toml new file mode 100644 index 000000000000..3be79eac93e1 --- /dev/null +++ b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "member" +version = "0.1.0" +edition = "2021" + +[dependencies] +gdb-command = "0.7" diff --git a/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member2/Cargo.toml b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member2/Cargo.toml new file mode 100644 index 000000000000..297d3a8659e9 --- /dev/null +++ b/pkg/fanal/analyzer/language/rust/cargo/testdata/toml-workspace-members/member2/Cargo.toml @@ -0,0 +1,7 @@ +[package] +edition = "2021" +name = "member2" +version = "0.1.0" + +[dependencies] +regex = { workspace = true}