Change model ScanResult.ScannedCves.AffectedPackages

This commit is contained in:
kota kanbe
2017-08-17 12:18:06 +09:00
parent b5d4d27312
commit 6129ac7bd4
15 changed files with 121 additions and 76 deletions

View File

@@ -92,15 +92,14 @@ func (ps Packages) FindOne(f func(Package) bool) (string, Package, bool) {
// Package has installed packages.
type Package struct {
Name string
Version string
Release string
NewVersion string
NewRelease string
Arch string
Repository string
Changelog Changelog
NotFixedYet bool // Ubuntu OVAL Only
Name string
Version string
Release string
NewVersion string
NewRelease string
Arch string
Repository string
Changelog Changelog
}
// FormatVer returns package version-release

View File

@@ -104,11 +104,28 @@ func (v VulnInfos) FormatCveSummary() string {
m["High"], m["Medium"], m["Low"], m["Unknown"])
}
// PackageStatuses is a list of PackageStatus
type PackageStatuses []PackageStatus
// Sort by Name
func (p PackageStatuses) Sort() {
sort.Slice(p, func(i, j int) bool {
return p[i].Name < p[j].Name
})
return
}
// PackageStatus has name and other status abount the package
type PackageStatus struct {
Name string
NotFixedYet bool
}
// VulnInfo has a vulnerability information and unsecure packages
type VulnInfo struct {
CveID string
Confidence Confidence
PackageNames []string
AffectedPackages PackageStatuses
DistroAdvisories []DistroAdvisory // for Aamazon, RHEL, FreeBSD
CpeNames []string
CveContents CveContents
@@ -547,8 +564,8 @@ func (v *VulnInfo) NilToEmpty() *VulnInfo {
if v.DistroAdvisories == nil {
v.DistroAdvisories = []DistroAdvisory{}
}
if v.PackageNames == nil {
v.PackageNames = []string{}
if v.AffectedPackages == nil {
v.AffectedPackages = PackageStatuses{}
}
if v.CveContents == nil {
v.CveContents = NewCveContents()

View File

@@ -910,3 +910,27 @@ func TestFormatMaxCvssScore(t *testing.T) {
}
}
}
func TestSortPackageStatues(t *testing.T) {
var tests = []struct {
in PackageStatuses
out PackageStatuses
}{
{
in: PackageStatuses{
{Name: "b"},
{Name: "a"},
},
out: PackageStatuses{
{Name: "a"},
{Name: "b"},
},
},
}
for _, tt := range tests {
tt.in.Sort()
if !reflect.DeepEqual(tt.in, tt.out) {
t.Errorf("\nexpected: %v\n actual: %v\n", tt.out, tt.in)
}
}
}

View File

@@ -18,8 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package oval
import (
"sort"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
@@ -95,11 +93,11 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
}
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, name := range vinfo.PackageNames {
defPacks.actuallyAffectedPackNames[name] = true
for _, pack := range vinfo.AffectedPackages {
defPacks.actuallyAffectedPackNames[pack.Name] = true
}
vinfo.PackageNames = defPacks.packNames()
sort.Strings(vinfo.PackageNames)
vinfo.AffectedPackages = defPacks.toPackStatuses()
vinfo.AffectedPackages.Sort()
r.ScannedCves[defPacks.def.Debian.CveID] = vinfo
}

View File

@@ -36,7 +36,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
in: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
PackageNames: []string{"packA"},
AffectedPackages: models.PackageStatuses{{Name: "packA"}},
},
},
},
@@ -53,9 +53,9 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
out: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
PackageNames: []string{
"packA",
"packB",
AffectedPackages: models.PackageStatuses{
{Name: "packA"},
{Name: "packB"},
},
},
},
@@ -66,8 +66,8 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
util.Log = util.NewCustomLogger(config.ServerInfo{})
for i, tt := range tests {
Debian{}.update(&tt.in, tt.defPacks)
e := tt.out.ScannedCves["CVE-2000-1000"].PackageNames
a := tt.in.ScannedCves["CVE-2000-1000"].PackageNames
e := tt.out.ScannedCves["CVE-2000-1000"].AffectedPackages
a := tt.in.ScannedCves["CVE-2000-1000"].AffectedPackages
if !reflect.DeepEqual(a, e) {
t.Errorf("[%d] expected: %v\n actual: %v\n", i, e, a)
}

View File

@@ -19,7 +19,6 @@ package oval
import (
"fmt"
"sort"
"strconv"
"strings"
@@ -98,11 +97,11 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) {
}
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
for _, name := range vinfo.PackageNames {
defPacks.actuallyAffectedPackNames[name] = true
for _, pack := range vinfo.AffectedPackages {
defPacks.actuallyAffectedPackNames[pack.Name] = true
}
vinfo.PackageNames = defPacks.packNames()
sort.Strings(vinfo.PackageNames)
vinfo.AffectedPackages = defPacks.toPackStatuses()
vinfo.AffectedPackages.Sort()
r.ScannedCves[cve.CveID] = vinfo
}
}

View File

@@ -102,7 +102,7 @@ func TestPackNamesOfUpdate(t *testing.T) {
in: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
PackageNames: []string{"packA"},
AffectedPackages: models.PackageStatuses{{Name: "packA"}},
},
},
},
@@ -123,9 +123,9 @@ func TestPackNamesOfUpdate(t *testing.T) {
out: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
PackageNames: []string{
"packA",
"packB",
AffectedPackages: models.PackageStatuses{
{Name: "packA"},
{Name: "packB"},
},
},
},
@@ -136,8 +136,8 @@ func TestPackNamesOfUpdate(t *testing.T) {
util.Log = util.NewCustomLogger(config.ServerInfo{})
for i, tt := range tests {
RedHat{}.update(&tt.in, tt.defPacks)
e := tt.out.ScannedCves["CVE-2000-1000"].PackageNames
a := tt.in.ScannedCves["CVE-2000-1000"].PackageNames
e := tt.out.ScannedCves["CVE-2000-1000"].AffectedPackages
a := tt.in.ScannedCves["CVE-2000-1000"].AffectedPackages
if !reflect.DeepEqual(a, e) {
t.Errorf("[%d] expected: %v\n actual: %v\n", i, e, a)
}

View File

@@ -44,9 +44,9 @@ type defPacks struct {
actuallyAffectedPackNames map[string]bool
}
func (e defPacks) packNames() (names []string) {
func (e defPacks) toPackStatuses() (ps models.PackageStatuses) {
for k := range e.actuallyAffectedPackNames {
names = append(names, k)
ps = append(ps, models.PackageStatus{Name: k})
}
return
}
@@ -192,7 +192,7 @@ func httpGet(url string, pack *models.Package, resChan chan<- response, errChan
}
func getDefsByPackNameFromOvalDB(family, osRelease string,
packs models.Packages) (relatedDefs ovalResult, err error) {
installedPacks models.Packages) (relatedDefs ovalResult, err error) {
ovallog.Initialize(config.Conf.LogDir)
path := config.Conf.OvalDBURL
@@ -211,7 +211,7 @@ func getDefsByPackNameFromOvalDB(family, osRelease string,
return
}
defer ovaldb.CloseDB()
for _, pack := range packs {
for _, pack := range installedPacks {
definitions, err := ovaldb.GetByPackName(osRelease, pack.Name)
if err != nil {
return relatedDefs, fmt.Errorf("Failed to get %s OVAL info by package name: %v", family, err)

View File

@@ -174,12 +174,12 @@ func toSlackAttachments(r models.ScanResult) (attaches []*attachment) {
for _, vinfo := range vinfos {
curent := []string{}
for _, name := range vinfo.PackageNames {
if p, ok := r.Packages[name]; ok {
for _, affected := range vinfo.AffectedPackages {
if p, ok := r.Packages[affected.Name]; ok {
curent = append(curent,
fmt.Sprintf("%s-%s", p.Name, p.FormatVer()))
} else {
curent = append(curent, name)
curent = append(curent, affected.Name)
}
}
for _, n := range vinfo.CpeNames {
@@ -187,8 +187,8 @@ func toSlackAttachments(r models.ScanResult) (attaches []*attachment) {
}
new := []string{}
for _, name := range vinfo.PackageNames {
if p, ok := r.Packages[name]; ok {
for _, affected := range vinfo.AffectedPackages {
if p, ok := r.Packages[affected.Name]; ok {
new = append(new, p.FormatNewVer())
} else {
new = append(new, "?")

View File

@@ -713,8 +713,8 @@ func setChangelogLayout(g *gocui.Gui) error {
lines = append(lines, adv.Format())
}
for _, name := range vinfo.PackageNames {
pack := currentScanResult.Packages[name]
for _, affected := range vinfo.AffectedPackages {
pack := currentScanResult.Packages[affected.Name]
for _, p := range currentScanResult.Packages {
if pack.Name == p.Name {
lines = append(lines, p.FormatChangelog(), "\n")
@@ -763,10 +763,10 @@ func detailLines() (string, error) {
vinfo := vinfos[currentVinfo]
packsVer := []string{}
sort.Strings(vinfo.PackageNames)
for _, name := range vinfo.PackageNames {
vinfo.AffectedPackages.Sort()
for _, affected := range vinfo.AffectedPackages {
// packages detected by OVAL may not be actually installed
if pack, ok := r.Packages[name]; ok {
if pack, ok := r.Packages[affected.Name]; ok {
packsVer = append(packsVer, pack.FormatVersionFromTo())
}
}

View File

@@ -216,9 +216,9 @@ No CVE-IDs are found in updatable packages.
}
packsVer := []string{}
sort.Strings(vuln.PackageNames)
for _, name := range vuln.PackageNames {
if pack, ok := r.Packages[name]; ok {
vuln.AffectedPackages.Sort()
for _, affected := range vuln.AffectedPackages {
if pack, ok := r.Packages[affected.Name]; ok {
packsVer = append(packsVer, pack.FormatVersionFromTo())
}
}
@@ -322,9 +322,9 @@ func diff(curResults, preResults models.ScanResults) (diffed models.ScanResults,
current.ScannedCves = getDiffCves(previous, current)
packages := models.Packages{}
for _, s := range current.ScannedCves {
for _, name := range s.PackageNames {
p := current.Packages[name]
packages[name] = p
for _, affected := range s.AffectedPackages {
p := current.Packages[affected.Name]
packages[affected.Name] = p
}
}
current.Packages = packages

View File

@@ -183,13 +183,13 @@ func TestDiff(t *testing.T) {
ScannedCves: models.VulnInfos{
"CVE-2012-6702": {
CveID: "CVE-2012-6702",
PackageNames: []string{"libexpat1"},
AffectedPackages: models.PackageStatuses{{Name: "libexpat1"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},
"CVE-2014-9761": {
CveID: "CVE-2014-9761",
PackageNames: []string{"libc-bin"},
AffectedPackages: models.PackageStatuses{{Name: "libc-bin"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},
@@ -208,13 +208,13 @@ func TestDiff(t *testing.T) {
ScannedCves: models.VulnInfos{
"CVE-2012-6702": {
CveID: "CVE-2012-6702",
PackageNames: []string{"libexpat1"},
AffectedPackages: models.PackageStatuses{{Name: "libexpat1"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},
"CVE-2014-9761": {
CveID: "CVE-2014-9761",
PackageNames: []string{"libc-bin"},
AffectedPackages: models.PackageStatuses{{Name: "libc-bin"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},
@@ -245,7 +245,7 @@ func TestDiff(t *testing.T) {
ScannedCves: models.VulnInfos{
"CVE-2016-6662": {
CveID: "CVE-2016-6662",
PackageNames: []string{"mysql-libs"},
AffectedPackages: models.PackageStatuses{{Name: "mysql-libs"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},
@@ -283,7 +283,7 @@ func TestDiff(t *testing.T) {
ScannedCves: models.VulnInfos{
"CVE-2016-6662": {
CveID: "CVE-2016-6662",
PackageNames: []string{"mysql-libs"},
AffectedPackages: models.PackageStatuses{{Name: "mysql-libs"}},
DistroAdvisories: []models.DistroAdvisory{},
CpeNames: []string{},
},

View File

@@ -508,10 +508,15 @@ func (o *debian) scanVulnInfos(updatablePacks models.Packages, meta *cache.Meta)
o.log.Debugf("%d Cves are found. cves: %v", len(cveIDs), cveIDs)
vinfos := models.VulnInfos{}
for cveID, names := range cvePackages {
affected := models.PackageStatuses{}
for _, n := range names {
affected = append(affected, models.PackageStatus{Name: n})
}
vinfos[cveID.CveID] = models.VulnInfo{
CveID: cveID.CveID,
Confidence: cveID.Confidence,
PackageNames: names,
CveID: cveID.CveID,
Confidence: cveID.Confidence,
AffectedPackages: affected,
}
}

View File

@@ -164,13 +164,15 @@ func (o *bsd) scanUnsecurePackages() (models.VulnInfos, error) {
})
}
names := []string{}
affected := models.PackageStatuses{}
for name := range packs {
names = append(names, name)
affected = append(affected, models.PackageStatus{
Name: name,
})
}
vinfos[cveID] = models.VulnInfo{
CveID: cveID,
PackageNames: names,
AffectedPackages: affected,
DistroAdvisories: disAdvs,
Confidence: models.PkgAuditMatch,
}

View File

@@ -610,13 +610,13 @@ func (o *redhat) scanCveIDsInChangelog(updatable models.Packages) (models.VulnIn
for name, cveIDs := range packCveIDs {
for _, cid := range cveIDs {
if v, ok := vinfos[cid]; ok {
v.PackageNames = append(v.PackageNames, name)
v.AffectedPackages = append(v.AffectedPackages, models.PackageStatus{Name: name})
vinfos[cid] = v
} else {
vinfos[cid] = models.VulnInfo{
CveID: cid,
PackageNames: []string{name},
Confidence: models.ChangelogExactMatch,
CveID: cid,
AffectedPackages: models.PackageStatuses{{Name: name}},
Confidence: models.ChangelogExactMatch,
}
}
}
@@ -703,18 +703,19 @@ func (o *redhat) scanCveIDsByCommands(updatable models.Packages) (models.VulnInf
packs := dict[advIDCveIDs.DistroAdvisory.AdvisoryID]
for _, pack := range packs {
vinfo.PackageNames = append(vinfo.PackageNames, pack.Name)
vinfo.AffectedPackages = append(vinfo.AffectedPackages,
models.PackageStatus{Name: pack.Name})
}
} else {
names := []string{}
packs := dict[advIDCveIDs.DistroAdvisory.AdvisoryID]
for _, pack := range packs {
names = append(names, pack.Name)
affected := models.PackageStatuses{}
for _, p := range packs {
affected = append(affected, models.PackageStatus{Name: p.Name})
}
vinfo = models.VulnInfo{
CveID: cveID,
DistroAdvisories: []models.DistroAdvisory{advIDCveIDs.DistroAdvisory},
PackageNames: names,
AffectedPackages: affected,
Confidence: models.YumUpdateSecurityMatch,
}
}