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
}