replace dummy matcher with os matcher

This commit is contained in:
Alex Goodman 2020-06-01 07:18:17 -04:00
parent 16c478536e
commit 386a13a4f6
No known key found for this signature in database
GPG key ID: 86E2870463D5E890
3 changed files with 81 additions and 40 deletions

View file

@ -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...)
}

View file

@ -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",
},
}
}

View 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
}