From f26b61d77353a6ec4b097935c799c3f825f8a0f2 Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Sat, 6 May 2017 04:52:19 +0900 Subject: [PATCH] Change CveContents data type to map --- commands/util.go | 2 +- commands/util_test.go | 58 +++++++++++++++++++++---------------------- models/models.go | 58 ++++++++++++++++++++++--------------------- oval/debian.go | 2 +- oval/redhat.go | 2 +- scan/base.go | 2 +- scan/executil.go | 4 ++- 7 files changed, 66 insertions(+), 62 deletions(-) diff --git a/commands/util.go b/commands/util.go index cea5989f..8a17f39a 100644 --- a/commands/util.go +++ b/commands/util.go @@ -295,7 +295,7 @@ func scanVulnByCpeNames(cpeNames []string, scannedVulns []models.VulnInfo) ([]mo CpeNames: []string{name}, Confidence: models.CpeNameMatch, } - v.NilSliceToEmpty() + v.NilToEmpty() set[detail.CveID] = v } } diff --git a/commands/util_test.go b/commands/util_test.go index 0c598a01..a461428b 100644 --- a/commands/util_test.go +++ b/commands/util_test.go @@ -48,13 +48,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0001", - CveContents: []models.CveContent{ - { + CveContents: models.NewCveContents( + models.CveContent{ Type: models.NVD, CveID: "CVE-2017-0001", LastModified: time.Time{}, }, - }, + ), }, }, }, @@ -62,13 +62,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0001", - CveContents: []models.CveContent{ - { + CveContents: models.NewCveContents( + models.CveContent{ Type: models.NVD, CveID: "CVE-2017-0001", LastModified: time.Time{}, }, - }, + ), }, }, }, @@ -83,13 +83,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0002", - CveContents: []models.CveContent{ - { - Type: models.JVN, + CveContents: models.NewCveContents( + models.CveContent{ + Type: models.NVD, CveID: "CVE-2017-0002", LastModified: old, }, - }, + ), }, }, }, @@ -97,13 +97,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0002", - CveContents: []models.CveContent{ - { - Type: models.JVN, + CveContents: models.NewCveContents( + models.CveContent{ + Type: models.NVD, CveID: "CVE-2017-0002", LastModified: old, }, - }, + ), }, }, }, @@ -119,13 +119,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0003", - CveContents: []models.CveContent{ - { - Type: models.Ubuntu, - CveID: "CVE-2017-0003", + CveContents: models.NewCveContents( + models.CveContent{ + Type: models.NVD, + CveID: "CVE-2017-0002", LastModified: new, }, - }, + ), }, }, }, @@ -134,13 +134,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0003", - CveContents: []models.CveContent{ - { - Type: models.Ubuntu, - CveID: "CVE-2017-0003", + CveContents: models.NewCveContents( + models.CveContent{ + Type: models.NVD, + CveID: "CVE-2017-0002", LastModified: old, }, - }, + ), }, }, }, @@ -156,13 +156,13 @@ func TestIsCveInfoUpdated(t *testing.T) { ScannedCves: []models.VulnInfo{ { CveID: "CVE-2017-0004", - CveContents: []models.CveContent{ - { - Type: models.RedHat, - CveID: "CVE-2017-0004", + CveContents: models.NewCveContents( + models.CveContent{ + Type: models.NVD, + CveID: "CVE-2017-0002", LastModified: old, }, - }, + ), }, }, }, diff --git a/models/models.go b/models/models.go index c7aa23aa..55489b3f 100644 --- a/models/models.go +++ b/models/models.go @@ -383,8 +383,8 @@ type VulnInfo struct { CveContents CveContents } -// NilSliceToEmpty set nil slice fields to empty slice to avoid null in JSON -func (v *VulnInfo) NilSliceToEmpty() { +// NilToEmpty set nil slice or map fields to empty to avoid null in JSON +func (v *VulnInfo) NilToEmpty() { if v.CpeNames == nil { v.CpeNames = []string{} } @@ -394,6 +394,9 @@ func (v *VulnInfo) NilSliceToEmpty() { if v.Packages == nil { v.Packages = PackageInfoList{} } + if v.CveContents == nil { + v.CveContents = NewCveContents() + } } // CveContentType is a source of CVE information @@ -440,49 +443,48 @@ const ( Unknown CveContentType = "unknown" ) -// CveContents has slice of CveContent -type CveContents []CveContent +// CveContents has CveContent +type CveContents map[CveContentType]CveContent + +// NewCveContents create CveContents +func NewCveContents(conts ...CveContent) CveContents { + m := make(map[CveContentType]CveContent) + for _, cont := range conts { + m[cont.Type] = cont + } + return m +} // Get CveContent by cveID // TODO Pointer -func (v *CveContents) Get(typestr CveContentType) (CveContent, bool) { - for _, vv := range *v { - if vv.Type == typestr { - return vv, true - } +func (v CveContents) Get(typestr CveContentType) (CveContent, bool) { + if vv, ok := v[typestr]; ok { + return vv, true } return CveContent{}, false } // Delete by cveID -func (v *CveContents) Delete(typestr CveContentType) { - cveContents := *v - for i, cc := range cveContents { - if cc.Type == typestr { - *v = append(cveContents[:i], cveContents[i+1:]...) - break - } - } +func (v CveContents) Delete(typestr CveContentType) { + delete(v, typestr) } // Insert CveContent -func (v *CveContents) Insert(cont CveContent) { - *v = append(*v, cont) +func (v CveContents) Insert(cont CveContent) { + v[cont.Type] = cont } // Update VulnInfo -func (v *CveContents) Update(cont CveContent) (ok bool) { - for i, vv := range *v { - if vv.Type == cont.Type { - (*v)[i] = cont - return true - } +func (v CveContents) Update(cont CveContent) (ok bool) { + if _, ok := v[cont.Type]; ok { + v[cont.Type] = cont + return true } return false } // Upsert CveContent -func (v *CveContents) Upsert(cont CveContent) { +func (v CveContents) Upsert(cont CveContent) { ok := v.Update(cont) if !ok { v.Insert(cont) @@ -490,7 +492,7 @@ func (v *CveContents) Upsert(cont CveContent) { } // CvssV2Score returns CVSS V2 Score -func (v *CveContents) CvssV2Score() float64 { +func (v CveContents) CvssV2Score() float64 { //TODO if cont, found := v.Get(NVD); found { return cont.Cvss2Score @@ -503,7 +505,7 @@ func (v *CveContents) CvssV2Score() float64 { } // CvssV3Score returns CVSS V2 Score -func (v *CveContents) CvssV3Score() float64 { +func (v CveContents) CvssV3Score() float64 { if cont, found := v.Get(RedHat); found { return cont.Cvss3Score } diff --git a/oval/debian.go b/oval/debian.go index 864b9f73..1bbd0877 100644 --- a/oval/debian.go +++ b/oval/debian.go @@ -70,7 +70,7 @@ func (o Debian) fillOvalInfo(r *models.ScanResult, definition *ovalmodels.Defini CveID: definition.Debian.CveID, Confidence: models.OvalMatch, Packages: getPackageInfoList(r, definition), - CveContents: []models.CveContent{ovalContent}, + CveContents: models.NewCveContents(ovalContent), } } else { if _, ok := vinfo.CveContents.Get(models.NewCveContentType(r.Family)); !ok { diff --git a/oval/redhat.go b/oval/redhat.go index f59f4d00..58f0dd8f 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -66,7 +66,7 @@ func (o Redhat) fillOvalInfo(r *models.ScanResult, definition *ovalmodels.Defini CveID: cve.CveID, Confidence: models.OvalMatch, Packages: getPackageInfoList(r, definition), - CveContents: []models.CveContent{ovalContent}, + CveContents: models.NewCveContents(ovalContent), } } else { if _, ok := vinfo.CveContents.Get(models.RedHat); !ok { diff --git a/scan/base.go b/scan/base.go index 01351585..b2a2da1d 100644 --- a/scan/base.go +++ b/scan/base.go @@ -293,7 +293,7 @@ func (l *base) convertToModel() models.ScanResult { // Avoid null slice being null in JSON for i := range l.VulnInfos { - l.VulnInfos[i].NilSliceToEmpty() + l.VulnInfos[i].NilToEmpty() } return models.ScanResult{ diff --git a/scan/executil.go b/scan/executil.go index 81b45452..e8215272 100644 --- a/scan/executil.go +++ b/scan/executil.go @@ -148,6 +148,9 @@ func parallelExec(fn func(osTypeInterface) error, timeoutSec ...int) { } func exec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result execResult) { + logger := getSSHLogger(log...) + logger.Debugf("Executing... %s", strings.Replace(cmd, "\n", "", -1)) + if c.Port == "local" && (c.Host == "127.0.0.1" || c.Host == "localhost") { result = localExec(c, cmd, sudo) @@ -157,7 +160,6 @@ func exec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (resul result = sshExecExternal(c, cmd, sudo) } - logger := getSSHLogger(log...) logger.Debug(result) return }