From 464d523c4201c4a1fb925dc24ebea06ddd1ccfd7 Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Wed, 8 Apr 2020 21:26:34 +0900 Subject: [PATCH] Display fixed-in version for each package in report (#801) * refactor(model): PackageFixStatus.Name to BinName * refacotr(oval): change var name * feat(report): Add FixedIn in JSON * refactor(tui): chage args * display fixedin in report * refactor(model): change fileld name * remove unused field of PackageFixStatus --- models/packages.go | 15 +++-- models/packages_test.go | 122 ++++++++++++++++++++++++++++++++++++++++ models/vulninfos.go | 7 ++- oval/debian.go | 35 ++++++++---- oval/debian_test.go | 11 ++-- oval/redhat.go | 14 +++-- oval/redhat_test.go | 7 ++- oval/suse.go | 5 +- oval/util.go | 79 ++++++++++++++++++-------- oval/util_test.go | 121 ++++++++++++++++++++++++++++----------- report/tui.go | 6 +- report/util.go | 6 +- scan/redhatbase_test.go | 4 +- 13 files changed, 336 insertions(+), 96 deletions(-) diff --git a/models/packages.go b/models/packages.go index c5f3c537..628d521d 100644 --- a/models/packages.go +++ b/models/packages.go @@ -120,18 +120,23 @@ func (p Package) FormatNewVer() string { } // FormatVersionFromTo formats installed and new package version -func (p Package) FormatVersionFromTo(notFixedYet bool, status string) string { +func (p Package) FormatVersionFromTo(stat PackageFixStatus) string { to := p.FormatNewVer() - if notFixedYet { - if status != "" { - to = status + if stat.NotFixedYet { + if stat.FixState != "" { + to = stat.FixState } else { to = "Not Fixed Yet" } } else if p.NewVersion == "" { to = "Unknown" } - return fmt.Sprintf("%s-%s -> %s", p.Name, p.FormatVer(), to) + var fixedIn string + if stat.FixedIn != "" { + fixedIn = fmt.Sprintf(" (FixedIn: %s)", stat.FixedIn) + } + return fmt.Sprintf("%s-%s -> %s%s", + p.Name, p.FormatVer(), to, fixedIn) } // FormatChangelog formats the changelog diff --git a/models/packages_test.go b/models/packages_test.go index ee600135..6209e34e 100644 --- a/models/packages_test.go +++ b/models/packages_test.go @@ -175,3 +175,125 @@ func TestFindByBinName(t *testing.T) { } } } + +func TestPackage_FormatVersionFromTo(t *testing.T) { + type fields struct { + Name string + Version string + Release string + NewVersion string + NewRelease string + Arch string + Repository string + Changelog Changelog + AffectedProcs []AffectedProcess + NeedRestartProcs []NeedRestartProcess + } + type args struct { + stat PackageFixStatus + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "fixed", + fields: fields{ + Name: "packA", + Version: "1.0.0", + Release: "a", + NewVersion: "1.0.1", + NewRelease: "b", + }, + args: args{ + stat: PackageFixStatus{ + NotFixedYet: false, + FixedIn: "1.0.1-b", + }, + }, + want: "packA-1.0.0-a -> 1.0.1-b (FixedIn: 1.0.1-b)", + }, + { + name: "nfy", + fields: fields{ + Name: "packA", + Version: "1.0.0", + Release: "a", + }, + args: args{ + stat: PackageFixStatus{ + NotFixedYet: true, + }, + }, + want: "packA-1.0.0-a -> Not Fixed Yet", + }, + { + name: "nfy", + fields: fields{ + Name: "packA", + Version: "1.0.0", + Release: "a", + }, + args: args{ + stat: PackageFixStatus{ + NotFixedYet: false, + FixedIn: "1.0.1-b", + }, + }, + want: "packA-1.0.0-a -> Unknown (FixedIn: 1.0.1-b)", + }, + { + name: "nfy2", + fields: fields{ + Name: "packA", + Version: "1.0.0", + Release: "a", + }, + args: args{ + stat: PackageFixStatus{ + NotFixedYet: true, + FixedIn: "1.0.1-b", + FixState: "open", + }, + }, + want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)", + }, + { + name: "nfy3", + fields: fields{ + Name: "packA", + Version: "1.0.0", + Release: "a", + }, + args: args{ + stat: PackageFixStatus{ + NotFixedYet: true, + FixedIn: "1.0.1-b", + FixState: "open", + }, + }, + want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := Package{ + Name: tt.fields.Name, + Version: tt.fields.Version, + Release: tt.fields.Release, + NewVersion: tt.fields.NewVersion, + NewRelease: tt.fields.NewRelease, + Arch: tt.fields.Arch, + Repository: tt.fields.Repository, + Changelog: tt.fields.Changelog, + AffectedProcs: tt.fields.AffectedProcs, + NeedRestartProcs: tt.fields.NeedRestartProcs, + } + if got := p.FormatVersionFromTo(tt.args.stat); got != tt.want { + t.Errorf("Package.FormatVersionFromTo() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/models/vulninfos.go b/models/vulninfos.go index 6f39c0e5..6418efa6 100644 --- a/models/vulninfos.go +++ b/models/vulninfos.go @@ -136,9 +136,10 @@ func (ps PackageFixStatuses) Sort() { // PackageFixStatus has name and other status abount the package type PackageFixStatus struct { - Name string `json:"name"` - NotFixedYet bool `json:"notFixedYet"` - FixState string `json:"fixState"` + Name string `json:"name,omitempty"` + NotFixedYet bool `json:"notFixedYet,omitempty"` + FixState string `json:"fixState,omitempty"` + FixedIn string `json:"fixedIn,omitempty"` } // VulnInfo has a vulnerability information and unsecure packages diff --git a/oval/debian.go b/oval/debian.go index e063230a..a60dff35 100644 --- a/oval/debian.go +++ b/oval/debian.go @@ -42,17 +42,28 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) { vinfo.CveContents = cveContents } - // uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames) + // uniq(vinfo.PackNames + defPacks.binpkgStat) for _, pack := range vinfo.AffectedPackages { - defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet + defPacks.binpkgFixstat[pack.Name] = fixStat{ + notFixedYet: pack.NotFixedYet, + fixedIn: pack.FixedIn, + isSrcPack: false, + } } - // update notFixedYet of SrcPackage - for binName := range defPacks.actuallyAffectedPackNames { + // Update package status of source packages. + // In the case of Debian based Linux, sometimes source package name is difined as affected package in OVAL. + // To display binary package name showed in apt-get, need to convert source name to binary name. + for binName := range defPacks.binpkgFixstat { if srcPack, ok := r.SrcPackages.FindByBinName(binName); ok { for _, p := range defPacks.def.AffectedPacks { if p.Name == srcPack.Name { - defPacks.actuallyAffectedPackNames[binName] = p.NotFixedYet + defPacks.binpkgFixstat[binName] = fixStat{ + notFixedYet: p.NotFixedYet, + fixedIn: p.Version, + isSrcPack: true, + srcPackName: srcPack.Name, + } } } } @@ -134,9 +145,9 @@ func (o Debian) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err for _, defPacks := range relatedDefs.entries { // Remove "linux" added above for oval search // linux is not a real package name (key of affected packages in OVAL) - if notFixedYet, ok := defPacks.actuallyAffectedPackNames["linux"]; ok { - defPacks.actuallyAffectedPackNames[linuxImage] = notFixedYet - delete(defPacks.actuallyAffectedPackNames, "linux") + if notFixedYet, ok := defPacks.binpkgFixstat["linux"]; ok { + defPacks.binpkgFixstat[linuxImage] = notFixedYet + delete(defPacks.binpkgFixstat, "linux") for i, p := range defPacks.def.AffectedPacks { if p.Name == "linux" { p.Name = linuxImage @@ -309,11 +320,11 @@ func (o Ubuntu) fillWithOval(driver db.DB, r *models.ScanResult, kernelNamesInOv } for _, defPacks := range relatedDefs.entries { - // Remove "linux" added above to search for oval + // Remove "linux" added above for searching oval // "linux" is not a real package name (key of affected packages in OVAL) - if nfy, ok := defPacks.actuallyAffectedPackNames[kernelPkgInOVAL]; isOVALKernelPkgAdded && ok { - defPacks.actuallyAffectedPackNames[linuxImage] = nfy - delete(defPacks.actuallyAffectedPackNames, kernelPkgInOVAL) + if nfy, ok := defPacks.binpkgFixstat[kernelPkgInOVAL]; isOVALKernelPkgAdded && ok { + defPacks.binpkgFixstat[linuxImage] = nfy + delete(defPacks.binpkgFixstat, kernelPkgInOVAL) for i, p := range defPacks.def.AffectedPacks { if p.Name == kernelPkgInOVAL { p.Name = linuxImage diff --git a/oval/debian_test.go b/oval/debian_test.go index 913b8b61..b6b06f86 100644 --- a/oval/debian_test.go +++ b/oval/debian_test.go @@ -33,8 +33,11 @@ func TestPackNamesOfUpdateDebian(t *testing.T) { CveID: "CVE-2000-1000", }, }, - actuallyAffectedPackNames: map[string]bool{ - "packB": true, + binpkgFixstat: map[string]fixStat{ + "packB": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, }, }, out: models.ScanResult{ @@ -42,7 +45,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) { "CVE-2000-1000": models.VulnInfo{ AffectedPackages: models.PackageFixStatuses{ {Name: "packA"}, - {Name: "packB", NotFixedYet: true}, + {Name: "packB", NotFixedYet: true, FixedIn: "1.0.0"}, {Name: "packC"}, }, }, @@ -57,7 +60,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) { 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) + t.Errorf("[%d] expected: %#v\n actual: %#v\n", i, e, a) } } } diff --git a/oval/redhat.go b/oval/redhat.go index cf816278..c554adf4 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -120,10 +120,16 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) // uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames) for _, pack := range vinfo.AffectedPackages { - if nfy, ok := defPacks.actuallyAffectedPackNames[pack.Name]; !ok { - defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet - } else if nfy { - defPacks.actuallyAffectedPackNames[pack.Name] = true + if stat, ok := defPacks.binpkgFixstat[pack.Name]; !ok { + defPacks.binpkgFixstat[pack.Name] = fixStat{ + notFixedYet: pack.NotFixedYet, + fixedIn: pack.FixedIn, + } + } else if stat.notFixedYet { + defPacks.binpkgFixstat[pack.Name] = fixStat{ + notFixedYet: true, + fixedIn: pack.FixedIn, + } } } vinfo.AffectedPackages = defPacks.toPackStatuses() diff --git a/oval/redhat_test.go b/oval/redhat_test.go index 8d6e2123..9631e3f4 100644 --- a/oval/redhat_test.go +++ b/oval/redhat_test.go @@ -110,8 +110,11 @@ func TestPackNamesOfUpdate(t *testing.T) { }, }, }, - actuallyAffectedPackNames: map[string]bool{ - "packB": true, + binpkgFixstat: map[string]fixStat{ + "packB": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, }, }, out: models.ScanResult{ diff --git a/oval/suse.go b/oval/suse.go index b094a4a1..fff224d6 100644 --- a/oval/suse.go +++ b/oval/suse.go @@ -75,7 +75,10 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) { // uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames) for _, pack := range vinfo.AffectedPackages { - defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet + defPacks.binpkgFixstat[pack.Name] = fixStat{ + notFixedYet: pack.NotFixedYet, + fixedIn: pack.FixedIn, + } } vinfo.AffectedPackages = defPacks.toPackStatuses() vinfo.AffectedPackages.Sort() diff --git a/oval/util.go b/oval/util.go index 7510b52d..0ee65fbc 100644 --- a/oval/util.go +++ b/oval/util.go @@ -27,32 +27,42 @@ type defPacks struct { def ovalmodels.Definition // BinaryPackageName : NotFixedYet - actuallyAffectedPackNames map[string]bool + binpkgFixstat map[string]fixStat +} + +type fixStat struct { + notFixedYet bool + fixedIn string + isSrcPack bool + srcPackName string } func (e defPacks) toPackStatuses() (ps models.PackageFixStatuses) { - for name, notFixedYet := range e.actuallyAffectedPackNames { + for name, stat := range e.binpkgFixstat { ps = append(ps, models.PackageFixStatus{ Name: name, - NotFixedYet: notFixedYet, + NotFixedYet: stat.notFixedYet, + FixedIn: stat.fixedIn, }) } return } -func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, notFixedYet bool) (upserted bool) { +func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, fstat fixStat) (upserted bool) { // alpine's entry is empty since Alpine secdb is not OVAL format if def.DefinitionID != "" { for i, entry := range e.entries { if entry.def.DefinitionID == def.DefinitionID { - e.entries[i].actuallyAffectedPackNames[packName] = notFixedYet + e.entries[i].binpkgFixstat[packName] = fstat return true } } } e.entries = append(e.entries, defPacks{ - def: def, - actuallyAffectedPackNames: map[string]bool{packName: notFixedYet}, + def: def, + binpkgFixstat: map[string]fixStat{ + packName: fstat, + }, }) return false @@ -134,17 +144,27 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) ( select { case res := <-resChan: for _, def := range res.defs { - affected, notFixedYet := isOvalDefAffected(def, res.request, r.Family, r.RunningKernel) + affected, notFixedYet, fixedIn := isOvalDefAffected(def, res.request, r.Family, r.RunningKernel) if !affected { continue } if res.request.isSrcPack { for _, n := range res.request.binaryPackNames { - relatedDefs.upsert(def, n, false) + fs := fixStat{ + srcPackName: res.request.packName, + isSrcPack: true, + notFixedYet: notFixedYet, + fixedIn: fixedIn, + } + relatedDefs.upsert(def, n, fs) } } else { - relatedDefs.upsert(def, res.request.packName, notFixedYet) + fs := fixStat{ + notFixedYet: notFixedYet, + fixedIn: fixedIn, + } + relatedDefs.upsert(def, res.request.packName, fs) } } case err := <-errChan: @@ -227,17 +247,27 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef return relatedDefs, xerrors.Errorf("Failed to get %s OVAL info by package: %#v, err: %w", r.Family, req, err) } for _, def := range definitions { - affected, notFixedYet := isOvalDefAffected(def, req, r.Family, r.RunningKernel) + affected, notFixedYet, fixedIn := isOvalDefAffected(def, req, r.Family, r.RunningKernel) if !affected { continue } if req.isSrcPack { - for _, n := range req.binaryPackNames { - relatedDefs.upsert(def, n, false) + for _, binName := range req.binaryPackNames { + fs := fixStat{ + notFixedYet: false, + isSrcPack: true, + fixedIn: fixedIn, + srcPackName: req.packName, + } + relatedDefs.upsert(def, binName, fs) } } else { - relatedDefs.upsert(def, req.packName, notFixedYet) + fs := fixStat{ + notFixedYet: notFixedYet, + fixedIn: fixedIn, + } + relatedDefs.upsert(def, req.packName, fs) } } } @@ -255,7 +285,7 @@ func major(version string) string { return ver[0:strings.Index(ver, ".")] } -func isOvalDefAffected(def ovalmodels.Definition, req request, family string, running models.Kernel) (affected, notFixedYet bool) { +func isOvalDefAffected(def ovalmodels.Definition, req request, family string, running models.Kernel) (affected, notFixedYet bool, fixedIn string) { for _, ovalPack := range def.AffectedPacks { if req.packName != ovalPack.Name { continue @@ -274,7 +304,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru } if ovalPack.NotFixedYet { - return true, true + return true, true, ovalPack.Version } // Compare between the installed version vs the version in OVAL @@ -282,9 +312,14 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru if err != nil { util.Log.Debugf("Failed to parse versions: %s, Ver: %#v, OVAL: %#v, DefID: %s", err, req.versionRelease, ovalPack, def.DefinitionID) - return false, false + return false, false, ovalPack.Version } if less { + if req.isSrcPack { + // Unable to judge whether fixed or not-fixed of src package(Ubuntu, Debian) + return true, false, ovalPack.Version + } + // If the version of installed is less than in OVAL switch family { case config.RedHat, @@ -293,7 +328,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru config.Debian, config.Ubuntu: // Use fixed state in OVAL for these distros. - return true, false + return true, false, ovalPack.Version } // But CentOS can't judge whether fixed or unfixed. @@ -304,7 +339,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru // In these mode, the blow field was set empty. // Vuls can not judge fixed or unfixed. if req.newVersionRelease == "" { - return true, false + return true, false, ovalPack.Version } // compare version: newVer vs oval @@ -312,12 +347,12 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru if err != nil { util.Log.Debugf("Failed to parse versions: %s, NewVer: %#v, OVAL: %#v, DefID: %s", err, req.newVersionRelease, ovalPack, def.DefinitionID) - return false, false + return false, false, ovalPack.Version } - return true, less + return true, less, ovalPack.Version } } - return false, false + return false, false, "" } var centosVerPattern = regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`) diff --git a/oval/util_test.go b/oval/util_test.go index 01c68157..91de0028 100644 --- a/oval/util_test.go +++ b/oval/util_test.go @@ -12,12 +12,12 @@ import ( func TestUpsert(t *testing.T) { var tests = []struct { - res ovalResult - def ovalmodels.Definition - packName string - notFixedYet bool - upserted bool - out ovalResult + res ovalResult + def ovalmodels.Definition + packName string + fixStat fixStat + upserted bool + out ovalResult }{ //insert { @@ -25,17 +25,23 @@ func TestUpsert(t *testing.T) { def: ovalmodels.Definition{ DefinitionID: "1111", }, - packName: "pack1", - notFixedYet: true, - upserted: false, + packName: "pack1", + fixStat: fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, + upserted: false, out: ovalResult{ []defPacks{ { def: ovalmodels.Definition{ DefinitionID: "1111", }, - actuallyAffectedPackNames: map[string]bool{ - "pack1": true, + binpkgFixstat: map[string]fixStat{ + "pack1": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, }, }, }, @@ -49,16 +55,22 @@ func TestUpsert(t *testing.T) { def: ovalmodels.Definition{ DefinitionID: "1111", }, - actuallyAffectedPackNames: map[string]bool{ - "pack1": true, + binpkgFixstat: map[string]fixStat{ + "pack1": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, }, }, { def: ovalmodels.Definition{ DefinitionID: "2222", }, - actuallyAffectedPackNames: map[string]bool{ - "pack3": true, + binpkgFixstat: map[string]fixStat{ + "pack3": fixStat{ + notFixedYet: true, + fixedIn: "2.0.0", + }, }, }, }, @@ -66,26 +78,38 @@ func TestUpsert(t *testing.T) { def: ovalmodels.Definition{ DefinitionID: "1111", }, - packName: "pack2", - notFixedYet: false, - upserted: true, + packName: "pack2", + fixStat: fixStat{ + notFixedYet: false, + fixedIn: "3.0.0", + }, + upserted: true, out: ovalResult{ []defPacks{ { def: ovalmodels.Definition{ DefinitionID: "1111", }, - actuallyAffectedPackNames: map[string]bool{ - "pack1": true, - "pack2": false, + binpkgFixstat: map[string]fixStat{ + "pack1": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + }, + "pack2": fixStat{ + notFixedYet: false, + fixedIn: "3.0.0", + }, }, }, { def: ovalmodels.Definition{ DefinitionID: "2222", }, - actuallyAffectedPackNames: map[string]bool{ - "pack3": true, + binpkgFixstat: map[string]fixStat{ + "pack3": fixStat{ + notFixedYet: true, + fixedIn: "2.0.0", + }, }, }, }, @@ -93,7 +117,7 @@ func TestUpsert(t *testing.T) { }, } for i, tt := range tests { - upserted := tt.res.upsert(tt.def, tt.packName, tt.notFixedYet) + upserted := tt.res.upsert(tt.def, tt.packName, tt.fixStat) if tt.upserted != upserted { t.Errorf("[%d]\nexpected: %t\n actual: %t\n", i, tt.upserted, upserted) } @@ -121,17 +145,27 @@ func TestDefpacksToPackStatuses(t *testing.T) { { Name: "a", NotFixedYet: true, + Version: "1.0.0", }, { Name: "b", NotFixedYet: false, + Version: "2.0.0", }, }, }, - actuallyAffectedPackNames: map[string]bool{ - "a": true, - "b": true, - "c": true, + binpkgFixstat: map[string]fixStat{ + "a": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + isSrcPack: false, + }, + "b": fixStat{ + notFixedYet: true, + fixedIn: "1.0.0", + isSrcPack: true, + srcPackName: "lib-b", + }, }, }, }, @@ -139,14 +173,12 @@ func TestDefpacksToPackStatuses(t *testing.T) { { Name: "a", NotFixedYet: true, + FixedIn: "1.0.0", }, { Name: "b", NotFixedYet: true, - }, - { - Name: "c", - NotFixedYet: true, + FixedIn: "1.0.0", }, }, }, @@ -173,6 +205,7 @@ func TestIsOvalDefAffected(t *testing.T) { in in affected bool notFixedYet bool + fixedIn string }{ // 0. Ubuntu ovalpack.NotFixedYet == true { @@ -187,6 +220,7 @@ func TestIsOvalDefAffected(t *testing.T) { { Name: "b", NotFixedYet: true, + Version: "1.0.0", }, }, }, @@ -196,6 +230,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: true, + fixedIn: "1.0.0", }, // 1. Ubuntu // ovalpack.NotFixedYet == false @@ -226,6 +261,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "1.0.0-1", }, // 2. Ubuntu // ovalpack.NotFixedYet == false @@ -285,6 +321,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, }, affected: true, + fixedIn: "1.0.0-3", notFixedYet: false, }, // 4. Ubuntu @@ -318,6 +355,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "1.0.0-2", }, // 5 RedHat { @@ -345,6 +383,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 6 RedHat { @@ -372,6 +411,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 7 RedHat { @@ -451,6 +491,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 10 RedHat { @@ -478,6 +519,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 11 RedHat { @@ -504,6 +546,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 12 RedHat { @@ -583,6 +626,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 15 { @@ -662,6 +706,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: true, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 18 { @@ -689,6 +734,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 19 { @@ -716,6 +762,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, // 20 { @@ -794,6 +841,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, { in: in{ @@ -870,6 +918,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: true, + fixedIn: "0:1.2.3-45.el6_7.8", }, { in: in{ @@ -896,6 +945,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, { in: in{ @@ -922,6 +972,7 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", }, { in: in{ @@ -1021,16 +1072,20 @@ func TestIsOvalDefAffected(t *testing.T) { }, affected: true, notFixedYet: false, + fixedIn: "3.1.0", }, } for i, tt := range tests { - affected, notFixedYet := isOvalDefAffected(tt.in.def, tt.in.req, tt.in.family, tt.in.kernel) + affected, notFixedYet, fixedIn := isOvalDefAffected(tt.in.def, tt.in.req, tt.in.family, tt.in.kernel) if tt.affected != affected { t.Errorf("[%d] affected\nexpected: %v\n actual: %v\n", i, tt.affected, affected) } if tt.notFixedYet != notFixedYet { t.Errorf("[%d] notfixedyet\nexpected: %v\n actual: %v\n", i, tt.notFixedYet, notFixedYet) } + if tt.fixedIn != fixedIn { + t.Errorf("[%d] fixedIn\nexpected: %v\n actual: %v\n", i, tt.fixedIn, fixedIn) + } } } diff --git a/report/tui.go b/report/tui.go index 6343ffc7..7172b26d 100644 --- a/report/tui.go +++ b/report/tui.go @@ -706,12 +706,10 @@ func setChangelogLayout(g *gocui.Gui) error { var line string if pack.Repository != "" { line = fmt.Sprintf("* %s (%s)", - pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState), + pack.FormatVersionFromTo(affected), pack.Repository) } else { - line = fmt.Sprintf("* %s", - pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState), - ) + line = fmt.Sprintf("* %s", pack.FormatVersionFromTo(affected)) } lines = append(lines, line) diff --git a/report/util.go b/report/util.go index abdc5d56..7e2fa76f 100644 --- a/report/util.go +++ b/report/util.go @@ -251,12 +251,10 @@ No CVE-IDs are found in updatable packages. var line string if pack.Repository != "" { line = fmt.Sprintf("%s (%s)", - pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState), + pack.FormatVersionFromTo(affected), pack.Repository) } else { - line = fmt.Sprintf("%s", - pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState), - ) + line = pack.FormatVersionFromTo(affected) } data = append(data, []string{"Affected Pkg", line}) diff --git a/scan/redhatbase_test.go b/scan/redhatbase_test.go index f422c330..ec8a4c94 100644 --- a/scan/redhatbase_test.go +++ b/scan/redhatbase_test.go @@ -315,7 +315,7 @@ if-not-architecture 0 100 200 amzn-main` } func TestParseNeedsRestarting(t *testing.T) { - r := newCentOS(config.ServerInfo{}) + r := newRHEL(config.ServerInfo{}) r.Distro = config.Distro{Family: "centos"} var tests = []struct { @@ -323,7 +323,7 @@ func TestParseNeedsRestarting(t *testing.T) { out []models.NeedRestartProcess }{ { - `1 : /usr/lib/systemd/systemd --switched-root --system --deserialize 21 + `1 : /usr/lib/systemd/systemd --switched-root --system --deserialize 21kk 437 : /usr/sbin/NetworkManager --no-daemon`, []models.NeedRestartProcess{ {