From 092a19bdc1b628a518f0da7dbd81bdc1d02305f3 Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Tue, 6 Mar 2018 16:50:09 +0900 Subject: [PATCH] fix: bug of report -diff option (#607) --- oval/redhat.go | 10 ++++++-- report/report.go | 16 ++++++------ report/util.go | 61 ++++++++++++++++++++++++++------------------- report/util_test.go | 9 +++++++ 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/oval/redhat.go b/oval/redhat.go index 1e439f88..5b46ef40 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -112,8 +112,14 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) { } } else { cveContents := vinfo.CveContents - if _, ok := vinfo.CveContents[ctype]; ok { - util.Log.Debugf("%s OVAL will be overwritten", cve.CveID) + if v, ok := vinfo.CveContents[ctype]; ok { + if v.LastModified.After(ovalContent.LastModified) { + util.Log.Debugf("%s, OvalID: %s ignroed: ", + cve.CveID, defPacks.def.ID) + continue + } else { + util.Log.Debugf("%s OVAL will be overwritten", cve.CveID) + } } else { util.Log.Debugf("%s also detected by OVAL", cve.CveID) cveContents = models.CveContents{} diff --git a/report/report.go b/report/report.go index 57f7cd6e..2add5da4 100644 --- a/report/report.go +++ b/report/report.go @@ -34,7 +34,7 @@ const ( // FillCveInfos fills CVE Detailed Information func FillCveInfos(rs []models.ScanResult, dir string) ([]models.ScanResult, error) { - var filled []models.ScanResult + var filledResults []models.ScanResult reportedAt := time.Now() for _, r := range rs { if c.Conf.RefreshCve || needToRefreshCve(r) { @@ -50,34 +50,34 @@ func FillCveInfos(rs []models.ScanResult, dir string) ([]models.ScanResult, erro if err := overwriteJSONFile(dir, r); err != nil { return nil, fmt.Errorf("Failed to write JSON: %s", err) } - filled = append(filled, r) + filledResults = append(filledResults, r) } else { util.Log.Debugf("No need to refresh") - filled = append(filled, r) + filledResults = append(filledResults, r) } } if c.Conf.Diff { - previous, err := loadPrevious(filled) + prevs, err := loadPrevious(filledResults) if err != nil { return nil, err } - diff, err := diff(filled, previous) + diff, err := diff(filledResults, prevs) if err != nil { return nil, err } - filled = []models.ScanResult{} + filledResults = []models.ScanResult{} for _, r := range diff { if err := fillCveDetail(&r); err != nil { return nil, err } - filled = append(filled, r) + filledResults = append(filledResults, r) } } filtered := []models.ScanResult{} - for _, r := range filled { + for _, r := range filledResults { r = r.FilterByCvssOver(c.Conf.CvssScoreOver) r = r.FilterIgnoreCves(c.Conf.Servers[r.ServerName].IgnoreCves) r = r.FilterUnfixed() diff --git a/report/util.go b/report/util.go index 8ef9aa53..45f5c258 100644 --- a/report/util.go +++ b/report/util.go @@ -23,6 +23,7 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "regexp" "sort" "strings" @@ -273,27 +274,35 @@ func overwriteJSONFile(dir string, r models.ScanResult) error { return nil } -func loadPrevious(current models.ScanResults) (previous models.ScanResults, err error) { +func loadPrevious(currs models.ScanResults) (prevs models.ScanResults, err error) { dirs, err := ListValidJSONDirs() if err != nil { return } - for _, result := range current { + for _, result := range currs { + filename := result.ServerName + ".json" + if result.Container.Name != "" { + filename = fmt.Sprintf("%s@%s.json", result.Container.Name, result.ServerName) + } for _, dir := range dirs[1:] { - var r *models.ScanResult - path := filepath.Join(dir, result.ServerName+".json") - if r, err = loadOneServerScanResult(path); err != nil { + path := filepath.Join(dir, filename) + r, err := loadOneServerScanResult(path) + if err != nil { + util.Log.Errorf("%s", err) continue } if r.Family == result.Family && r.Release == result.Release { - previous = append(previous, *r) + prevs = append(prevs, *r) util.Log.Infof("Previous json found: %s", path) break + } else { + util.Log.Infof("Previous json is different family.Release: %s, pre: %s.%s cur: %s.%s", + path, r.Family, r.Release, result.Family, result.Release) } } } - return previous, nil + return prevs, nil } func diff(curResults, preResults models.ScanResults) (diffed models.ScanResults, err error) { @@ -301,7 +310,7 @@ func diff(curResults, preResults models.ScanResults) (diffed models.ScanResults, found := false var previous models.ScanResult for _, r := range preResults { - if current.ServerName == r.ServerName { + if current.ServerName == r.ServerName && current.Container.Name == r.Container.Name { found = true previous = r break @@ -337,8 +346,12 @@ func getDiffCves(previous, current models.ScanResult) models.VulnInfos { if previousCveIDsSet[v.CveID] { if isCveInfoUpdated(v.CveID, previous, current) { updated[v.CveID] = v + util.Log.Debugf("updated: %s", v.CveID) + } else { + util.Log.Debugf("same: %s", v.CveID) } } else { + util.Log.Debugf("newsame: %s", v.CveID) new[v.CveID] = v } } @@ -357,32 +370,28 @@ func isCveInfoUpdated(cveID string, previous, current models.ScanResult) bool { } prevLastModified := map[models.CveContentType]time.Time{} - for _, c := range previous.ScannedCves { - if cveID == c.CveID { - for _, cType := range cTypes { - content, _ := c.CveContents[cType] - prevLastModified[cType] = content.LastModified - } - break + preVinfo, ok := previous.ScannedCves[cveID] + if !ok { + return true + } + for _, cType := range cTypes { + if content, ok := preVinfo.CveContents[cType]; ok { + prevLastModified[cType] = content.LastModified } } curLastModified := map[models.CveContentType]time.Time{} - for _, c := range current.ScannedCves { - if cveID == c.CveID { - for _, cType := range cTypes { - content, _ := c.CveContents[cType] - curLastModified[cType] = content.LastModified - } - break - } + curVinfo, ok := current.ScannedCves[cveID] + if !ok { + return true } for _, cType := range cTypes { - if !prevLastModified[cType].Equal(curLastModified[cType]) { - return true + if content, ok := curVinfo.CveContents[cType]; ok { + curLastModified[cType] = content.LastModified } } - return false + + return !reflect.DeepEqual(curLastModified, prevLastModified) } // jsonDirPattern is file name pattern of JSON directory diff --git a/report/util_test.go b/report/util_test.go index 4deb6934..b5868a73 100644 --- a/report/util_test.go +++ b/report/util_test.go @@ -1,14 +1,23 @@ package report import ( + "os" "reflect" "testing" "time" + "github.com/future-architect/vuls/config" "github.com/future-architect/vuls/models" + "github.com/future-architect/vuls/util" "github.com/k0kubun/pp" ) +func TestMain(m *testing.M) { + util.Log = util.NewCustomLogger(config.ServerInfo{}) + code := m.Run() + os.Exit(code) +} + func TestIsCveInfoUpdated(t *testing.T) { f := "2006-01-02" old, _ := time.Parse(f, "2015-12-15")