Add RPM file scanning support (#1188)

This commit is contained in:
Keith Zantow
2022-09-07 14:16:30 -04:00
committed by GitHub
parent 1c7b7c5f8a
commit 70db13d49e
37 changed files with 470 additions and 108 deletions
@@ -80,6 +80,8 @@ func decodeComponent(c *cyclonedx.Component) *pkg.Package {
common.DecodeInto(p, values, "syft:package", CycloneDXFields)
p.MetadataType = pkg.CleanMetadataType(p.MetadataType)
p.Metadata = decodePackageMetadata(values, c, p.MetadataType)
if p.Type == "" {
@@ -109,8 +109,8 @@ func Test_encodeComponentProperties(t *testing.T) {
Name: "dive",
Version: "0.9.2-1",
Type: pkg.RpmPkg,
MetadataType: pkg.RpmdbMetadataType,
Metadata: pkg.RpmdbMetadata{
MetadataType: pkg.RpmMetadataType,
Metadata: pkg.RpmMetadata{
Name: "dive",
Epoch: &epoch,
Arch: "x86_64",
@@ -124,7 +124,7 @@ func Test_encodeComponentProperties(t *testing.T) {
},
},
expected: &[]cyclonedx.Property{
{Name: "syft:package:metadataType", Value: "RpmdbMetadata"},
{Name: "syft:package:metadataType", Value: "RpmMetadata"},
{Name: "syft:package:type", Value: "rpm"},
{Name: "syft:metadata:epoch", Value: "2"},
{Name: "syft:metadata:release", Value: "1"},
@@ -193,29 +193,51 @@ func Test_deriveBomRef(t *testing.T) {
}
func Test_decodeComponent(t *testing.T) {
javaComponentWithNoSyftProperties := cyclonedx.Component{
Name: "ch.qos.logback/logback-classic",
Version: "1.2.3",
PackageURL: "pkg:maven/ch.qos.logback/logback-classic@1.2.3",
Type: "library",
BOMRef: "pkg:maven/ch.qos.logback/logback-classic@1.2.3",
}
tests := []struct {
name string
component cyclonedx.Component
want pkg.Language
name string
component cyclonedx.Component
wantLanguage pkg.Language
wantMetadataType pkg.MetadataType
}{
{
name: "derive language from pURL if missing",
component: javaComponentWithNoSyftProperties,
want: pkg.Java,
name: "derive language from pURL if missing",
component: cyclonedx.Component{
Name: "ch.qos.logback/logback-classic",
Version: "1.2.3",
PackageURL: "pkg:maven/ch.qos.logback/logback-classic@1.2.3",
Type: "library",
BOMRef: "pkg:maven/ch.qos.logback/logback-classic@1.2.3",
},
wantLanguage: pkg.Java,
},
{
name: "handle existing RpmdbMetadata type",
component: cyclonedx.Component{
Name: "acl",
Version: "2.2.53-1.el8",
PackageURL: "pkg:rpm/centos/acl@2.2.53-1.el8?arch=x86_64&upstream=acl-2.2.53-1.el8.src.rpm&distro=centos-8",
Type: "library",
BOMRef: "pkg:rpm/centos/acl@2.2.53-1.el8?arch=x86_64&upstream=acl-2.2.53-1.el8.src.rpm&distro=centos-8",
Properties: &[]cyclonedx.Property{
{
Name: "syft:package:metadataType",
Value: "RpmdbMetadata",
},
},
},
wantMetadataType: pkg.RpmMetadataType,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, decodeComponent(&tt.component).Language)
p := decodeComponent(&tt.component)
if tt.wantLanguage != "" {
assert.Equal(t, tt.wantLanguage, p.Language)
}
if tt.wantMetadataType != "" {
assert.Equal(t, tt.wantMetadataType, p.MetadataType)
}
})
}
}
@@ -9,7 +9,7 @@ func encodePublisher(p pkg.Package) string {
switch metadata := p.Metadata.(type) {
case pkg.ApkMetadata:
return metadata.Maintainer
case pkg.RpmdbMetadata:
case pkg.RpmMetadata:
return metadata.Vendor
case pkg.DpkgMetadata:
return metadata.Maintainer
@@ -22,7 +22,7 @@ func decodePublisher(publisher string, metadata interface{}) {
switch meta := metadata.(type) {
case *pkg.ApkMetadata:
meta.Maintainer = publisher
case *pkg.RpmdbMetadata:
case *pkg.RpmMetadata:
meta.Vendor = publisher
case *pkg.DpkgMetadata:
meta.Maintainer = publisher
@@ -31,7 +31,7 @@ func Test_encodePublisher(t *testing.T) {
{
name: "from rpm",
input: pkg.Package{
Metadata: pkg.RpmdbMetadata{
Metadata: pkg.RpmMetadata{
Vendor: "auth",
},
},
@@ -80,7 +80,7 @@ func Test_Originator(t *testing.T) {
{
name: "from rpm",
input: pkg.Package{
Metadata: pkg.RpmdbMetadata{
Metadata: pkg.RpmMetadata{
Vendor: "auth",
},
},
@@ -28,7 +28,7 @@ func Originator(p pkg.Package) string {
if len(metadata.Authors) > 0 {
author = metadata.Authors[0]
}
case pkg.RpmdbMetadata:
case pkg.RpmMetadata:
return "Organization: " + metadata.Vendor
case pkg.DpkgMetadata:
author = metadata.Maintainer
@@ -326,7 +326,7 @@ func extractMetadata(p *spdx.Package2_2, info pkgInfo) (pkg.MetadataType, interf
if license == "" {
license = p.PackageLicenseConcluded
}
return pkg.RpmdbMetadataType, pkg.RpmdbMetadata{
return pkg.RpmMetadataType, pkg.RpmMetadata{
Name: p.PackageName,
Version: p.PackageVersion,
Epoch: epoch,
@@ -176,8 +176,8 @@ func Test_extractMetadata(t *testing.T) {
},
},
},
metaType: pkg.RpmdbMetadataType,
meta: pkg.RpmdbMetadata{
metaType: pkg.RpmMetadataType,
meta: pkg.RpmMetadata{
Name: "SomeRpmPkg",
Version: "13.2.79",
Epoch: &oneTwoThreeFour,
+4 -3
View File
@@ -74,7 +74,8 @@ func (p *Package) UnmarshalJSON(b []byte) error {
//nolint:funlen,gocognit,gocyclo
func unpackMetadata(p *Package, unpacker packageMetadataUnpacker) error {
p.MetadataType = unpacker.MetadataType
p.MetadataType = pkg.CleanMetadataType(unpacker.MetadataType)
switch p.MetadataType {
case "":
// there is no metadata, skip
@@ -91,8 +92,8 @@ func unpackMetadata(p *Package, unpacker packageMetadataUnpacker) error {
return err
}
p.Metadata = payload
case pkg.RpmdbMetadataType:
var payload pkg.RpmdbMetadata
case pkg.RpmMetadataType:
var payload pkg.RpmMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
@@ -133,6 +133,45 @@ func Test_unpackMetadata(t *testing.T) {
"purl": "pkg:golang/gopkg.in/square/go-jose.v2@v2.6.0"
}`),
},
{
name: "can handle RpmdbMetadata",
metadataType: pkg.RpmMetadataType,
packageData: []byte(`{
"id": "4ac699c3b8fe1835",
"name": "acl",
"version": "2.2.53-1.el8",
"type": "rpm",
"foundBy": "rpm-db-cataloger",
"locations": [
{
"path": "/var/lib/rpm/Packages",
"layerID": "sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59"
}
],
"licenses": [
"GPLv2+"
],
"language": "",
"cpes": [
"cpe:2.3:a:centos:acl:2.2.53-1.el8:*:*:*:*:*:*:*",
"cpe:2.3:a:acl:acl:2.2.53-1.el8:*:*:*:*:*:*:*"
],
"purl": "pkg:rpm/centos/acl@2.2.53-1.el8?arch=x86_64&upstream=acl-2.2.53-1.el8.src.rpm&distro=centos-8",
"metadataType": "RpmdbMetadata",
"metadata": {
"name": "acl",
"version": "2.2.53",
"epoch": null,
"architecture": "x86_64",
"release": "1.el8",
"sourceRpm": "acl-2.2.53-1.el8.src.rpm",
"size": 205740,
"license": "GPLv2+",
"vendor": "CentOS",
"modularityLabel": ""
}
}`),
},
{
name: "bad metadata type is an error",
metadataType: "BOGOSITY",