updater: update Ubuntu fetcher and add not-affected capability

This commit is contained in:
Quentin Machu 2016-01-19 11:03:27 -05:00 committed by Jimmy Zelinskie
parent 6e20993bac
commit ea59b0e45f

View File

@ -17,6 +17,7 @@ package ubuntu
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -72,6 +73,9 @@ var (
affectsCaptureRegexpNames = affectsCaptureRegexp.SubexpNames() affectsCaptureRegexpNames = affectsCaptureRegexp.SubexpNames()
log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater/fetchers/ubuntu") log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater/fetchers/ubuntu")
// ErrFilesystem is returned when a fetcher fails to interact with the local filesystem.
ErrFilesystem = errors.New("updater/fetchers: something went wrong when interacting with the fs")
) )
// UbuntuFetcher implements updater.Fetcher and get vulnerability updates from // UbuntuFetcher implements updater.Fetcher and get vulnerability updates from
@ -79,7 +83,7 @@ var (
type UbuntuFetcher struct{} type UbuntuFetcher struct{}
func init() { func init() {
//updater.RegisterFetcher("Ubuntu", &UbuntuFetcher{}) updater.RegisterFetcher("Ubuntu", &UbuntuFetcher{})
} }
// FetchUpdate gets vulnerability updates from the Ubuntu CVE Tracker. // FetchUpdate gets vulnerability updates from the Ubuntu CVE Tracker.
@ -137,14 +141,13 @@ func (fetcher *UbuntuFetcher) FetchUpdate(datastore database.Datastore) (resp up
continue continue
} }
v, pkgs, unknownReleases, err := parseUbuntuCVE(file) v, unknownReleases, err := parseUbuntuCVE(file)
if err != nil { if err != nil {
return resp, err return resp, err
} }
if len(v.FixedInNodes) > 0 { if len(v.FixedIn) > 0 {
resp.Vulnerabilities = append(resp.Vulnerabilities, v) resp.Vulnerabilities = append(resp.Vulnerabilities, v)
resp.Packages = append(resp.Packages, pkgs...)
} }
// Log any unknown releases. // Log any unknown releases.
@ -273,8 +276,7 @@ func getRevisionNumber(pathToRepo string) (int, error) {
return revno, nil return revno, nil
} }
func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerability, packages []*database.Package, unknownReleases map[string]struct{}, err error) { func parseUbuntuCVE(fileContent io.Reader) (vulnerability database.Vulnerability, unknownReleases map[string]struct{}, err error) {
vulnerability = &database.Vulnerability{}
unknownReleases = make(map[string]struct{}) unknownReleases = make(map[string]struct{})
readingDescription := false readingDescription := false
scanner := bufio.NewScanner(fileContent) scanner := bufio.NewScanner(fileContent)
@ -289,7 +291,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
// Parse the name. // Parse the name.
if strings.HasPrefix(line, "Candidate:") { if strings.HasPrefix(line, "Candidate:") {
vulnerability.ID = strings.TrimSpace(strings.TrimPrefix(line, "Candidate:")) vulnerability.Name = strings.TrimSpace(strings.TrimPrefix(line, "Candidate:"))
continue continue
} }
@ -308,7 +310,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
priority = priority[:strings.Index(priority, " ")] priority = priority[:strings.Index(priority, " ")]
} }
vulnerability.Severity = ubuntuPriorityToPriority(priority) vulnerability.Severity = ubuntuPriorityToSeverity(priority)
continue continue
} }
@ -342,9 +344,9 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
continue continue
} }
// Only consider the package if its status is needed, active, deferred // Only consider the package if its status is needed, active, deferred, not-affected or
// or released. Ignore DNE, needs-triage, not-affected, ignored, pending. // released. Ignore DNE (package does not exist), needs-triage, ignored, pending.
if md["status"] == "needed" || md["status"] == "active" || md["status"] == "deferred" || md["status"] == "released" { if md["status"] == "needed" || md["status"] == "active" || md["status"] == "deferred" || md["status"] == "released" || md["status"] == "not-affected" {
if _, isReleaseIgnored := ubuntuIgnoredReleases[md["release"]]; isReleaseIgnored { if _, isReleaseIgnored := ubuntuIgnoredReleases[md["release"]]; isReleaseIgnored {
continue continue
} }
@ -362,6 +364,8 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
log.Warningf("could not parse package version '%s': %s. skipping", md["note"], err) log.Warningf("could not parse package version '%s': %s. skipping", md["note"], err)
} }
} }
} else if md["status"] == "not-affected" {
version = types.MinVersion
} else { } else {
version = types.MaxVersion version = types.MaxVersion
} }
@ -370,13 +374,14 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
} }
// Create and add the new package. // Create and add the new package.
pkg := &database.Package{ featureVersion := database.FeatureVersion{
OS: "ubuntu:" + database.UbuntuReleasesMapping[md["release"]], Feature: database.Feature{
Namespace: database.Namespace{Name: "ubuntu:" + database.UbuntuReleasesMapping[md["release"]]},
Name: md["package"], Name: md["package"],
},
Version: version, Version: version,
} }
packages = append(packages, pkg) vulnerability.FixedIn = append(vulnerability.FixedIn, featureVersion)
vulnerability.FixedInNodes = append(vulnerability.FixedInNodes, pkg.GetNode())
} }
} }
} }
@ -397,7 +402,7 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability *database.Vulnerabilit
return return
} }
func ubuntuPriorityToPriority(priority string) types.Severity { func ubuntuPriorityToSeverity(priority string) types.Priority {
switch priority { switch priority {
case "untriaged": case "untriaged":
return types.Unknown return types.Unknown