-
Notifications
You must be signed in to change notification settings - Fork 604
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Keith Zantow <kzantow@gmail.com>
- Loading branch information
Showing
17 changed files
with
327 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package rpm | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/anchore/syft/internal" | ||
"github.com/anchore/syft/syft/file" | ||
rpmdb "github.com/knqyf263/go-rpmdb/pkg" | ||
"github.com/sassoftware/go-rpmutils" | ||
|
||
"github.com/anchore/syft/syft/artifact" | ||
"github.com/anchore/syft/syft/pkg" | ||
"github.com/anchore/syft/syft/source" | ||
) | ||
|
||
type FileCataloger struct{} | ||
|
||
// NewFileCataloger returns a new RPM file cataloger object. | ||
func NewFileCataloger() *FileCataloger { | ||
return &FileCataloger{} | ||
} | ||
|
||
// Name returns a string that uniquely describes a cataloger | ||
func (c *FileCataloger) Name() string { | ||
return "rpm-file-cataloger" | ||
} | ||
|
||
// UsesExternalSources indicates that the rpmdb cataloger does not use external sources | ||
func (c *FileCataloger) UsesExternalSources() bool { | ||
return false | ||
} | ||
|
||
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing rpm files | ||
func (c *FileCataloger) Catalog(resolver source.FileResolver) ([]pkg.Package, []artifact.Relationship, error) { | ||
fileMatches, err := resolver.FilesByGlob("**/*.rpm") | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to find rpm files's by glob: %w", err) | ||
} | ||
|
||
var pkgs []pkg.Package | ||
for _, location := range fileMatches { | ||
dbContentReader, err := resolver.FileContentsByLocation(location) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
rpm, err := rpmutils.ReadRpm(dbContentReader) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
nevra, err := rpm.Header.GetNEVRA() | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
licenses, _ := rpm.Header.GetStrings(rpmutils.LICENSE) | ||
sourceRpm, _ := rpm.Header.GetString(rpmutils.SOURCERPM) | ||
vendor, _ := rpm.Header.GetString(rpmutils.VENDOR) | ||
digestAlgorithm := getDigestAlgorithm(rpm.Header) | ||
size, _ := rpm.Header.InstalledSize() | ||
files, _ := rpm.Header.GetFiles() | ||
|
||
p := pkg.Package{ | ||
Name: nevra.Name, | ||
Version: nevra.Version, | ||
FoundBy: c.Name(), | ||
Licenses: licenses, | ||
Locations: source.NewLocationSet(location), | ||
Type: pkg.RpmPkg, | ||
MetadataType: pkg.RpmdbMetadataType, | ||
Metadata: pkg.RpmdbMetadata{ | ||
Name: nevra.Name, | ||
Version: nevra.Version, | ||
Epoch: parseEpoch(nevra.Epoch), | ||
Arch: nevra.Arch, | ||
Release: nevra.Release, | ||
SourceRpm: sourceRpm, | ||
Vendor: vendor, | ||
License: strings.Join(licenses, " AND "), | ||
Size: int(size), | ||
Files: mapFiles(files, digestAlgorithm), | ||
}, | ||
} | ||
p.SetID() | ||
pkgs = append(pkgs, p) | ||
|
||
internal.CloseAndLogError(dbContentReader, location.VirtualPath) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("unable to catalog rpm file=%+v: %w", location.RealPath, err) | ||
} | ||
} | ||
|
||
return pkgs, nil, nil | ||
} | ||
|
||
func getDigestAlgorithm(header *rpmutils.RpmHeader) string { | ||
digestAlgorithm, _ := header.GetString(rpmutils.FILEDIGESTALGO) | ||
if digestAlgorithm != "" { | ||
return digestAlgorithm | ||
} | ||
digestAlgorithms, _ := header.GetUint32s(rpmutils.FILEDIGESTALGO) | ||
if len(digestAlgorithms) > 0 { | ||
digestAlgo := int(digestAlgorithms[0]) | ||
return rpmutils.GetFileAlgoName(digestAlgo) | ||
} | ||
return "" | ||
} | ||
|
||
func mapFiles(files []rpmutils.FileInfo, digestAlgorithm string) []pkg.RpmdbFileRecord { | ||
var out []pkg.RpmdbFileRecord | ||
for _, f := range files { | ||
digest := file.Digest{} | ||
if f.Digest() != "" { | ||
digest = file.Digest{ | ||
Algorithm: digestAlgorithm, | ||
Value: f.Digest(), | ||
} | ||
} | ||
out = append(out, pkg.RpmdbFileRecord{ | ||
Path: f.Name(), | ||
Mode: pkg.RpmdbFileMode(f.Mode()), | ||
Size: int(f.Size()), | ||
Digest: digest, | ||
UserName: f.UserName(), | ||
GroupName: f.GroupName(), | ||
Flags: rpmdb.FileFlags(f.Flags()).String(), | ||
}) | ||
} | ||
return out | ||
} | ||
|
||
func parseEpoch(epoch string) *int { | ||
i, err := strconv.Atoi(epoch) | ||
if err != nil { | ||
return nil | ||
} | ||
return &i | ||
} |
Oops, something went wrong.