v0.5.0 (no backwards compatibility) (#478)

* Change config.toml, Auto-generate UUIDs, change structure of optional field

* Detect processes affected by update using yum-ps (#482)

Detect processes affected by update using yum-ps

* Detect processes needs restart using checkrestart on Debian and Ubuntu.

* pass cpename by args when calling FillCveInfo (#513)

* fix new db (#502)

* Include Version,Revision in JSON

* Include hostname in JSON

* Update goval-dictionary's commit hash in Gopkg.lock

* Remove README.ja.md

* update packages (#596)

* fix: change ControlPath to .vuls of SSH option (#618)

* feat: checkrestart for Ubuntu and Debian (#622)

* feat: checkrestart for Ubuntu and Debian

* fix: dependencies check logic of configtest

* feat: need-restarting on RedHat

* refactor: Process.ProcName to Process.Name

* feat: detect a systemd service name of need-restarting-process

* feat: detect a systemd service name of need-restarting-process on Ubuntu

* feat: fill a service name of need-restarting-process, init-system

* Support NVD JSON and CVSS3 of JVN (#605)

* fix: compile errors

* fix: Show CVSS3 on TUI

* fix: test cases

* fix: Avoid null in JSON

* Fix maxCvssScore (#621)

* Fix maxCvssScore

* Update vulninfos.go

* fix(init): remove unnecessary log initialization

* refactor(nvd): use only json feed if exists json data. if not, use xml feed

* fix(scan): make Confidence slice

* feat(CWE): Display CWE name to TUI

* feat(cwe): import CWE defs in Japanese

* feat(cwe): add OWASP Top 10 ranking to CWE if applicable

* feat(scan): add -fast-root mode, implement scan/amazon.go

* refactor(const): change const name JVN to Jvn

* feat(scan): add -fast-root mode, implement scan/centos.go

* refactor(dep): update deps

* fix(amazon): deps check

* feat(scan): add -fast-root mode, implement scan/rhel.go

* feat(scan): add -fast-root mode, implement scan/oracle.go

* fix complile err

* feat(scan): add -fast-root mode, implement scan/debian.go

* fix testcase

* fix(amazon): scan using yum

* fix(configtest): change error message, status when no scannnable servers

* Fix(scan): detect init process logic

* fix(tui): display cvss as table format

* fix(scan): parse a output of reboot-notifier on CentOS6.9

* fix(tui): don't display score, vector when score is zero

* fix(scan): add -offline mode to suse scanner

* fix(scan): fix help message

* feat(scan): enable to define scan mode for each servers in config.toml #510

* refactor(config): chagne cpeNames to cpeURIs

* refactor(config): change dependencyCheckXMLPath to owaspDCXMLPath

* fix(config): containers -> containersIncluded, Excluded, containerType

* feature(report): enable to define cpeURIs for each contaner

* feature(report): enable to specify owasp dc xml path for each container

* fix(discover): fix a template displayed at the end of discover

* feature(report): add ignorePkgsRegexp #665

* feature(report): enable to define ignoreCves for each container #666

* fix(report): Displayed nothing in TUI detail area when CweID is nil

* Gopkg.toml diet

* feat(server): support server mode (#678)

* feat(server): support server mode

* Lock go version

* Use the latest kernel release among the installed release when the running kernel release is unknown

* Add TestViaHTTP

* Set logger to go-cve-dictionary client

* Add -to-localfile

* Add -to-http option to report

* Load -to-http conf from config.toml

* Support gost (#676)

* feat(gost): Support RedHat API

* feat(gost): Support Debian Security Tracker

* feat(db): display error msg when SQLite3 is locked at the beginning of reporting.

* feat(gost): TUI

* Only use RedHat information of installed packages

* feat(tui): show mitigation on TUI

* feat(gost): support redis backend

* fix test case

* fix nil pointer when db is nil

* fix(gost): detect vulns of src packages for Debian

* feat(gost): implement redis backend for gost redhat api

* feat(report): display fixState of unfixed pkgs

* fix(report): display distincted cweIDs

* feat(slack): display gost info

* feat(slack): display mitigation

* feat(report): display available patch state as fixed/total

* fix(tui): display - if source of reference is empty

* update deps

* fix(report): key in ScanResult JSON be lowerCamelcase.

* some keys to lower camel

* fix(configtest): dep check logic of yum-plugin-ps

* fix(tui): format

* feat(report): add -format-list option

* fix(report): -format-full-text

* fix(report): report -format-full-text

* fix(report): display v3 score detected by gost

* fix(scan): scan in fast mode if not defined in config.toml

* fix(gost): fetch RedHat data for fixed CVEs

* feat(report): show number of cves detected in each database

* fix(report): show new version as `Unknown` in offline and fast scan mode

* fix(report): fix num of upadtable and fixed

* fix(report): set `Not fixed yet` if packageStatus is empty

* refact(gost): make convertToModel public

* fix(test): fix test case

* update deps

* fix(report): include gost score in MaxCvssScore

* [WIP] feat(config): enable to set options in config.toml instead of cmd opt (#690)

* feat(config): enable to set options in config.toml instead of cmd opt

* fix(config): change Conf.Report.Slack to Conf.Slack

* fix(discover): change tempalte

* fix(report): fix config.toml auto-generate with -uuid

* Add endpoint for health check and change endpoint

* refact(cmd): refactor flag set

* fix(report): enable to specify opts with cmd arg and env value

* fix(scan): enable to parse the release version of amazon linux 2

* add(report) add -to-saas option (#695)

* add(report) add -to-saas option

* ignore other writer if -to-saas

* fix(saas) fix bug

* fix(scan): need-restarting needs internet connection

* fix(scan,configtest): check scan mode

* refactor(scan): change func name

* fix(suse): support offline mode, bug fix on AWS, zypper --no-color

* fix(tui): fix nil pointer when no vulns in tui

* feat(report): enable to define CPE FS format in config.toml

* fix(vet): fix warnings of go vet

* fix(travis): go version to 1.11

* update deps
This commit is contained in:
Kota Kanbe
2018-08-27 13:51:09 +09:00
committed by GitHub
parent d785fc2a54
commit 44fa2c5800
82 changed files with 14019 additions and 2485 deletions

View File

@@ -21,6 +21,7 @@ import (
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
)
// Alpine is the struct of Alpine Linux
@@ -38,22 +39,22 @@ func NewAlpine() Alpine {
}
// FillWithOval returns scan result after updating CVE info by OVAL
func (o Alpine) FillWithOval(r *models.ScanResult) (err error) {
func (o Alpine) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
var relatedDefs ovalResult
if o.isFetchViaHTTP() {
if o.IsFetchViaHTTP() {
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
return err
return 0, err
}
} else {
if relatedDefs, err = getDefsByPackNameFromOvalDB(r); err != nil {
return err
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
return 0, err
}
}
for _, defPacks := range relatedDefs.entries {
o.update(r, defPacks)
}
return nil
return len(relatedDefs.entries), nil
}
func (o Alpine) update(r *models.ScanResult, defPacks defPacks) {
@@ -62,8 +63,8 @@ func (o Alpine) update(r *models.ScanResult, defPacks defPacks) {
if !ok {
util.Log.Debugf("%s is newly detected by OVAL", cveID)
vinfo = models.VulnInfo{
CveID: cveID,
Confidence: models.OvalMatch,
CveID: cveID,
Confidences: []models.Confidence{models.OvalMatch},
}
}

View File

@@ -21,6 +21,7 @@ import (
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
ovalmodels "github.com/kotakanbe/goval-dictionary/models"
)
@@ -37,7 +38,7 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
util.Log.Debugf("%s is newly detected by OVAL", defPacks.def.Debian.CveID)
vinfo = models.VulnInfo{
CveID: defPacks.def.Debian.CveID,
Confidence: models.OvalMatch,
Confidences: []models.Confidence{models.OvalMatch},
CveContents: models.NewCveContents(ovalContent),
}
} else {
@@ -51,17 +52,14 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
defPacks.def.Debian.CveID)
cveContents = models.CveContents{}
}
if vinfo.Confidence.Score < models.OvalMatch.Score {
vinfo.Confidence = models.OvalMatch
}
vinfo.Confidences.AppendIfMissing(models.OvalMatch)
cveContents[ctype] = ovalContent
vinfo.CveContents = cveContents
}
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, pack := range vinfo.AffectedPackages {
notFixedYet, _ := defPacks.actuallyAffectedPackNames[pack.Name]
defPacks.actuallyAffectedPackNames[pack.Name] = notFixedYet
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
}
// update notFixedYet of SrcPackage
@@ -91,11 +89,11 @@ func (o DebianBase) convertToModel(def *ovalmodels.Definition) *models.CveConten
}
return &models.CveContent{
CveID: def.Debian.CveID,
Title: def.Title,
Summary: def.Description,
Severity: def.Advisory.Severity,
References: refs,
CveID: def.Debian.CveID,
Title: def.Title,
Summary: def.Description,
Cvss2Severity: def.Advisory.Severity,
References: refs,
}
}
@@ -116,17 +114,17 @@ func NewDebian() Debian {
}
// FillWithOval returns scan result after updating CVE info by OVAL
func (o Debian) FillWithOval(r *models.ScanResult) (err error) {
func (o Debian) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
//Debian's uname gives both of kernel release(uname -r), version(kernel-image version)
linuxImage := "linux-image-" + r.RunningKernel.Release
// Add linux and set the version of running kernel to search OVAL.
newVer := ""
if p, ok := r.Packages[linuxImage]; ok {
newVer = p.NewVersion
}
if r.Container.ContainerID == "" {
newVer := ""
if p, ok := r.Packages[linuxImage]; ok {
newVer = p.NewVersion
}
r.Packages["linux"] = models.Package{
Name: "linux",
Version: r.RunningKernel.Version,
@@ -135,13 +133,13 @@ func (o Debian) FillWithOval(r *models.ScanResult) (err error) {
}
var relatedDefs ovalResult
if o.isFetchViaHTTP() {
if o.IsFetchViaHTTP() {
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
return err
return 0, err
}
} else {
if relatedDefs, err = getDefsByPackNameFromOvalDB(r); err != nil {
return err
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
return 0, err
}
}
@@ -170,7 +168,7 @@ func (o Debian) FillWithOval(r *models.ScanResult) (err error) {
vuln.CveContents[models.Debian] = cont
}
}
return nil
return len(relatedDefs.entries), nil
}
// Ubuntu is the interface for Debian OVAL
@@ -190,7 +188,7 @@ func NewUbuntu() Ubuntu {
}
// FillWithOval returns scan result after updating CVE info by OVAL
func (o Ubuntu) FillWithOval(r *models.ScanResult) (err error) {
func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
ovalKernelImageNames := []string{
"linux-aws",
"linux-azure",
@@ -245,13 +243,13 @@ func (o Ubuntu) FillWithOval(r *models.ScanResult) (err error) {
}
var relatedDefs ovalResult
if o.isFetchViaHTTP() {
if o.IsFetchViaHTTP() {
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
return err
return 0, err
}
} else {
if relatedDefs, err = getDefsByPackNameFromOvalDB(r); err != nil {
return err
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
return 0, err
}
}
@@ -282,5 +280,5 @@ func (o Ubuntu) FillWithOval(r *models.ScanResult) (err error) {
vuln.CveContents[models.Ubuntu] = cont
}
}
return nil
return len(relatedDefs.entries), nil
}

View File

@@ -23,7 +23,7 @@ import (
"net/http"
"time"
"github.com/future-architect/vuls/config"
cnf "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
@@ -33,11 +33,12 @@ import (
// Client is the interface of OVAL client.
type Client interface {
CheckHTTPHealth() error
FillWithOval(r *models.ScanResult) error
FillWithOval(db.DB, *models.ScanResult) (int, error)
// CheckIfOvalFetched checks if oval entries are in DB by family, release.
CheckIfOvalFetched(string, string) (bool, error)
CheckIfOvalFresh(string, string) (bool, error)
CheckIfOvalFetched(db.DB, string, string) (bool, error)
CheckIfOvalFresh(db.DB, string, string) (bool, error)
IsFetchViaHTTP() bool
}
// Base is a base struct
@@ -47,11 +48,11 @@ type Base struct {
// CheckHTTPHealth do health check
func (b Base) CheckHTTPHealth() error {
if !b.isFetchViaHTTP() {
if !b.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", config.Conf.OvalDBURL)
url := fmt.Sprintf("%s/health", cnf.Conf.OvalDict.URL)
var errs []error
var resp *http.Response
resp, _, errs = gorequest.New().Get(url).End()
@@ -65,19 +66,9 @@ func (b Base) CheckHTTPHealth() error {
}
// CheckIfOvalFetched checks if oval entries are in DB by family, release.
func (b Base) CheckIfOvalFetched(osFamily, release string) (fetched bool, err error) {
if !b.isFetchViaHTTP() {
var ovaldb db.DB
if ovaldb, _, err = db.NewDB(
osFamily,
config.Conf.OvalDBType,
config.Conf.OvalDBPath,
config.Conf.DebugSQL,
); err != nil {
return false, err
}
defer ovaldb.CloseDB()
count, err := ovaldb.CountDefs(osFamily, release)
func (b Base) CheckIfOvalFetched(driver db.DB, osFamily, release string) (fetched bool, err error) {
if !b.IsFetchViaHTTP() {
count, err := driver.CountDefs(osFamily, release)
if err != nil {
return false, fmt.Errorf("Failed to count OVAL defs: %s, %s, %v",
osFamily, release, err)
@@ -85,7 +76,7 @@ func (b Base) CheckIfOvalFetched(osFamily, release string) (fetched bool, err er
return 0 < count, nil
}
url, _ := util.URLPathJoin(config.Conf.OvalDBURL, "count", osFamily, release)
url, _ := util.URLPathJoin(cnf.Conf.OvalDict.URL, "count", osFamily, release)
resp, body, errs := gorequest.New().Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return false, fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
@@ -100,22 +91,12 @@ func (b Base) CheckIfOvalFetched(osFamily, release string) (fetched bool, err er
}
// CheckIfOvalFresh checks if oval entries are fresh enough
func (b Base) CheckIfOvalFresh(osFamily, release string) (ok bool, err error) {
func (b Base) CheckIfOvalFresh(driver db.DB, osFamily, release string) (ok bool, err error) {
var lastModified time.Time
if !b.isFetchViaHTTP() {
var ovaldb db.DB
if ovaldb, _, err = db.NewDB(
osFamily,
config.Conf.OvalDBType,
config.Conf.OvalDBPath,
config.Conf.DebugSQL,
); err != nil {
return false, err
}
defer ovaldb.CloseDB()
lastModified = ovaldb.GetLastModified(osFamily, release)
if !b.IsFetchViaHTTP() {
lastModified = driver.GetLastModified(osFamily, release)
} else {
url, _ := util.URLPathJoin(config.Conf.OvalDBURL, "lastmodified", osFamily, release)
url, _ := util.URLPathJoin(cnf.Conf.OvalDict.URL, "lastmodified", osFamily, release)
resp, body, errs := gorequest.New().Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return false, fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
@@ -139,7 +120,8 @@ func (b Base) CheckIfOvalFresh(osFamily, release string) (ok bool, err error) {
return true, nil
}
func (b Base) isFetchViaHTTP() bool {
// IsFetchViaHTTP checks whether fetch via HTTP
func (b Base) IsFetchViaHTTP() bool {
// Default value of OvalDBType is sqlite3
return config.Conf.OvalDBURL != "" && config.Conf.OvalDBType == "sqlite3"
return cnf.Conf.OvalDict.URL != "" && cnf.Conf.OvalDict.Type == "sqlite3"
}

View File

@@ -25,6 +25,7 @@ import (
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
ovalmodels "github.com/kotakanbe/goval-dictionary/models"
)
@@ -34,20 +35,20 @@ type RedHatBase struct {
}
// FillWithOval returns scan result after updating CVE info by OVAL
func (o RedHatBase) FillWithOval(r *models.ScanResult) (err error) {
func (o RedHatBase) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
var relatedDefs ovalResult
if o.isFetchViaHTTP() {
if o.IsFetchViaHTTP() {
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
return err
return 0, err
}
} else {
if relatedDefs, err = getDefsByPackNameFromOvalDB(r); err != nil {
return err
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
return 0, err
}
}
for _, defPacks := range relatedDefs.entries {
o.update(r, defPacks)
nCVEs += o.update(r, defPacks)
}
for _, vuln := range r.ScannedCves {
@@ -64,7 +65,8 @@ func (o RedHatBase) FillWithOval(r *models.ScanResult) (err error) {
}
}
}
return nil
return nCVEs, nil
}
var kernelRelatedPackNames = map[string]bool{
@@ -98,7 +100,7 @@ var kernelRelatedPackNames = map[string]bool{
"python-perf": true,
}
func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) {
func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) {
ctype := models.NewCveContentType(o.family)
for _, cve := range defPacks.def.Advisory.Cves {
ovalContent := *o.convertToModel(cve.CveID, &defPacks.def)
@@ -107,9 +109,10 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) {
util.Log.Debugf("%s is newly detected by OVAL", cve.CveID)
vinfo = models.VulnInfo{
CveID: cve.CveID,
Confidence: models.OvalMatch,
Confidences: models.Confidences{models.OvalMatch},
CveContents: models.NewCveContents(ovalContent),
}
nCVEs++
} else {
cveContents := vinfo.CveContents
if v, ok := vinfo.CveContents[ctype]; ok {
@@ -125,22 +128,24 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) {
cveContents = models.CveContents{}
}
if vinfo.Confidence.Score < models.OvalMatch.Score {
vinfo.Confidence = models.OvalMatch
}
vinfo.Confidences.AppendIfMissing(models.OvalMatch)
cveContents[ctype] = ovalContent
vinfo.CveContents = cveContents
}
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, pack := range vinfo.AffectedPackages {
notFixedYet, _ := defPacks.actuallyAffectedPackNames[pack.Name]
defPacks.actuallyAffectedPackNames[pack.Name] = notFixedYet
if nfy, ok := defPacks.actuallyAffectedPackNames[pack.Name]; !ok {
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
} else if nfy {
defPacks.actuallyAffectedPackNames[pack.Name] = true
}
}
vinfo.AffectedPackages = defPacks.toPackStatuses()
vinfo.AffectedPackages.Sort()
r.ScannedCves[cve.CveID] = vinfo
}
return
}
func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
@@ -165,20 +170,32 @@ func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *mo
severity = cve.Impact
}
sev2, sev3 := "", ""
if score2 != 0 {
sev2 = severity
}
if score3 != 0 {
sev3 = severity
}
// CWE-ID in RedHat OVAL may have multiple cweIDs separated by space
cwes := strings.Fields(cve.Cwe)
return &models.CveContent{
Type: models.NewCveContentType(o.family),
CveID: cve.CveID,
Title: def.Title,
Summary: def.Description,
Severity: severity,
Cvss2Score: score2,
Cvss2Vector: vec2,
Cvss3Score: score3,
Cvss3Vector: vec3,
References: refs,
CweID: cve.Cwe,
Published: def.Advisory.Issued,
LastModified: def.Advisory.Updated,
Type: models.NewCveContentType(o.family),
CveID: cve.CveID,
Title: def.Title,
Summary: def.Description,
Cvss2Score: score2,
Cvss2Vector: vec2,
Cvss2Severity: sev2,
Cvss3Score: score3,
Cvss3Vector: vec3,
Cvss3Severity: sev3,
References: refs,
CweIDs: cwes,
Published: def.Advisory.Issued,
LastModified: def.Advisory.Updated,
}
}
return nil
@@ -207,7 +224,7 @@ func (o RedHatBase) parseCvss3(scoreVector string) (score float64, vector string
if score, err = strconv.ParseFloat(ss[0], 64); err != nil {
return 0, ""
}
return score, strings.Join(ss[1:], "/")
return score, fmt.Sprintf("CVSS:3.0/%s", ss[1])
}
return 0, ""
}

View File

@@ -72,7 +72,7 @@ func TestParseCvss3(t *testing.T) {
in: "5.6/CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
out: out{
score: 5.6,
vector: "AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
vector: "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
},
},
{

View File

@@ -21,6 +21,7 @@ import (
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
ovalmodels "github.com/kotakanbe/goval-dictionary/models"
)
@@ -40,15 +41,15 @@ func NewSUSE() SUSE {
}
// FillWithOval returns scan result after updating CVE info by OVAL
func (o SUSE) FillWithOval(r *models.ScanResult) (err error) {
func (o SUSE) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
var relatedDefs ovalResult
if o.isFetchViaHTTP() {
if o.IsFetchViaHTTP() {
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
return err
return 0, err
}
} else {
if relatedDefs, err = getDefsByPackNameFromOvalDB(r); err != nil {
return err
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
return 0, err
}
}
for _, defPacks := range relatedDefs.entries {
@@ -61,7 +62,7 @@ func (o SUSE) FillWithOval(r *models.ScanResult) (err error) {
vuln.CveContents[models.SUSE] = cont
}
}
return nil
return len(relatedDefs.entries), nil
}
func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
@@ -72,7 +73,7 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
util.Log.Debugf("%s is newly detected by OVAL", defPacks.def.Title)
vinfo = models.VulnInfo{
CveID: defPacks.def.Title,
Confidence: models.OvalMatch,
Confidences: models.Confidences{models.OvalMatch},
CveContents: models.NewCveContents(ovalContent),
}
} else {
@@ -84,17 +85,14 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
util.Log.Debugf("%s is also detected by OVAL", defPacks.def.Title)
cveContents = models.CveContents{}
}
if vinfo.Confidence.Score < models.OvalMatch.Score {
vinfo.Confidence = models.OvalMatch
}
vinfo.Confidences.AppendIfMissing(models.OvalMatch)
cveContents[ctype] = ovalContent
vinfo.CveContents = cveContents
}
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, pack := range vinfo.AffectedPackages {
notFixedYet, _ := defPacks.actuallyAffectedPackNames[pack.Name]
defPacks.actuallyAffectedPackNames[pack.Name] = notFixedYet
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
}
vinfo.AffectedPackages = defPacks.toPackStatuses()
vinfo.AffectedPackages.Sort()

View File

@@ -126,7 +126,7 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
select {
case req := <-reqChan:
url, err := util.URLPathJoin(
config.Conf.OvalDBURL,
config.Conf.OvalDict.URL,
"packs",
r.Family,
r.Release,
@@ -216,20 +216,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
}
}
func getDefsByPackNameFromOvalDB(r *models.ScanResult) (relatedDefs ovalResult, err error) {
path := config.Conf.OvalDBURL
if config.Conf.OvalDBType == "sqlite3" {
path = config.Conf.OvalDBPath
}
util.Log.Debugf("Open oval-dictionary db (%s): %s", config.Conf.OvalDBType, path)
var ovaldb db.DB
if ovaldb, _, err = db.NewDB(r.Family, config.Conf.OvalDBType,
path, config.Conf.DebugSQL); err != nil {
return
}
defer ovaldb.CloseDB()
func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDefs ovalResult, err error) {
requests := []request{}
for _, pack := range r.Packages {
requests = append(requests, request{
@@ -249,9 +236,9 @@ func getDefsByPackNameFromOvalDB(r *models.ScanResult) (relatedDefs ovalResult,
}
for _, req := range requests {
definitions, err := ovaldb.GetByPackName(r.Release, req.packName)
definitions, err := driver.GetByPackName(r.Release, req.packName)
if err != nil {
return relatedDefs, fmt.Errorf("Failed to get %s OVAL info by package name: %v", r.Family, err)
return relatedDefs, fmt.Errorf("Failed to get %s OVAL info by package: %#v, err: %s", r.Family, req, err)
}
for _, def := range definitions {
affected, notFixedYet := isOvalDefAffected(def, req, r.Family, r.RunningKernel)
@@ -316,8 +303,12 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
// Unable to judge whether fixed or not fixed of src package(Ubuntu, Debian)
return true, false
}
// `offline` or `fast` scan mode can't get a updatable version.
// In these mode, the blow field was set empty.
// Vuls can not judge fixed or unfixed.
if req.NewVersionRelease == "" {
return true, true
return true, false
}
// compare version: newVer vs oval

View File

@@ -319,7 +319,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: false,
},
// RedHat
// 5 RedHat
{
in: in{
family: "redhat",
@@ -337,64 +337,16 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.7",
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.7",
NewVersionRelease: "",
},
},
affected: true,
notFixedYet: true,
},
{
in: in{
family: "redhat",
def: ovalmodels.Definition{
AffectedPacks: []ovalmodels.Package{
{
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.8",
},
},
affected: false,
notFixedYet: false,
},
{
in: in{
family: "redhat",
def: ovalmodels.Definition{
AffectedPacks: []ovalmodels.Package{
{
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.9",
},
},
affected: false,
notFixedYet: false,
},
// 6 RedHat
{
in: in{
family: "redhat",
@@ -421,6 +373,86 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: true,
},
// 7 RedHat
{
in: in{
family: "redhat",
def: ovalmodels.Definition{
AffectedPacks: []ovalmodels.Package{
{
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.8",
},
},
affected: false,
notFixedYet: false,
},
// 8 RedHat
{
in: in{
family: "redhat",
def: ovalmodels.Definition{
AffectedPacks: []ovalmodels.Package{
{
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.9",
},
},
affected: false,
notFixedYet: false,
},
// 9 RedHat
{
in: in{
family: "redhat",
def: ovalmodels.Definition{
AffectedPacks: []ovalmodels.Package{
{
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.7",
},
},
affected: true,
notFixedYet: true,
},
// 10 RedHat
{
in: in{
family: "redhat",
@@ -447,6 +479,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: false,
},
// 11 RedHat
{
in: in{
family: "redhat",
@@ -456,8 +489,7 @@ func TestIsOvalDefAffected(t *testing.T) {
Name: "a",
NotFixedYet: false,
},
{
Name: "b",
{Name: "b",
NotFixedYet: false,
Version: "0:1.2.3-45.el6_7.8",
},
@@ -473,6 +505,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: false,
},
// 12 RedHat
{
in: in{
family: "redhat",
@@ -498,6 +531,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// 13 RedHat
{
in: in{
family: "redhat",
@@ -523,7 +557,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// CentOS
// 14 CentOS
{
in: in{
family: "centos",
@@ -541,14 +575,16 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
req: request{
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.7",
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.7",
NewVersionRelease: "",
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
},
// 15
{
in: in{
family: "centos",
@@ -574,6 +610,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// 16
{
in: in{
family: "centos",
@@ -599,6 +636,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// 17
{
in: in{
family: "centos",
@@ -625,6 +663,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: true,
},
// 18
{
in: in{
family: "centos",
@@ -651,6 +690,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: false,
},
// 19
{
in: in{
family: "centos",
@@ -677,6 +717,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: true,
notFixedYet: false,
},
// 20
{
in: in{
family: "centos",
@@ -702,6 +743,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// 21
{
in: in{
family: "centos",
@@ -727,7 +769,7 @@ func TestIsOvalDefAffected(t *testing.T) {
affected: false,
notFixedYet: false,
},
// TODO: If vuls support Scientific, replace "centos" below to "scientific".
// 22
{
in: in{
family: "centos",
@@ -751,7 +793,7 @@ func TestIsOvalDefAffected(t *testing.T) {
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
},
{
in: in{