github.com/anchore/syft@v1.38.2/syft/pkg/rpm.go (about) 1 package pkg 2 3 import ( 4 "sort" 5 "strings" 6 7 "github.com/scylladb/go-set/strset" 8 9 "github.com/anchore/syft/syft/file" 10 ) 11 12 // RpmDBGlob is the glob pattern used to find RPM DB files. Where: 13 // - /var/lib/rpm/... is the typical path for most distributions 14 // - /usr/share/rpm/... is common for rpm-ostree distributions (coreos-like) 15 // - Packages is the legacy Berkeley db based format 16 // - Packages.db is the "ndb" format used in SUSE 17 // - rpmdb.sqlite is the sqlite format used in fedora + derivates 18 const RpmDBGlob = "**/{var/lib,usr/share,usr/lib/sysimage}/rpm/{Packages,Packages.db,rpmdb.sqlite}" 19 20 // RpmManifestGlob is used in CBL-Mariner distroless images 21 const RpmManifestGlob = "**/var/lib/rpmmanifest/container-manifest-2" 22 23 var _ FileOwner = (*RpmDBEntry)(nil) 24 25 // RpmArchive represents package metadata extracted directly from a .rpm archive file, containing the same information as an RPM database entry. 26 type RpmArchive RpmDBEntry 27 28 // RpmDBEntry represents all captured data from a RPM DB package entry. 29 type RpmDBEntry struct { 30 // Name is the RPM package name as found in the RPM database. 31 Name string `json:"name"` 32 33 // Version is the upstream version of the package. 34 Version string `json:"version"` 35 36 // Epoch is the version epoch used to force upgrade ordering (null if not set). 37 Epoch *int `json:"epoch" cyclonedx:"epoch" jsonschema:"nullable"` 38 39 // Arch is the target CPU architecture (e.g., "x86_64", "aarch64", "noarch"). 40 Arch string `json:"architecture"` 41 42 // Release is the package release number or distribution-specific version suffix. 43 Release string `json:"release" cyclonedx:"release"` 44 45 // SourceRpm is the source RPM filename that was used to build this package. 46 SourceRpm string `json:"sourceRpm" cyclonedx:"sourceRpm"` 47 48 // Signatures contains GPG signature metadata for package verification. 49 Signatures []RpmSignature `json:"signatures,omitempty" cyclonedx:"signatures"` 50 51 // Size is the total installed size of the package in bytes. 52 Size int `json:"size" cyclonedx:"size"` 53 54 // Vendor is the organization that packaged the software. 55 Vendor string `json:"vendor"` 56 57 // ModularityLabel identifies the module stream for modular RPM packages (e.g., "nodejs:12:20200101"). 58 ModularityLabel *string `json:"modularityLabel,omitempty" cyclonedx:"modularityLabel"` 59 60 // Provides lists the virtual packages and capabilities this package provides. 61 Provides []string `json:"provides,omitempty"` 62 63 // Requires lists the dependencies required by this package. 64 Requires []string `json:"requires,omitempty"` 65 66 // Files are the file records for all files owned by this package. 67 Files []RpmFileRecord `json:"files"` 68 } 69 70 // RpmSignature represents a GPG signature for an RPM package used for authenticity verification. 71 type RpmSignature struct { 72 // PublicKeyAlgorithm is the public key algorithm used for signing (e.g., "RSA"). 73 PublicKeyAlgorithm string `json:"algo"` 74 75 // HashAlgorithm is the hash algorithm used for the signature (e.g., "SHA256"). 76 HashAlgorithm string `json:"hash"` 77 78 // Created is the timestamp when the signature was created. 79 Created string `json:"created"` 80 81 // IssuerKeyID is the GPG key ID that created the signature. 82 IssuerKeyID string `json:"issuer"` 83 } 84 85 func (s RpmSignature) String() string { 86 if s.PublicKeyAlgorithm == "" && s.HashAlgorithm == "" && s.Created == "" && s.IssuerKeyID == "" { 87 return "" 88 } 89 // mimics the output you would see from rpm -q --qf "%{RSAHEADER}" 90 // e.g."RSA/SHA256, Mon May 16 12:32:55 2022, Key ID 702d426d350d275d" 91 return strings.Join([]string{s.PublicKeyAlgorithm + "/" + s.HashAlgorithm, s.Created, "Key ID " + s.IssuerKeyID}, ", ") 92 } 93 94 // RpmFileRecord represents the file metadata for a single file attributed to a RPM package. 95 type RpmFileRecord struct { 96 // Path is the absolute file path where the file is installed. 97 Path string `json:"path"` 98 99 // Mode is the file permission mode bits following Unix stat.h conventions. 100 Mode RpmFileMode `json:"mode"` 101 102 // Size is the file size in bytes. 103 Size int `json:"size"` 104 105 // Digest contains the hash algorithm and value for file integrity verification. 106 Digest file.Digest `json:"digest"` 107 108 // UserName is the owner username for the file. 109 UserName string `json:"userName"` 110 111 // GroupName is the group name for the file. 112 GroupName string `json:"groupName"` 113 114 // Flags indicates the file type (e.g., "%config", "%doc", "%ghost"). 115 Flags string `json:"flags"` 116 } 117 118 // RpmFileMode is the raw file mode for a single file. This can be interpreted as the linux stat.h mode (see https://pubs.opengroup.org/onlinepubs/007908799/xsh/sysstat.h.html) 119 type RpmFileMode uint16 120 121 func (m RpmDBEntry) OwnedFiles() (result []string) { 122 s := strset.New() 123 for _, f := range m.Files { 124 if f.Path != "" { 125 s.Add(f.Path) 126 } 127 } 128 result = s.List() 129 sort.Strings(result) 130 return result 131 }