From 09bebdb3f7942b145e5a81ca8a70b6073c3ab101 Mon Sep 17 00:00:00 2001 From: Yousef Alowayed Date: Tue, 16 Apr 2024 12:09:03 -0700 Subject: [PATCH] Add license extraction to RPM extractor and proto. PiperOrigin-RevId: 625411754 --- binary/proto/proto.go | 1 + binary/proto/proto_test.go | 56 ++++++++++++++++++++++++++++-- binary/proto/scan_result.proto | 1 + extractor/os/rpm/extractor.go | 6 ++++ extractor/os/rpm/extractor_test.go | 13 +++++++ extractor/os/rpm/metadata.go | 1 + 6 files changed, 76 insertions(+), 2 deletions(-) diff --git a/binary/proto/proto.go b/binary/proto/proto.go index 7568afc0..09e2c5c0 100644 --- a/binary/proto/proto.go +++ b/binary/proto/proto.go @@ -277,6 +277,7 @@ func setProtoMetadata(meta any, i *spb.Inventory) { OsBuildId: m.OSBuildID, Vendor: m.Vendor, Architecture: m.Architecture, + License: m.License, }, } case *cos.Metadata: diff --git a/binary/proto/proto_test.go b/binary/proto/proto_test.go index 6cd20557..f48ee5f5 100644 --- a/binary/proto/proto_test.go +++ b/binary/proto/proto_test.go @@ -29,6 +29,7 @@ import ( "github.com/google/osv-scalibr/extractor/language/javascript/packagejson" "github.com/google/osv-scalibr/extractor/language/python/wheelegg" "github.com/google/osv-scalibr/extractor/os/dpkg" + "github.com/google/osv-scalibr/extractor/os/rpm" "github.com/google/osv-scalibr/extractor/sbom/spdx" "github.com/google/osv-scalibr/plugin" "github.com/google/osv-scalibr/purl" @@ -274,6 +275,57 @@ func TestScanResultToProto(t *testing.T) { Locations: []string{"/file3"}, Extractor: "sbom/spdx", } + purlRPMInventory := &extractor.Inventory{ + Name: "openssh-clients", + Version: "5.3p1", + Metadata: &rpm.Metadata{ + PackageName: "openssh-clients", + SourceRPM: "openssh-5.3p1-124.el6_10.src.rpm", + Epoch: 2, + OSID: "rhel", + OSVersionID: "8.9", + OSBuildID: "", + OSName: "Red Hat Enterprise Linux", + Vendor: "CentOS", + Architecture: "x86_64", + License: "BSD", + }, + Locations: []string{"/file1"}, + Extractor: "os/rpm", + } + purlRPMInventoryProto := &spb.Inventory{ + Name: "openssh-clients", + Version: "5.3p1", + Purl: &spb.Purl{ + Purl: "pkg:rpm/rhel/openssh-clients@5.3p1?arch=x86_64&distro=rhel-8.9&epoch=2&sourcerpm=openssh-5.3p1-124.el6_10.src.rpm", + Type: purl.TypeRPM, + Namespace: "rhel", + Name: "openssh-clients", + Version: "5.3p1", + Qualifiers: []*spb.Qualifier{ + &spb.Qualifier{Key: "arch", Value: "x86_64"}, + &spb.Qualifier{Key: "distro", Value: "rhel-8.9"}, + &spb.Qualifier{Key: "epoch", Value: "2"}, + &spb.Qualifier{Key: "sourcerpm", Value: "openssh-5.3p1-124.el6_10.src.rpm"}, + }, + }, + Metadata: &spb.Inventory_RpmMetadata{ + RpmMetadata: &spb.RPMPackageMetadata{ + PackageName: "openssh-clients", + SourceRpm: "openssh-5.3p1-124.el6_10.src.rpm", + Epoch: 2, + OsId: "rhel", + OsVersionId: "8.9", + OsBuildId: "", + OsName: "Red Hat Enterprise Linux", + Vendor: "CentOS", + Architecture: "x86_64", + License: "BSD", + }, + }, + Locations: []string{"/file1"}, + Extractor: "os/rpm", + } testCases := []struct { desc string @@ -300,7 +352,7 @@ func TestScanResultToProto(t *testing.T) { Status: success, }, }, - Inventories: []*extractor.Inventory{purlDPKGInventory, purlPythonInventory, purlJavascriptInventory, cpeInventory}, + Inventories: []*extractor.Inventory{purlDPKGInventory, purlPythonInventory, purlJavascriptInventory, cpeInventory, purlRPMInventory}, Findings: []*detector.Finding{ &detector.Finding{ Adv: &detector.Advisory{ @@ -343,7 +395,7 @@ func TestScanResultToProto(t *testing.T) { Status: successProto, }, }, - Inventories: []*spb.Inventory{purlDPKGInventoryProto, purlPythonInventoryProto, purlJavascriptInventoryProto, cpeInventoryProto}, + Inventories: []*spb.Inventory{purlDPKGInventoryProto, purlPythonInventoryProto, purlJavascriptInventoryProto, cpeInventoryProto, purlRPMInventoryProto}, Findings: []*spb.Finding{ &spb.Finding{ Adv: &spb.Advisory{ diff --git a/binary/proto/scan_result.proto b/binary/proto/scan_result.proto index 19e9d0e4..c88b53e0 100644 --- a/binary/proto/scan_result.proto +++ b/binary/proto/scan_result.proto @@ -222,6 +222,7 @@ message RPMPackageMetadata { string os_name = 7; string vendor = 8; string architecture = 9; + string license = 10; } // The additional data found in COS packages. diff --git a/extractor/os/rpm/extractor.go b/extractor/os/rpm/extractor.go index 799c964f..0846d14c 100644 --- a/extractor/os/rpm/extractor.go +++ b/extractor/os/rpm/extractor.go @@ -117,6 +117,7 @@ func (e Extractor) Extract(ctx context.Context, input *extractor.ScanInput) ([]* OSBuildID: m["BUILD_ID"], Vendor: p.Vendor, Architecture: p.Architecture, + License: p.License, } i := &extractor.Inventory{ @@ -167,6 +168,7 @@ func (e Extractor) parseRPMDB(path string) ([]rpmPackageInfo, error) { SourceRPM: pkg.SourceRpm, Vendor: pkg.Vendor, Architecture: pkg.Arch, + License: pkg.License, } result = append(result, newPkg) @@ -184,6 +186,7 @@ type rpmPackageInfo struct { Maintainer string Vendor string Architecture string + License string } func toNamespace(m *Metadata) string { @@ -227,6 +230,9 @@ func (e Extractor) ToPURL(i *extractor.Inventory) (*purl.PackageURL, error) { if m.SourceRPM != "" { q[purl.SourceRPM] = m.SourceRPM } + if m.Architecture != "" { + q[purl.Arch] = m.Architecture + } return &purl.PackageURL{ Type: purl.TypeRPM, Namespace: toNamespace(m), diff --git a/extractor/os/rpm/extractor_test.go b/extractor/os/rpm/extractor_test.go index bedc47ec..26499876 100644 --- a/extractor/os/rpm/extractor_test.go +++ b/extractor/os/rpm/extractor_test.go @@ -118,6 +118,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "SUSE LLC ", Architecture: "x86_64", + License: "GPL-2.0+", }, }, &extractor.Inventory{ @@ -134,6 +135,7 @@ func TestExtract(t *testing.T) { OSVersionID: "38", Vendor: "SUSE LLC ", Architecture: "x86_64", + License: "GPL-3.0-or-later", }, }, &extractor.Inventory{ @@ -150,6 +152,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "SUSE LLC ", Architecture: "x86_64", + License: "GPL-3.0-or-later", }, }, }, @@ -175,6 +178,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "CentOS", Architecture: "x86_64", + License: "GPLv2+", }, }, &extractor.Inventory{ @@ -191,6 +195,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "CentOS", Architecture: "x86_64", + License: "LGPLv2+", }, }, &extractor.Inventory{ @@ -207,6 +212,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "CentOS", Architecture: "noarch", + License: "Public Domain", }, }, }, @@ -261,6 +267,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "Rocky Enterprise Software Foundation", Architecture: "x86_64", + License: "GPLv2", }, }, &extractor.Inventory{ @@ -277,6 +284,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "Rocky Enterprise Software Foundation", Architecture: "x86_64", + License: "LGPLv2+", }, }, &extractor.Inventory{ @@ -293,6 +301,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora Linux", Vendor: "Rocky Enterprise Software Foundation", Architecture: "noarch", + License: "Public Domain", }, }, }, @@ -318,6 +327,7 @@ func TestExtract(t *testing.T) { OSBuildID: "asdf", Vendor: "Rocky Enterprise Software Foundation", Architecture: "x86_64", + License: "GPLv2", }, }, &extractor.Inventory{ @@ -333,6 +343,7 @@ func TestExtract(t *testing.T) { OSBuildID: "asdf", Vendor: "Rocky Enterprise Software Foundation", Architecture: "x86_64", + License: "LGPLv2+", }, }, &extractor.Inventory{ @@ -348,6 +359,7 @@ func TestExtract(t *testing.T) { OSBuildID: "asdf", Vendor: "Rocky Enterprise Software Foundation", Architecture: "noarch", + License: "Public Domain", }, }, }, @@ -380,6 +392,7 @@ func TestExtract(t *testing.T) { OSName: "Fedora", OSVersionID: "32", Architecture: "x86_64", + License: "GPL", }, }, }, diff --git a/extractor/os/rpm/metadata.go b/extractor/os/rpm/metadata.go index 73da04c0..dd972e66 100644 --- a/extractor/os/rpm/metadata.go +++ b/extractor/os/rpm/metadata.go @@ -25,4 +25,5 @@ type Metadata struct { OSBuildID string Vendor string Architecture string + License string }