mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
replace dummy matcher with os matcher
This commit is contained in:
parent
16c478536e
commit
386a13a4f6
3 changed files with 81 additions and 40 deletions
|
@ -1,11 +1,12 @@
|
|||
package matcher
|
||||
|
||||
import (
|
||||
imgbomOS "github.com/anchore/imgbom/imgbom/os"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/internal/log"
|
||||
"github.com/anchore/vulnscan/vulnscan/match"
|
||||
"github.com/anchore/vulnscan/vulnscan/matcher/dummy"
|
||||
"github.com/anchore/vulnscan/vulnscan/matcher/os"
|
||||
"github.com/anchore/vulnscan/vulnscan/result"
|
||||
"github.com/anchore/vulnscan/vulnscan/vulnerability"
|
||||
)
|
||||
|
||||
var controllerInstance controller
|
||||
|
@ -14,7 +15,7 @@ func init() {
|
|||
controllerInstance = controller{
|
||||
matchers: make(map[pkg.Type][]Matcher),
|
||||
}
|
||||
controllerInstance.add(&dummy.Matcher{})
|
||||
controllerInstance.add(&os.Matcher{})
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
|
@ -23,28 +24,34 @@ type controller struct {
|
|||
|
||||
func (c *controller) add(matchers ...Matcher) {
|
||||
for _, m := range matchers {
|
||||
if _, ok := c.matchers[m.Type()]; ok {
|
||||
c.matchers[m.Type()] = make([]Matcher, 0)
|
||||
for _, t := range m.Types() {
|
||||
if _, ok := c.matchers[t]; ok {
|
||||
c.matchers[t] = make([]Matcher, 0)
|
||||
}
|
||||
|
||||
c.matchers[m.Type()] = append(c.matchers[m.Type()], m)
|
||||
log.Debugf("adding matcher: %+v", m.Type())
|
||||
c.matchers[t] = append(c.matchers[t], m)
|
||||
log.Debugf("adding matcher: %+v", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: do we need to pass the entire store? or just a reader interface subset?
|
||||
func (c *controller) findMatches(s match.Store, packages ...pkg.Package) result.Result {
|
||||
func (c *controller) findMatches(s vulnerability.Provider, o imgbomOS.OS, packages ...*pkg.Package) result.Result {
|
||||
res := result.NewResult()
|
||||
for _, p := range packages {
|
||||
for _, matchers := range c.matchers {
|
||||
for _, m := range matchers {
|
||||
res.Add(p, m.Match(s, p)...)
|
||||
matches, err := m.Match(s, o, p)
|
||||
if err != nil {
|
||||
log.Errorf("matcher failed for pkg=%s: %w", p, err)
|
||||
} else {
|
||||
res.Add(p, matches...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FindMatches(s match.Store, packages ...pkg.Package) result.Result {
|
||||
return controllerInstance.findMatches(s, packages...)
|
||||
func FindMatches(s vulnerability.Provider, o imgbomOS.OS, packages ...*pkg.Package) result.Result {
|
||||
return controllerInstance.findMatches(s, o, packages...)
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package dummy
|
||||
|
||||
import (
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan-db/pkg/vulnerability"
|
||||
"github.com/anchore/vulnscan/vulnscan/match"
|
||||
)
|
||||
|
||||
// TODO: delete me...
|
||||
|
||||
type Matcher struct {
|
||||
}
|
||||
|
||||
func (m *Matcher) Type() pkg.Type {
|
||||
return pkg.DebPkg
|
||||
}
|
||||
|
||||
func (m *Matcher) Match(match.Store, pkg.Package) []match.Match {
|
||||
return []match.Match{
|
||||
{
|
||||
Confidence: 42,
|
||||
Vulnerability: vulnerability.Vulnerability{},
|
||||
Package: pkg.Package{},
|
||||
SearchKey: "the key",
|
||||
},
|
||||
}
|
||||
}
|
61
vulnscan/matcher/os/matcher.go
Normal file
61
vulnscan/matcher/os/matcher.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package os
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/os"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/vulnscan/match"
|
||||
"github.com/anchore/vulnscan/vulnscan/version"
|
||||
"github.com/anchore/vulnscan/vulnscan/vulnerability"
|
||||
)
|
||||
|
||||
// TODO: consider renaming this package to DISTRO for easier importing...
|
||||
|
||||
type Matcher struct {
|
||||
}
|
||||
|
||||
func (m *Matcher) Types() []pkg.Type {
|
||||
return []pkg.Type{pkg.DebPkg}
|
||||
}
|
||||
|
||||
func (m *Matcher) Match(store vulnerability.Provider, o os.OS, p *pkg.Package) ([]match.Match, error) {
|
||||
// TODO: add other kinds of matches? fuzzy matches, etc...
|
||||
return m.exactPackageNameMatch(store, o, p)
|
||||
}
|
||||
|
||||
func (m *Matcher) exactPackageNameMatch(store vulnerability.Provider, o os.OS, p *pkg.Package) ([]match.Match, error) {
|
||||
|
||||
matches := make([]match.Match, 0)
|
||||
|
||||
// TODO: there should be a vulnerability object in the vulnscan-db/db/vulnerability for mondel serialization and one here in vulnerability for rich objects
|
||||
|
||||
allPkgVulns, err := store.GetByOs(o, p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("matcher failed to fetch os=%s pkg=%s: %w", o, p.Name, err)
|
||||
}
|
||||
|
||||
verObj, err := version.NewVersionFromPkg(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("matcher failed to parse version pkg=%s ver=%s: %w", p.Name, p.Version, err)
|
||||
}
|
||||
|
||||
for _, vuln := range allPkgVulns {
|
||||
// if the constraint it met, then the given package has the vulnerability
|
||||
satisfied, err := vuln.Constraint.Satisfied(verObj)
|
||||
if err != nil {
|
||||
// TODO: not enough information (cannot back track constraint object)
|
||||
return nil, fmt.Errorf("matcher failed to check constraint=%s version=%s: %w", vuln.Constraint, verObj, err)
|
||||
}
|
||||
|
||||
if satisfied {
|
||||
matches = append(matches, match.Match{
|
||||
Confidence: 1.0, // TODO: this is hard coded for now
|
||||
Vulnerability: *vuln,
|
||||
Package: p,
|
||||
SearchKey: fmt.Sprintf("%s:%s", p.Name, p.Version), // TODO: better way to signify exact match?
|
||||
})
|
||||
}
|
||||
}
|
||||
return matches, nil
|
||||
}
|
Loading…
Reference in a new issue