refactor: don't use global Config in private func (#1197)
* refactor: cve_client.go * refactor: don't use global Config in private func * remove import alias for config * refactor: dbclient * refactor: resultDir * refactor: resultsDir * refactor * refactor: gost * refactor: db client * refactor: cveDB * refactor: cvedb * refactor: exploitDB * refactor: remove detector/dbclient.go * refactor: writer * refactor: syslog writer * refactor: ips * refactor: ensureResultDir * refactor: proxy * fix(db): call CloseDB * add integration test * feat(report): sort array in json * sort func for json diff * add build-int to makefile * add int-rds-redis to makefile * fix: test case, makefile * fix makefile * show cve count after diff * make diff * diff -c * sort exploits in json for diff * sort metasploit, exploit
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -56,7 +57,7 @@ type ScanResult struct {
|
||||
Config struct {
|
||||
Scan config.Config `json:"scan"`
|
||||
Report config.Config `json:"report"`
|
||||
} `json:"constant"`
|
||||
} `json:"config"`
|
||||
}
|
||||
|
||||
// Container has Container information
|
||||
@@ -374,6 +375,48 @@ func (r *ScanResult) CheckEOL() {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ScanResult) SortForJSONOutput() {
|
||||
for k, v := range r.Packages {
|
||||
sort.SliceStable(v.AffectedProcs, func(i, j int) bool {
|
||||
return v.AffectedProcs[i].PID < v.AffectedProcs[j].PID
|
||||
})
|
||||
sort.SliceStable(v.NeedRestartProcs, func(i, j int) bool {
|
||||
return v.NeedRestartProcs[i].PID < v.NeedRestartProcs[j].PID
|
||||
})
|
||||
r.Packages[k] = v
|
||||
}
|
||||
|
||||
for k, v := range r.ScannedCves {
|
||||
sort.SliceStable(v.AffectedPackages, func(i, j int) bool {
|
||||
return v.AffectedPackages[i].Name < v.AffectedPackages[j].Name
|
||||
})
|
||||
sort.SliceStable(v.DistroAdvisories, func(i, j int) bool {
|
||||
return v.DistroAdvisories[i].AdvisoryID < v.DistroAdvisories[j].AdvisoryID
|
||||
})
|
||||
sort.SliceStable(v.Exploits, func(i, j int) bool {
|
||||
return v.Exploits[i].ID < v.Exploits[j].ID
|
||||
})
|
||||
sort.SliceStable(v.Metasploits, func(i, j int) bool {
|
||||
return v.Metasploits[i].Name < v.Metasploits[j].Name
|
||||
})
|
||||
for kk, vv := range v.CveContents {
|
||||
sort.SliceStable(vv.References, func(i, j int) bool {
|
||||
return vv.References[i].Link < vv.References[j].Link
|
||||
})
|
||||
v.CveContents[kk] = vv
|
||||
}
|
||||
|
||||
sort.SliceStable(v.AlertDict.En, func(i, j int) bool {
|
||||
return v.AlertDict.En[i].Title < v.AlertDict.En[j].Title
|
||||
})
|
||||
sort.SliceStable(v.AlertDict.Ja, func(i, j int) bool {
|
||||
return v.AlertDict.Ja[i].Title < v.AlertDict.Ja[j].Title
|
||||
})
|
||||
|
||||
r.ScannedCves[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// CweDict is a dictionary for CWE
|
||||
type CweDict map[string]CweDictEntry
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
@@ -92,3 +93,274 @@ func TestIsDisplayUpdatableNum(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanResult_Sort(t *testing.T) {
|
||||
type fields struct {
|
||||
Packages Packages
|
||||
ScannedCves VulnInfos
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
expected fields
|
||||
}{
|
||||
{
|
||||
name: "already asc",
|
||||
fields: fields{
|
||||
Packages: map[string]Package{
|
||||
"pkgA": {
|
||||
Name: "pkgA",
|
||||
AffectedProcs: []AffectedProcess{
|
||||
{PID: "1", Name: "procB"},
|
||||
{PID: "2", Name: "procA"},
|
||||
},
|
||||
NeedRestartProcs: []NeedRestartProcess{
|
||||
{PID: "1"},
|
||||
{PID: "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ScannedCves: VulnInfos{
|
||||
"CVE-2014-3591": VulnInfo{
|
||||
AffectedPackages: PackageFixStatuses{
|
||||
PackageFixStatus{Name: "pkgA"},
|
||||
PackageFixStatus{Name: "pkgB"},
|
||||
},
|
||||
DistroAdvisories: []DistroAdvisory{
|
||||
{AdvisoryID: "adv-1"},
|
||||
{AdvisoryID: "adv-2"},
|
||||
},
|
||||
Exploits: []Exploit{
|
||||
{ID: "a"},
|
||||
{ID: "b"},
|
||||
},
|
||||
Metasploits: []Metasploit{
|
||||
{Name: "a"},
|
||||
{Name: "b"},
|
||||
},
|
||||
CveContents: CveContents{
|
||||
"nvd": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
"jvn": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: fields{
|
||||
Packages: map[string]Package{
|
||||
"pkgA": {
|
||||
Name: "pkgA",
|
||||
AffectedProcs: []AffectedProcess{
|
||||
{PID: "1", Name: "procB"},
|
||||
{PID: "2", Name: "procA"},
|
||||
},
|
||||
NeedRestartProcs: []NeedRestartProcess{
|
||||
{PID: "1"},
|
||||
{PID: "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ScannedCves: VulnInfos{
|
||||
"CVE-2014-3591": VulnInfo{
|
||||
AffectedPackages: PackageFixStatuses{
|
||||
PackageFixStatus{Name: "pkgA"},
|
||||
PackageFixStatus{Name: "pkgB"},
|
||||
},
|
||||
DistroAdvisories: []DistroAdvisory{
|
||||
{AdvisoryID: "adv-1"},
|
||||
{AdvisoryID: "adv-2"},
|
||||
},
|
||||
Exploits: []Exploit{
|
||||
{ID: "a"},
|
||||
{ID: "b"},
|
||||
},
|
||||
Metasploits: []Metasploit{
|
||||
{Name: "a"},
|
||||
{Name: "b"},
|
||||
},
|
||||
CveContents: CveContents{
|
||||
"nvd": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
"jvn": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sort",
|
||||
fields: fields{
|
||||
Packages: map[string]Package{
|
||||
"pkgA": {
|
||||
Name: "pkgA",
|
||||
AffectedProcs: []AffectedProcess{
|
||||
{PID: "2", Name: "procA"},
|
||||
{PID: "1", Name: "procB"},
|
||||
},
|
||||
NeedRestartProcs: []NeedRestartProcess{
|
||||
{PID: "91"},
|
||||
{PID: "90"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ScannedCves: VulnInfos{
|
||||
"CVE-2014-3591": VulnInfo{
|
||||
AffectedPackages: PackageFixStatuses{
|
||||
PackageFixStatus{Name: "pkgB"},
|
||||
PackageFixStatus{Name: "pkgA"},
|
||||
},
|
||||
DistroAdvisories: []DistroAdvisory{
|
||||
{AdvisoryID: "adv-2"},
|
||||
{AdvisoryID: "adv-1"},
|
||||
},
|
||||
Exploits: []Exploit{
|
||||
{ID: "b"},
|
||||
{ID: "a"},
|
||||
},
|
||||
Metasploits: []Metasploit{
|
||||
{Name: "b"},
|
||||
{Name: "a"},
|
||||
},
|
||||
CveContents: CveContents{
|
||||
"nvd": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "b"},
|
||||
Reference{Link: "a"},
|
||||
},
|
||||
},
|
||||
"jvn": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "b"},
|
||||
Reference{Link: "a"},
|
||||
},
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
{Title: "b"},
|
||||
{Title: "a"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
{Title: "b"},
|
||||
{Title: "a"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: fields{
|
||||
Packages: map[string]Package{
|
||||
"pkgA": {
|
||||
Name: "pkgA",
|
||||
AffectedProcs: []AffectedProcess{
|
||||
{PID: "1", Name: "procB"},
|
||||
{PID: "2", Name: "procA"},
|
||||
},
|
||||
NeedRestartProcs: []NeedRestartProcess{
|
||||
{PID: "90"},
|
||||
{PID: "91"},
|
||||
},
|
||||
},
|
||||
},
|
||||
ScannedCves: VulnInfos{
|
||||
"CVE-2014-3591": VulnInfo{
|
||||
AffectedPackages: PackageFixStatuses{
|
||||
PackageFixStatus{Name: "pkgA"},
|
||||
PackageFixStatus{Name: "pkgB"},
|
||||
},
|
||||
DistroAdvisories: []DistroAdvisory{
|
||||
{AdvisoryID: "adv-1"},
|
||||
{AdvisoryID: "adv-2"},
|
||||
},
|
||||
Exploits: []Exploit{
|
||||
{ID: "a"},
|
||||
{ID: "b"},
|
||||
},
|
||||
Metasploits: []Metasploit{
|
||||
{Name: "a"},
|
||||
{Name: "b"},
|
||||
},
|
||||
CveContents: CveContents{
|
||||
"nvd": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
"jvn": CveContent{
|
||||
References: References{
|
||||
Reference{Link: "a"},
|
||||
Reference{Link: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
r := &ScanResult{
|
||||
Packages: tt.fields.Packages,
|
||||
ScannedCves: tt.fields.ScannedCves,
|
||||
}
|
||||
r.SortForJSONOutput()
|
||||
if !reflect.DeepEqual(r.Packages, tt.expected.Packages) {
|
||||
t.Errorf("act %+v, want %+v", r.Packages, tt.expected.Packages)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(r.ScannedCves, tt.expected.ScannedCves) {
|
||||
t.Errorf("act %+v, want %+v", r.ScannedCves, tt.expected.ScannedCves)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,14 +763,10 @@ type AlertDict struct {
|
||||
|
||||
// FormatSource returns which source has this alert
|
||||
func (a AlertDict) FormatSource() string {
|
||||
s := []string{}
|
||||
if len(a.En) != 0 {
|
||||
s = append(s, "USCERT")
|
||||
if len(a.En) != 0 || len(a.Ja) != 0 {
|
||||
return "CERT"
|
||||
}
|
||||
if len(a.Ja) != 0 {
|
||||
s = append(s, "JPCERT")
|
||||
}
|
||||
return strings.Join(s, "/")
|
||||
return ""
|
||||
}
|
||||
|
||||
// Confidences is a list of Confidence
|
||||
|
||||
Reference in New Issue
Block a user