diff --git a/commands/scan.go b/commands/scan.go index 896f70fb13..3d78280444 100644 --- a/commands/scan.go +++ b/commands/scan.go @@ -430,15 +430,17 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) return subcommands.ExitFailure } - Log.Info("Reporting...") - filtered := scanResults.FilterByCvssOver() - //Log.Info("FILTERED RESULTS: ", filtered) - for _, w := range reports { - if err := w.Write(filtered); err != nil { - Log.Fatalf("Failed to report, err: %s", err) - return subcommands.ExitFailure + /* + Log.Info("Reporting...") + filtered := scanResults.FilterByCvssOver() + //Log.Info("FILTERED RESULTS: ", filtered) + for _, w := range reports { + if err := w.Write(filtered); err != nil { + Log.Fatalf("Failed to report, err: %s", err) + return subcommands.ExitFailure + } } - } + */ return subcommands.ExitSuccess } diff --git a/models/models.go b/models/models.go index 3a1877748d..d8d52b350b 100644 --- a/models/models.go +++ b/models/models.go @@ -36,6 +36,7 @@ type ScanHistory struct { // ScanResults is slice of ScanResult. type ScanResults []ScanResult +type ScanPackageResults []ScanPackageResult // Len implement Sort Interface func (s ScanResults) Len() int { @@ -70,6 +71,23 @@ func (s ScanResults) FilterByCvssOver() (filtered ScanResults) { return } +type ScanPackageResult struct { + ScannedAt time.Time + + ServerName string // TOML Section key + // Hostname string + Family string + Release string + + Container Container + + Platform Platform + + // Fqdn string + // NWLinks []NWLink + Packages []PackageInfoCVE +} + // ScanResult has the result of scanned CVE information. type ScanResult struct { gorm.Model `json:"-"` @@ -94,6 +112,31 @@ type ScanResult struct { Optional [][]interface{} `gorm:"-"` } +func (r ScanResult) ByPackage() ScanPackageResult { + packMap := make(map[PackageInfo][]string) + allCVEs := append(append(r.KnownCves, r.UnknownCves...), r.IgnoredCves...) + for _, cve := range allCVEs { + for _, pack := range cve.Packages { + packMap[pack] = append(packMap[pack], cve.CveDetail.CveID) + } + } + packs := []PackageInfoCVE{} + for pack, cves := range packMap { + packs = append(packs, pack.WithCVEs(cves)) + } + + return ScanPackageResult{ + ScannedAt: r.ScannedAt, + ServerName: r.ServerName, + Family: r.Family, + Release: r.Release, + Container: r.Container, + Platform: r.Platform, + Packages: packs, + } + +} + // ServerInfo returns server name one line func (r ScanResult) ServerInfo() string { hostinfo := "" @@ -285,6 +328,28 @@ type PackageInfo struct { NewRelease string } +func (p PackageInfo) WithCVEs(cves []string) PackageInfoCVE { + return PackageInfoCVE{ + Name: p.Name, + Version: p.Version, + Release: p.Release, + NewVersion: p.NewVersion, + NewRelease: p.NewRelease, + CVEs: cves, + } +} + +type PackageInfoCVE struct { + Name string + Version string + Release string + + NewVersion string + NewRelease string + + CVEs []string +} + // ToStringCurrentVersion returns package name-version-release func (p PackageInfo) ToStringCurrentVersion() string { str := p.Name diff --git a/scan/base.go b/scan/base.go index a7361575a8..77fc344ec6 100644 --- a/scan/base.go +++ b/scan/base.go @@ -20,7 +20,6 @@ package scan import ( "fmt" "regexp" - "sort" "strings" "time" @@ -28,6 +27,7 @@ import ( "github.com/future-architect/vuls/config" "github.com/future-architect/vuls/cveapi" "github.com/future-architect/vuls/models" + cve "github.com/kotakanbe/go-cve-dictionary/models" ) type base struct { @@ -239,7 +239,7 @@ func (l *base) convertToModel() (models.ScanResult, error) { for _, icve := range l.getServerInfo().IgnoreCves { if icve == p.CveDetail.CveID { ignoredCves = append(ignoredCves, models.CveInfo{ - CveDetail: p.CveDetail, + CveDetail: cve.CveDetail{CveID: p.CveID}, Packages: p.Packs, DistroAdvisories: p.DistroAdvisories, }) @@ -254,7 +254,7 @@ func (l *base) convertToModel() (models.ScanResult, error) { // unscoredCves if p.CveDetail.CvssScore(config.Conf.Lang) <= 0 { unscoredCves = append(unscoredCves, models.CveInfo{ - CveDetail: p.CveDetail, + CveDetail: cve.CveDetail{CveID: p.CveID}, Packages: p.Packs, DistroAdvisories: p.DistroAdvisories, }) @@ -269,7 +269,7 @@ func (l *base) convertToModel() (models.ScanResult, error) { // scoredCves cve := models.CveInfo{ - CveDetail: p.CveDetail, + CveDetail: cve.CveDetail{CveID: p.CveID}, Packages: p.Packs, DistroAdvisories: p.DistroAdvisories, CpeNames: cpenames, @@ -282,10 +282,6 @@ func (l *base) convertToModel() (models.ScanResult, error) { Name: l.ServerInfo.Container.Name, } - sort.Sort(scoredCves) - sort.Sort(unscoredCves) - sort.Sort(ignoredCves) - return models.ScanResult{ ServerName: l.ServerInfo.ServerName, ScannedAt: time.Now(), diff --git a/scan/debian.go b/scan/debian.go index 2f5e757cd5..ac33807f38 100644 --- a/scan/debian.go +++ b/scan/debian.go @@ -26,9 +26,9 @@ import ( "github.com/future-architect/vuls/cache" "github.com/future-architect/vuls/config" - "github.com/future-architect/vuls/cveapi" "github.com/future-architect/vuls/models" "github.com/future-architect/vuls/util" + cve "github.com/kotakanbe/go-cve-dictionary/models" ) // inherit OsTypeInterface @@ -489,18 +489,17 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac } o.log.Debugf("%d Cves are found. cves: %v", len(cveIDs), cveIDs) - o.log.Info("Fetching CVE details...") - cveDetails, err := cveapi.CveClient.FetchCveDetails(cveIDs) if err != nil { return nil, err } o.log.Info("Done") - for _, detail := range cveDetails { + // Range over the IDs, don't worry about going to remote because fuck it + for _, id := range cveIDs { cvePacksList = append(cvePacksList, CvePacksInfo{ - CveID: detail.CveID, - CveDetail: detail, - Packs: cvePackages[detail.CveID], + CveID: id, + CveDetail: cve.CveDetail{}, + Packs: cvePackages[id], // CvssScore: cinfo.CvssScore(conf.Lang), }) } diff --git a/scan/serverapi.go b/scan/serverapi.go index bf0efef7d1..a0bd739620 100644 --- a/scan/serverapi.go +++ b/scan/serverapi.go @@ -567,13 +567,13 @@ func scanVulnByCpeName() []error { } // GetScanResults returns Scan Resutls -func GetScanResults() (results models.ScanResults, err error) { +func GetScanResults() (results models.ScanPackageResults, err error) { for _, s := range servers { r, err := s.convertToModel() if err != nil { return results, fmt.Errorf("Failed converting to model: %s", err) } - results = append(results, r) + results = append(results, r.ByPackage()) } return }