Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					591786fde6 | ||
| 
						 | 
					47e6ea249d | ||
| 
						 | 
					4a72295de7 | ||
| 
						 | 
					9ed5f2cac5 | 
@@ -110,6 +110,7 @@ func GetEOL(family, release string) (eol EOL, found bool) {
 | 
			
		||||
			"8":  {Ended: true},
 | 
			
		||||
			"9":  {StandardSupportUntil: time.Date(2022, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"10": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"11": {StandardSupportUntil: time.Date(2026, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
		}[major(release)]
 | 
			
		||||
	case constant.Raspbian:
 | 
			
		||||
		// Not found
 | 
			
		||||
 
 | 
			
		||||
@@ -290,6 +290,14 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) {
 | 
			
		||||
			now:      time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 12 is not supported yet",
 | 
			
		||||
			fields:   fields{family: Debian, release: "12"},
 | 
			
		||||
			now:      time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    false,
 | 
			
		||||
		},
 | 
			
		||||
		//alpine
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,11 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/fanal/analyzer/os"
 | 
			
		||||
	ftypes "github.com/aquasecurity/fanal/types"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/report"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/types"
 | 
			
		||||
	"github.com/future-architect/vuls/constant"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -22,9 +25,7 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
	vulnInfos := models.VulnInfos{}
 | 
			
		||||
	uniqueLibraryScannerPaths := map[string]models.LibraryScanner{}
 | 
			
		||||
	for _, trivyResult := range trivyResults {
 | 
			
		||||
		if IsTrivySupportedOS(trivyResult.Type) {
 | 
			
		||||
			overrideServerData(scanResult, &trivyResult)
 | 
			
		||||
		}
 | 
			
		||||
		setScanResultMeta(scanResult, &trivyResult)
 | 
			
		||||
		for _, vuln := range trivyResult.Vulnerabilities {
 | 
			
		||||
			if _, ok := vulnInfos[vuln.VulnerabilityID]; !ok {
 | 
			
		||||
				vulnInfos[vuln.VulnerabilityID] = models.VulnInfo{
 | 
			
		||||
@@ -81,7 +82,7 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
				}},
 | 
			
		||||
			}
 | 
			
		||||
			// do only if image type is Vuln
 | 
			
		||||
			if IsTrivySupportedOS(trivyResult.Type) {
 | 
			
		||||
			if isTrivySupportedOS(trivyResult.Type) {
 | 
			
		||||
				pkgs[vuln.PkgName] = models.Package{
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
					Version: vuln.InstalledVersion,
 | 
			
		||||
@@ -93,7 +94,6 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
					FixedIn:     vuln.FixedVersion,
 | 
			
		||||
				})
 | 
			
		||||
			} else {
 | 
			
		||||
				// LibraryScanの結果
 | 
			
		||||
				vulnInfo.LibraryFixedIns = append(vulnInfo.LibraryFixedIns, models.LibraryFixedIn{
 | 
			
		||||
					Key:     trivyResult.Type,
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
@@ -101,6 +101,7 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
					FixedIn: vuln.FixedVersion,
 | 
			
		||||
				})
 | 
			
		||||
				libScanner := uniqueLibraryScannerPaths[trivyResult.Target]
 | 
			
		||||
				libScanner.Type = trivyResult.Type
 | 
			
		||||
				libScanner.Libs = append(libScanner.Libs, types.Library{
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
					Version: vuln.InstalledVersion,
 | 
			
		||||
@@ -128,6 +129,7 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		libscanner := models.LibraryScanner{
 | 
			
		||||
			Type: v.Type,
 | 
			
		||||
			Path: path,
 | 
			
		||||
			Libs: libraries,
 | 
			
		||||
		}
 | 
			
		||||
@@ -142,39 +144,70 @@ func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanR
 | 
			
		||||
	return scanResult, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsTrivySupportedOS :
 | 
			
		||||
func IsTrivySupportedOS(family string) bool {
 | 
			
		||||
	supportedFamilies := []string{
 | 
			
		||||
		os.RedHat,
 | 
			
		||||
		os.Debian,
 | 
			
		||||
		os.Ubuntu,
 | 
			
		||||
		os.CentOS,
 | 
			
		||||
		os.Fedora,
 | 
			
		||||
		os.Amazon,
 | 
			
		||||
		os.Oracle,
 | 
			
		||||
		os.Windows,
 | 
			
		||||
		os.OpenSUSE,
 | 
			
		||||
		os.OpenSUSELeap,
 | 
			
		||||
		os.OpenSUSETumbleweed,
 | 
			
		||||
		os.SLES,
 | 
			
		||||
		os.Photon,
 | 
			
		||||
		os.Alpine,
 | 
			
		||||
	}
 | 
			
		||||
	for _, supportedFamily := range supportedFamilies {
 | 
			
		||||
		if family == supportedFamily {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
const trivyTarget = "trivy-target"
 | 
			
		||||
 | 
			
		||||
func overrideServerData(scanResult *models.ScanResult, trivyResult *report.Result) {
 | 
			
		||||
	scanResult.Family = trivyResult.Type
 | 
			
		||||
	scanResult.ServerName = trivyResult.Target
 | 
			
		||||
	scanResult.Optional = map[string]interface{}{
 | 
			
		||||
		"trivy-target": trivyResult.Target,
 | 
			
		||||
func setScanResultMeta(scanResult *models.ScanResult, trivyResult *report.Result) {
 | 
			
		||||
	if isTrivySupportedOS(trivyResult.Type) {
 | 
			
		||||
		scanResult.Family = trivyResult.Type
 | 
			
		||||
		scanResult.ServerName = trivyResult.Target
 | 
			
		||||
		scanResult.Optional = map[string]interface{}{
 | 
			
		||||
			trivyTarget: trivyResult.Target,
 | 
			
		||||
		}
 | 
			
		||||
	} else if isTrivySupportedLib(trivyResult.Type) {
 | 
			
		||||
		if scanResult.Family == "" {
 | 
			
		||||
			scanResult.Family = constant.ServerTypePseudo
 | 
			
		||||
		}
 | 
			
		||||
		if scanResult.ServerName == "" {
 | 
			
		||||
			scanResult.ServerName = "library scan by trivy"
 | 
			
		||||
		}
 | 
			
		||||
		if _, ok := scanResult.Optional[trivyTarget]; !ok {
 | 
			
		||||
			scanResult.Optional = map[string]interface{}{
 | 
			
		||||
				trivyTarget: trivyResult.Target,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	scanResult.ScannedAt = time.Now()
 | 
			
		||||
	scanResult.ScannedBy = "trivy"
 | 
			
		||||
	scanResult.ScannedVia = "trivy"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isTrivySupportedOS :
 | 
			
		||||
func isTrivySupportedOS(family string) bool {
 | 
			
		||||
	supportedFamilies := map[string]interface{}{
 | 
			
		||||
		os.RedHat:             struct{}{},
 | 
			
		||||
		os.Debian:             struct{}{},
 | 
			
		||||
		os.Ubuntu:             struct{}{},
 | 
			
		||||
		os.CentOS:             struct{}{},
 | 
			
		||||
		os.Fedora:             struct{}{},
 | 
			
		||||
		os.Amazon:             struct{}{},
 | 
			
		||||
		os.Oracle:             struct{}{},
 | 
			
		||||
		os.Windows:            struct{}{},
 | 
			
		||||
		os.OpenSUSE:           struct{}{},
 | 
			
		||||
		os.OpenSUSELeap:       struct{}{},
 | 
			
		||||
		os.OpenSUSETumbleweed: struct{}{},
 | 
			
		||||
		os.SLES:               struct{}{},
 | 
			
		||||
		os.Photon:             struct{}{},
 | 
			
		||||
		os.Alpine:             struct{}{},
 | 
			
		||||
	}
 | 
			
		||||
	_, ok := supportedFamilies[family]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isTrivySupportedLib(typestr string) bool {
 | 
			
		||||
	supportedLibs := map[string]interface{}{
 | 
			
		||||
		ftypes.Bundler:  struct{}{},
 | 
			
		||||
		ftypes.Cargo:    struct{}{},
 | 
			
		||||
		ftypes.Composer: struct{}{},
 | 
			
		||||
		ftypes.Npm:      struct{}{},
 | 
			
		||||
		ftypes.NuGet:    struct{}{},
 | 
			
		||||
		ftypes.Pip:      struct{}{},
 | 
			
		||||
		ftypes.Pipenv:   struct{}{},
 | 
			
		||||
		ftypes.Poetry:   struct{}{},
 | 
			
		||||
		ftypes.Yarn:     struct{}{},
 | 
			
		||||
		ftypes.Jar:      struct{}{},
 | 
			
		||||
		ftypes.GoBinary: struct{}{},
 | 
			
		||||
		ftypes.GoMod:    struct{}{},
 | 
			
		||||
	}
 | 
			
		||||
	_, ok := supportedLibs[typestr]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -202,7 +202,7 @@ func DetectPkgCves(r *models.ScanResult, ovalCnf config.GovalDictConf, gostCnf c
 | 
			
		||||
	} else if r.Family == constant.ServerTypePseudo {
 | 
			
		||||
		logging.Log.Infof("pseudo type. Skip OVAL and gost detection")
 | 
			
		||||
	} else {
 | 
			
		||||
		return xerrors.Errorf("Failed to fill CVEs. r.Release is empty")
 | 
			
		||||
		logging.Log.Infof("r.Release is empty. detect as pseudo type. Skip OVAL and gost detection")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, v := range r.ScannedCves {
 | 
			
		||||
@@ -307,9 +307,23 @@ func FillCvesWithNvdJvn(r *models.ScanResult, cnf config.GoCveDictConf, logOpts
 | 
			
		||||
				if vinfo.CveContents == nil {
 | 
			
		||||
					vinfo.CveContents = models.CveContents{}
 | 
			
		||||
				}
 | 
			
		||||
				for _, con := range append(nvds, jvns...) {
 | 
			
		||||
				for _, con := range nvds {
 | 
			
		||||
					if !con.Empty() {
 | 
			
		||||
						vinfo.CveContents[con.Type] = append(vinfo.CveContents[con.Type], con)
 | 
			
		||||
						vinfo.CveContents[con.Type] = []models.CveContent{con}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				for _, con := range jvns {
 | 
			
		||||
					if !con.Empty() {
 | 
			
		||||
						found := false
 | 
			
		||||
						for _, cveCont := range vinfo.CveContents[con.Type] {
 | 
			
		||||
							if con.SourceLink == cveCont.SourceLink {
 | 
			
		||||
								found = true
 | 
			
		||||
								break
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						if !found {
 | 
			
		||||
							vinfo.CveContents[con.Type] = append(vinfo.CveContents[con.Type], con)
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				vinfo.AlertDict = alerts
 | 
			
		||||
@@ -364,7 +378,7 @@ func detectPkgsCvesWithOval(cnf config.GovalDictConf, r *models.ScanResult) erro
 | 
			
		||||
	}
 | 
			
		||||
	if !ok {
 | 
			
		||||
		if r.Family == constant.Debian {
 | 
			
		||||
			logging.Log.Debug("Skip OVAL and Scan with gost alone.")
 | 
			
		||||
			logging.Log.Infof("Skip OVAL and Scan with gost alone.")
 | 
			
		||||
			logging.Log.Infof("%s: %d CVEs are detected with OVAL", r.FormatServerName(), 0)
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,7 @@ func DetectGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string,
 | 
			
		||||
 | 
			
		||||
				if val, ok := r.ScannedCves[cveID]; ok {
 | 
			
		||||
					val.GitHubSecurityAlerts = val.GitHubSecurityAlerts.Add(m)
 | 
			
		||||
					val.CveContents[models.GitHub] = append(val.CveContents[models.GitHub], cveContent)
 | 
			
		||||
					val.CveContents[models.GitHub] = []models.CveContent{cveContent}
 | 
			
		||||
					r.ScannedCves[cveID] = val
 | 
			
		||||
				} else {
 | 
			
		||||
					v := models.VulnInfo{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								go.mod
									
									
									
									
									
								
							@@ -7,11 +7,11 @@ require (
 | 
			
		||||
	github.com/BurntSushi/toml v0.3.1
 | 
			
		||||
	github.com/Ullaakut/nmap/v2 v2.1.2-0.20210406060955-59a52fe80a4f
 | 
			
		||||
	github.com/VividCortex/ewma v1.2.0 // indirect
 | 
			
		||||
	github.com/aquasecurity/fanal v0.0.0-20210719144537-c73c1e9f21bf
 | 
			
		||||
	github.com/aquasecurity/trivy v0.19.2
 | 
			
		||||
	github.com/aquasecurity/trivy-db v0.0.0-20210531102723-aaab62dec6ee
 | 
			
		||||
	github.com/aquasecurity/fanal v0.0.0-20210815095355-42429a80d0e3
 | 
			
		||||
	github.com/aquasecurity/trivy v0.19.3-0.20210909113250-19c0b70d2613
 | 
			
		||||
	github.com/aquasecurity/trivy-db v0.0.0-20210809142931-da8e09204404
 | 
			
		||||
	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
 | 
			
		||||
	github.com/aws/aws-sdk-go v1.37.0
 | 
			
		||||
	github.com/aws/aws-sdk-go v1.40.22
 | 
			
		||||
	github.com/boltdb/bolt v1.3.1
 | 
			
		||||
	github.com/briandowns/spinner v1.16.0 // indirect
 | 
			
		||||
	github.com/cenkalti/backoff v2.2.1+incompatible
 | 
			
		||||
@@ -29,7 +29,6 @@ require (
 | 
			
		||||
	github.com/hashicorp/go-uuid v1.0.2
 | 
			
		||||
	github.com/hashicorp/go-version v1.3.0
 | 
			
		||||
	github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
 | 
			
		||||
	github.com/jackc/pgx/v4 v4.13.0 // indirect
 | 
			
		||||
	github.com/jesseduffield/gocui v0.3.0
 | 
			
		||||
	github.com/k0kubun/pp v3.0.1+incompatible
 | 
			
		||||
	github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
 | 
			
		||||
@@ -39,9 +38,9 @@ require (
 | 
			
		||||
	github.com/knqyf263/gost v0.2.0
 | 
			
		||||
	github.com/kotakanbe/go-cve-dictionary v0.7.2-0.20210907024016-69922490c76a
 | 
			
		||||
	github.com/kotakanbe/go-pingscanner v0.1.0
 | 
			
		||||
	github.com/kotakanbe/goval-dictionary v0.3.6-0.20210625044258-9be85404d7dd
 | 
			
		||||
	github.com/kotakanbe/goval-dictionary v0.3.6-0.20210912113205-047e4dbfd356
 | 
			
		||||
	github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.13 // indirect
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.14 // indirect
 | 
			
		||||
	github.com/mattn/go-runewidth v0.0.13 // indirect
 | 
			
		||||
	github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
 | 
			
		||||
	github.com/mitchellh/go-homedir v1.1.0
 | 
			
		||||
@@ -49,8 +48,9 @@ require (
 | 
			
		||||
	github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 // indirect
 | 
			
		||||
	github.com/olekukonko/tablewriter v0.0.5
 | 
			
		||||
	github.com/parnurzeal/gorequest v0.2.16
 | 
			
		||||
	github.com/pelletier/go-toml v1.9.4 // indirect
 | 
			
		||||
	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
 | 
			
		||||
	github.com/sirupsen/logrus v1.8.0
 | 
			
		||||
	github.com/sirupsen/logrus v1.8.1
 | 
			
		||||
	github.com/spf13/afero v1.6.0
 | 
			
		||||
	github.com/spf13/cast v1.4.1 // indirect
 | 
			
		||||
	github.com/spf13/cobra v1.2.1
 | 
			
		||||
@@ -58,48 +58,53 @@ require (
 | 
			
		||||
	github.com/vulsio/go-exploitdb v0.2.0
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
 | 
			
		||||
	golang.org/x/net v0.0.0-20210902165921-8d991716f632 // indirect
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
 | 
			
		||||
	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
 | 
			
		||||
	golang.org/x/text v0.3.7 // indirect
 | 
			
		||||
	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
 | 
			
		||||
	gopkg.in/ini.v1 v1.63.0 // indirect
 | 
			
		||||
	gorm.io/driver/mysql v1.1.2 // indirect
 | 
			
		||||
	gorm.io/gorm v1.21.14 // indirect
 | 
			
		||||
	gorm.io/driver/postgres v1.1.1 // indirect
 | 
			
		||||
	gorm.io/driver/sqlite v1.1.5 // indirect
 | 
			
		||||
	k8s.io/utils v0.0.0-20210111153108-fddb29f9d009
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/Azure/go-autorest/autorest v0.10.2 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/autorest/adal v0.8.3 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/autorest/date v0.2.0 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/logger v0.1.0 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/tracing v0.5.0 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest v14.2.0+incompatible // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/autorest v0.11.1 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/autorest/adal v0.9.5 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/logger v0.2.0 // indirect
 | 
			
		||||
	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
 | 
			
		||||
	github.com/Masterminds/goutils v1.1.1 // indirect
 | 
			
		||||
	github.com/Masterminds/semver v1.5.0 // indirect
 | 
			
		||||
	github.com/Masterminds/sprig v2.22.0+incompatible // indirect
 | 
			
		||||
	github.com/aquasecurity/go-dep-parser v0.0.0-20210520015931-0dd56983cc62 // indirect
 | 
			
		||||
	github.com/aquasecurity/go-dep-parser v0.0.0-20210815080135-5be65146849a // indirect
 | 
			
		||||
	github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce // indirect
 | 
			
		||||
	github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 // indirect
 | 
			
		||||
	github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect
 | 
			
		||||
	github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect
 | 
			
		||||
	github.com/caarlos0/env/v6 v6.0.0 // indirect
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1 // indirect
 | 
			
		||||
	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
 | 
			
		||||
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 | 
			
		||||
	github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect
 | 
			
		||||
	github.com/go-redis/redis v6.15.9+incompatible // indirect
 | 
			
		||||
	github.com/go-sql-driver/mysql v1.6.0 // indirect
 | 
			
		||||
	github.com/golang/protobuf v1.5.2 // indirect
 | 
			
		||||
	github.com/google/go-github/v33 v33.0.0 // indirect
 | 
			
		||||
	github.com/google/go-querystring v1.0.0 // indirect
 | 
			
		||||
	github.com/google/uuid v1.2.0 // indirect
 | 
			
		||||
	github.com/google/uuid v1.3.0 // indirect
 | 
			
		||||
	github.com/google/wire v0.4.0 // indirect
 | 
			
		||||
	github.com/gorilla/websocket v1.4.2 // indirect
 | 
			
		||||
	github.com/grokify/html-strip-tags-go v0.0.1 // indirect
 | 
			
		||||
	github.com/hashicorp/errwrap v1.1.0 // indirect
 | 
			
		||||
	github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
 | 
			
		||||
	github.com/hashicorp/go-multierror v1.1.1 // indirect
 | 
			
		||||
	github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
 | 
			
		||||
	github.com/hashicorp/hcl v1.0.0 // indirect
 | 
			
		||||
	github.com/htcat/htcat v1.0.2 // indirect
 | 
			
		||||
	github.com/huandu/xstrings v1.3.2 // indirect
 | 
			
		||||
	github.com/imdario/mergo v0.3.9 // indirect
 | 
			
		||||
	github.com/imdario/mergo v0.3.12 // indirect
 | 
			
		||||
	github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac // indirect
 | 
			
		||||
	github.com/inconshreveable/mousetrap v1.0.0 // indirect
 | 
			
		||||
	github.com/jackc/chunkreader/v2 v2.0.1 // indirect
 | 
			
		||||
@@ -109,11 +114,11 @@ require (
 | 
			
		||||
	github.com/jackc/pgproto3/v2 v2.1.1 // indirect
 | 
			
		||||
	github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
 | 
			
		||||
	github.com/jackc/pgtype v1.8.1 // indirect
 | 
			
		||||
	github.com/jackc/pgx/v4 v4.13.0 // indirect
 | 
			
		||||
	github.com/jinzhu/inflection v1.0.0 // indirect
 | 
			
		||||
	github.com/jinzhu/now v1.1.2 // indirect
 | 
			
		||||
	github.com/jmespath/go-jmespath v0.4.0 // indirect
 | 
			
		||||
	github.com/labstack/gommon v0.3.0 // indirect
 | 
			
		||||
	github.com/magefile/mage v1.11.0 // indirect
 | 
			
		||||
	github.com/magiconair/properties v1.8.5 // indirect
 | 
			
		||||
	github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 // indirect
 | 
			
		||||
	github.com/mattn/go-colorable v0.1.8 // indirect
 | 
			
		||||
@@ -121,7 +126,6 @@ require (
 | 
			
		||||
	github.com/mitchellh/copystructure v1.1.1 // indirect
 | 
			
		||||
	github.com/mitchellh/mapstructure v1.4.1 // indirect
 | 
			
		||||
	github.com/mitchellh/reflectwalk v1.0.1 // indirect
 | 
			
		||||
	github.com/pelletier/go-toml v1.9.4 // indirect
 | 
			
		||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
			
		||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
			
		||||
	github.com/rivo/uniseg v0.2.0 // indirect
 | 
			
		||||
@@ -135,7 +139,7 @@ require (
 | 
			
		||||
	github.com/valyala/bytebufferpool v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/fasttemplate v1.2.1 // indirect
 | 
			
		||||
	github.com/ymomoi/goval-parser v0.0.0-20170813122243-0a0be1dd9d08 // indirect
 | 
			
		||||
	go.etcd.io/bbolt v1.3.5 // indirect
 | 
			
		||||
	go.etcd.io/bbolt v1.3.6 // indirect
 | 
			
		||||
	go.uber.org/atomic v1.7.0 // indirect
 | 
			
		||||
	go.uber.org/multierr v1.6.0 // indirect
 | 
			
		||||
	go.uber.org/zap v1.17.0 // indirect
 | 
			
		||||
@@ -144,10 +148,8 @@ require (
 | 
			
		||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.26.0 // indirect
 | 
			
		||||
	gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
 | 
			
		||||
	gopkg.in/ini.v1 v1.63.0 // indirect
 | 
			
		||||
	gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 | 
			
		||||
	gorm.io/driver/postgres v1.1.0 // indirect
 | 
			
		||||
	gorm.io/driver/sqlite v1.1.4 // indirect
 | 
			
		||||
	gorm.io/gorm v1.21.15 // indirect
 | 
			
		||||
	moul.io/http2curl v1.0.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ func (deb Debian) supported(major string) bool {
 | 
			
		||||
		"8":  "jessie",
 | 
			
		||||
		"9":  "stretch",
 | 
			
		||||
		"10": "buster",
 | 
			
		||||
		"11": "bullseye",
 | 
			
		||||
	}[major]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
@@ -142,7 +143,7 @@ func (deb Debian) detectCVEsWithFixState(r *models.ScanResult, fixStatus string)
 | 
			
		||||
				if v.CveContents == nil {
 | 
			
		||||
					v.CveContents = models.NewCveContents(cve)
 | 
			
		||||
				} else {
 | 
			
		||||
					v.CveContents[models.DebianSecurityTracker] = append(v.CveContents[models.DebianSecurityTracker], cve)
 | 
			
		||||
					v.CveContents[models.DebianSecurityTracker] = []models.CveContent{cve}
 | 
			
		||||
					v.Confidences = models.Confidences{models.DebianSecurityTrackerMatch}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -39,10 +39,17 @@ func TestDebian_Supported(t *testing.T) {
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "11 is not supported yet",
 | 
			
		||||
			name: "11 is supported",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "11",
 | 
			
		||||
			},
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "12 is not supported yet",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "12",
 | 
			
		||||
			},
 | 
			
		||||
			want: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ func (ms Microsoft) DetectCVEs(r *models.ScanResult, _ bool) (nCVEs int, err err
 | 
			
		||||
		if v.CveContents == nil {
 | 
			
		||||
			v.CveContents = models.CveContents{}
 | 
			
		||||
		}
 | 
			
		||||
		v.CveContents[models.Microsoft] = append(v.CveContents[models.Microsoft], *cveCont)
 | 
			
		||||
		v.CveContents[models.Microsoft] = []models.CveContent{*cveCont}
 | 
			
		||||
		v.Mitigations = append(v.Mitigations, mitigations...)
 | 
			
		||||
		r.ScannedCves[cveID] = v
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ func (red RedHat) setFixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models.S
 | 
			
		||||
		if v.CveContents == nil {
 | 
			
		||||
			v.CveContents = models.NewCveContents(*cveCont)
 | 
			
		||||
		} else {
 | 
			
		||||
			v.CveContents[models.RedHatAPI] = append(v.CveContents[models.RedHatAPI], *cveCont)
 | 
			
		||||
			v.CveContents[models.RedHatAPI] = []models.CveContent{*cveCont}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		v = models.VulnInfo{
 | 
			
		||||
@@ -123,7 +123,7 @@ func (red RedHat) setUnfixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models
 | 
			
		||||
		if v.CveContents == nil {
 | 
			
		||||
			v.CveContents = models.NewCveContents(*cveCont)
 | 
			
		||||
		} else {
 | 
			
		||||
			v.CveContents[models.RedHatAPI] = append(v.CveContents[models.RedHatAPI], *cveCont)
 | 
			
		||||
			v.CveContents[models.RedHatAPI] = []models.CveContent{*cveCont}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		v = models.VulnInfo{
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ func (ubu Ubuntu) DetectCVEs(r *models.ScanResult, _ bool) (nCVEs int, err error
 | 
			
		||||
				if v.CveContents == nil {
 | 
			
		||||
					v.CveContents = models.NewCveContents(cve)
 | 
			
		||||
				} else {
 | 
			
		||||
					v.CveContents[models.UbuntuAPI] = append(v.CveContents[models.UbuntuAPI], cve)
 | 
			
		||||
					v.CveContents[models.UbuntuAPI] = []models.CveContent{cve}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				v = models.VulnInfo{
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,20 @@ type CveContents map[CveContentType][]CveContent
 | 
			
		||||
func NewCveContents(conts ...CveContent) CveContents {
 | 
			
		||||
	m := CveContents{}
 | 
			
		||||
	for _, cont := range conts {
 | 
			
		||||
		m[cont.Type] = append(m[cont.Type], cont)
 | 
			
		||||
		if cont.Type == Jvn {
 | 
			
		||||
			found := false
 | 
			
		||||
			for _, cveCont := range m[cont.Type] {
 | 
			
		||||
				if cont.SourceLink == cveCont.SourceLink {
 | 
			
		||||
					found = true
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if !found {
 | 
			
		||||
				m[cont.Type] = append(m[cont.Type], cont)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			m[cont.Type] = []CveContent{cont}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
@@ -229,6 +242,7 @@ func (v CveContents) UniqCweIDs(myFamily string) (values []CveContentStr) {
 | 
			
		||||
	return values
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sort elements for integration-testing
 | 
			
		||||
func (v CveContents) Sort() {
 | 
			
		||||
	for contType, contents := range v {
 | 
			
		||||
		// CVSS3 desc, CVSS2 desc, SourceLink asc
 | 
			
		||||
 
 | 
			
		||||
@@ -106,15 +106,16 @@ func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[
 | 
			
		||||
		refs = append(refs, Reference{Source: "trivy", Link: refURL})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	content := CveContent{
 | 
			
		||||
		Type:          Trivy,
 | 
			
		||||
		CveID:         cveID,
 | 
			
		||||
		Title:         vul.Title,
 | 
			
		||||
		Summary:       vul.Description,
 | 
			
		||||
		Cvss3Severity: string(vul.Severity),
 | 
			
		||||
		References:    refs,
 | 
			
		||||
	contents[Trivy] = []CveContent{
 | 
			
		||||
		{
 | 
			
		||||
			Type:          Trivy,
 | 
			
		||||
			CveID:         cveID,
 | 
			
		||||
			Title:         vul.Title,
 | 
			
		||||
			Summary:       vul.Description,
 | 
			
		||||
			Cvss3Severity: string(vul.Severity),
 | 
			
		||||
			References:    refs,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	contents[Trivy] = append(contents[Trivy], content)
 | 
			
		||||
	return contents
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -893,7 +893,7 @@ const (
 | 
			
		||||
	// ChangelogExactMatchStr :
 | 
			
		||||
	ChangelogExactMatchStr = "ChangelogExactMatch"
 | 
			
		||||
 | 
			
		||||
	// ChangelogRoughMatch :
 | 
			
		||||
	// ChangelogRoughMatchStr :
 | 
			
		||||
	ChangelogRoughMatchStr = "ChangelogRoughMatch"
 | 
			
		||||
 | 
			
		||||
	// GitHubMatchStr :
 | 
			
		||||
 
 | 
			
		||||
@@ -54,8 +54,8 @@ func (o Alpine) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
	return len(relatedDefs.entries), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Alpine) update(r *models.ScanResult, defPacks defPacks) {
 | 
			
		||||
	cveID := defPacks.def.Advisory.Cves[0].CveID
 | 
			
		||||
func (o Alpine) update(r *models.ScanResult, defpacks defPacks) {
 | 
			
		||||
	cveID := defpacks.def.Advisory.Cves[0].CveID
 | 
			
		||||
	vinfo, ok := r.ScannedCves[cveID]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		logging.Log.Debugf("%s is newly detected by OVAL", cveID)
 | 
			
		||||
@@ -65,7 +65,7 @@ func (o Alpine) update(r *models.ScanResult, defPacks defPacks) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vinfo.AffectedPackages = defPacks.toPackStatuses()
 | 
			
		||||
	vinfo.AffectedPackages = defpacks.toPackStatuses()
 | 
			
		||||
	vinfo.AffectedPackages.Sort()
 | 
			
		||||
	r.ScannedCves[cveID] = vinfo
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								oval/debian.go
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								oval/debian.go
									
									
									
									
									
								
							@@ -20,73 +20,75 @@ type DebianBase struct {
 | 
			
		||||
	Base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
 | 
			
		||||
	ovalContent := *o.convertToModel(&defPacks.def)
 | 
			
		||||
	ovalContent.Type = models.NewCveContentType(o.family)
 | 
			
		||||
	vinfo, ok := r.ScannedCves[defPacks.def.Debian.CveID]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		logging.Log.Debugf("%s is newly detected by OVAL", defPacks.def.Debian.CveID)
 | 
			
		||||
		vinfo = models.VulnInfo{
 | 
			
		||||
			CveID:       defPacks.def.Debian.CveID,
 | 
			
		||||
			Confidences: []models.Confidence{models.OvalMatch},
 | 
			
		||||
			CveContents: models.NewCveContents(ovalContent),
 | 
			
		||||
func (o DebianBase) update(r *models.ScanResult, defpacks defPacks) {
 | 
			
		||||
	for _, cve := range defpacks.def.Advisory.Cves {
 | 
			
		||||
		ovalContent := o.convertToModel(cve.CveID, &defpacks.def)
 | 
			
		||||
		if ovalContent == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		cveContents := vinfo.CveContents
 | 
			
		||||
		ctype := models.NewCveContentType(o.family)
 | 
			
		||||
		if _, ok := vinfo.CveContents[ctype]; ok {
 | 
			
		||||
			logging.Log.Debugf("%s OVAL will be overwritten",
 | 
			
		||||
				defPacks.def.Debian.CveID)
 | 
			
		||||
		vinfo, ok := r.ScannedCves[cve.CveID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			logging.Log.Debugf("%s is newly detected by OVAL", cve.CveID)
 | 
			
		||||
			vinfo = models.VulnInfo{
 | 
			
		||||
				CveID:       cve.CveID,
 | 
			
		||||
				Confidences: []models.Confidence{models.OvalMatch},
 | 
			
		||||
				CveContents: models.NewCveContents(*ovalContent),
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			logging.Log.Debugf("%s is also detected by OVAL",
 | 
			
		||||
				defPacks.def.Debian.CveID)
 | 
			
		||||
			cveContents = models.CveContents{}
 | 
			
		||||
		}
 | 
			
		||||
		if r.Family != constant.Raspbian {
 | 
			
		||||
			cveContents := vinfo.CveContents
 | 
			
		||||
			if _, ok := vinfo.CveContents[ovalContent.Type]; ok {
 | 
			
		||||
				logging.Log.Debugf("%s OVAL will be overwritten", cve.CveID)
 | 
			
		||||
			} else {
 | 
			
		||||
				logging.Log.Debugf("%s is also detected by OVAL", cve.CveID)
 | 
			
		||||
				cveContents = models.CveContents{}
 | 
			
		||||
			}
 | 
			
		||||
			vinfo.Confidences.AppendIfMissing(models.OvalMatch)
 | 
			
		||||
		} else {
 | 
			
		||||
			if len(vinfo.Confidences) == 0 {
 | 
			
		||||
				vinfo.Confidences.AppendIfMissing(models.OvalMatch)
 | 
			
		||||
			cveContents[ovalContent.Type] = []models.CveContent{*ovalContent}
 | 
			
		||||
			vinfo.CveContents = cveContents
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// uniq(vinfo.AffectedPackages[].Name + defPacks.binpkgFixstat(map[string(=package name)]fixStat{}))
 | 
			
		||||
		collectBinpkgFixstat := defPacks{
 | 
			
		||||
			binpkgFixstat: map[string]fixStat{},
 | 
			
		||||
		}
 | 
			
		||||
		for packName, fixStatus := range defpacks.binpkgFixstat {
 | 
			
		||||
			collectBinpkgFixstat.binpkgFixstat[packName] = fixStatus
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, pack := range vinfo.AffectedPackages {
 | 
			
		||||
			collectBinpkgFixstat.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
				notFixedYet: pack.NotFixedYet,
 | 
			
		||||
				fixedIn:     pack.FixedIn,
 | 
			
		||||
				isSrcPack:   false,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		cveContents[ctype] = append(cveContents[ctype], ovalContent)
 | 
			
		||||
		vinfo.CveContents = cveContents
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// uniq(vinfo.PackNames + defPacks.binpkgStat)
 | 
			
		||||
	for _, pack := range vinfo.AffectedPackages {
 | 
			
		||||
		defPacks.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
			notFixedYet: pack.NotFixedYet,
 | 
			
		||||
			fixedIn:     pack.FixedIn,
 | 
			
		||||
			isSrcPack:   false,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update package status of source packages.
 | 
			
		||||
	// In the case of Debian based Linux, sometimes source package name is defined 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.binpkgFixstat[binName] = fixStat{
 | 
			
		||||
						notFixedYet: p.NotFixedYet,
 | 
			
		||||
						fixedIn:     p.Version,
 | 
			
		||||
						isSrcPack:   true,
 | 
			
		||||
						srcPackName: srcPack.Name,
 | 
			
		||||
		// Update package status of source packages.
 | 
			
		||||
		// In the case of Debian based Linux, sometimes source package name is defined 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 {
 | 
			
		||||
						collectBinpkgFixstat.binpkgFixstat[binName] = fixStat{
 | 
			
		||||
							notFixedYet: p.NotFixedYet,
 | 
			
		||||
							fixedIn:     p.Version,
 | 
			
		||||
							isSrcPack:   true,
 | 
			
		||||
							srcPackName: srcPack.Name,
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vinfo.AffectedPackages = defPacks.toPackStatuses()
 | 
			
		||||
	vinfo.AffectedPackages.Sort()
 | 
			
		||||
	r.ScannedCves[defPacks.def.Debian.CveID] = vinfo
 | 
			
		||||
		vinfo.AffectedPackages = collectBinpkgFixstat.toPackStatuses()
 | 
			
		||||
		vinfo.AffectedPackages.Sort()
 | 
			
		||||
		r.ScannedCves[cve.CveID] = vinfo
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o DebianBase) convertToModel(def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
	refs := []models.Reference{}
 | 
			
		||||
func (o DebianBase) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
	refs := make([]models.Reference, 0, len(def.References))
 | 
			
		||||
	for _, r := range def.References {
 | 
			
		||||
		refs = append(refs, models.Reference{
 | 
			
		||||
			Link:   r.RefURL,
 | 
			
		||||
@@ -95,14 +97,23 @@ func (o DebianBase) convertToModel(def *ovalmodels.Definition) *models.CveConten
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &models.CveContent{
 | 
			
		||||
		CveID:         def.Debian.CveID,
 | 
			
		||||
		Title:         def.Title,
 | 
			
		||||
		Summary:       def.Description,
 | 
			
		||||
		Cvss2Severity: def.Advisory.Severity,
 | 
			
		||||
		Cvss3Severity: def.Advisory.Severity,
 | 
			
		||||
		References:    refs,
 | 
			
		||||
	for _, cve := range def.Advisory.Cves {
 | 
			
		||||
		if cve.CveID != cveID {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return &models.CveContent{
 | 
			
		||||
			Type:          models.NewCveContentType(o.family),
 | 
			
		||||
			CveID:         cve.CveID,
 | 
			
		||||
			Title:         def.Title,
 | 
			
		||||
			Summary:       def.Description,
 | 
			
		||||
			Cvss2Severity: def.Advisory.Severity,
 | 
			
		||||
			Cvss3Severity: def.Advisory.Severity,
 | 
			
		||||
			References:    refs,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Debian is the interface for Debian OVAL
 | 
			
		||||
@@ -183,9 +194,9 @@ func (o Debian) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
 | 
			
		||||
	for _, vuln := range r.ScannedCves {
 | 
			
		||||
		if conts, ok := vuln.CveContents[models.Debian]; ok {
 | 
			
		||||
			for _, cont := range conts {
 | 
			
		||||
			for i, cont := range conts {
 | 
			
		||||
				cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID
 | 
			
		||||
				vuln.CveContents[models.Debian] = append(vuln.CveContents[models.Debian], cont)
 | 
			
		||||
				vuln.CveContents[models.Debian][i] = cont
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -502,9 +513,9 @@ func (o Ubuntu) fillWithOval(r *models.ScanResult, kernelNamesInOval []string) (
 | 
			
		||||
 | 
			
		||||
	for _, vuln := range r.ScannedCves {
 | 
			
		||||
		if conts, ok := vuln.CveContents[models.Ubuntu]; ok {
 | 
			
		||||
			for _, cont := range conts {
 | 
			
		||||
			for i, cont := range conts {
 | 
			
		||||
				cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID
 | 
			
		||||
				vuln.CveContents[models.Ubuntu] = append(vuln.CveContents[models.Ubuntu], cont)
 | 
			
		||||
				vuln.CveContents[models.Ubuntu][i] = cont
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,8 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			defPacks: defPacks{
 | 
			
		||||
				def: ovalmodels.Definition{
 | 
			
		||||
					Debian: ovalmodels.Debian{
 | 
			
		||||
						CveID: "CVE-2000-1000",
 | 
			
		||||
					Advisory: ovalmodels.Advisory{
 | 
			
		||||
						Cves: []ovalmodels.Cve{{CveID: "CVE-2000-1000"}},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				binpkgFixstat: map[string]fixStat{
 | 
			
		||||
@@ -53,15 +53,68 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: models.ScanResult{
 | 
			
		||||
				ScannedCves: models.VulnInfos{
 | 
			
		||||
					"CVE-2000-1000": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packA"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2000-1001": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packC"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			defPacks: defPacks{
 | 
			
		||||
				def: ovalmodels.Definition{
 | 
			
		||||
					Advisory: ovalmodels.Advisory{
 | 
			
		||||
						Cves: []ovalmodels.Cve{
 | 
			
		||||
							{
 | 
			
		||||
								CveID: "CVE-2000-1000",
 | 
			
		||||
							},
 | 
			
		||||
							{
 | 
			
		||||
								CveID: "CVE-2000-1001",
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				binpkgFixstat: map[string]fixStat{
 | 
			
		||||
					"packB": {
 | 
			
		||||
						notFixedYet: false,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			out: models.ScanResult{
 | 
			
		||||
				ScannedCves: models.VulnInfos{
 | 
			
		||||
					"CVE-2000-1000": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packA"},
 | 
			
		||||
							{Name: "packB", NotFixedYet: false},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2000-1001": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packB", NotFixedYet: false},
 | 
			
		||||
							{Name: "packC"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// util.Log = util.NewCustomLogger()
 | 
			
		||||
	for i, tt := range tests {
 | 
			
		||||
		Debian{}.update(&tt.in, tt.defPacks)
 | 
			
		||||
		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)
 | 
			
		||||
		for cveid := range tt.out.ScannedCves {
 | 
			
		||||
			e := tt.out.ScannedCves[cveid].AffectedPackages
 | 
			
		||||
			a := tt.in.ScannedCves[cveid].AffectedPackages
 | 
			
		||||
			if !reflect.DeepEqual(a, e) {
 | 
			
		||||
				t.Errorf("[%d] expected: %v\n  actual: %v\n", i, e, a)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -52,16 +52,16 @@ func (o RedHatBase) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
		switch models.NewCveContentType(o.family) {
 | 
			
		||||
		case models.RedHat:
 | 
			
		||||
			if conts, ok := vuln.CveContents[models.RedHat]; ok {
 | 
			
		||||
				for _, cont := range conts {
 | 
			
		||||
				for i, cont := range conts {
 | 
			
		||||
					cont.SourceLink = "https://access.redhat.com/security/cve/" + cont.CveID
 | 
			
		||||
					vuln.CveContents[models.RedHat] = append(vuln.CveContents[models.RedHat], cont)
 | 
			
		||||
					vuln.CveContents[models.RedHat][i] = cont
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case models.Oracle:
 | 
			
		||||
			if conts, ok := vuln.CveContents[models.Oracle]; ok {
 | 
			
		||||
				for _, cont := range conts {
 | 
			
		||||
				for i, cont := range conts {
 | 
			
		||||
					cont.SourceLink = fmt.Sprintf("https://linux.oracle.com/cve/%s.html", cont.CveID)
 | 
			
		||||
					vuln.CveContents[models.Oracle] = append(vuln.CveContents[models.Oracle], cont)
 | 
			
		||||
					vuln.CveContents[models.Oracle][i] = cont
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -102,57 +102,66 @@ var kernelRelatedPackNames = map[string]bool{
 | 
			
		||||
	"python-perf":             true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) {
 | 
			
		||||
	ctype := models.NewCveContentType(o.family)
 | 
			
		||||
	for _, cve := range defPacks.def.Advisory.Cves {
 | 
			
		||||
		ovalContent := *o.convertToModel(cve.CveID, &defPacks.def)
 | 
			
		||||
func (o RedHatBase) update(r *models.ScanResult, defpacks defPacks) (nCVEs int) {
 | 
			
		||||
	for _, cve := range defpacks.def.Advisory.Cves {
 | 
			
		||||
		ovalContent := o.convertToModel(cve.CveID, &defpacks.def)
 | 
			
		||||
		if ovalContent == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		vinfo, ok := r.ScannedCves[cve.CveID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			logging.Log.Debugf("%s is newly detected by OVAL: DefID: %s", cve.CveID, defPacks.def.DefinitionID)
 | 
			
		||||
			logging.Log.Debugf("%s is newly detected by OVAL: DefID: %s", cve.CveID, defpacks.def.DefinitionID)
 | 
			
		||||
			vinfo = models.VulnInfo{
 | 
			
		||||
				CveID:       cve.CveID,
 | 
			
		||||
				Confidences: models.Confidences{models.OvalMatch},
 | 
			
		||||
				CveContents: models.NewCveContents(ovalContent),
 | 
			
		||||
				CveContents: models.NewCveContents(*ovalContent),
 | 
			
		||||
			}
 | 
			
		||||
			nCVEs++
 | 
			
		||||
		} else {
 | 
			
		||||
			cveContents := vinfo.CveContents
 | 
			
		||||
			if v, ok := vinfo.CveContents[ctype]; ok {
 | 
			
		||||
			if v, ok := vinfo.CveContents[ovalContent.Type]; ok {
 | 
			
		||||
				for _, vv := range v {
 | 
			
		||||
					if vv.LastModified.After(ovalContent.LastModified) {
 | 
			
		||||
						logging.Log.Debugf("%s ignored. DefID: %s ", cve.CveID, defPacks.def.DefinitionID)
 | 
			
		||||
						logging.Log.Debugf("%s ignored. DefID: %s ", cve.CveID, defpacks.def.DefinitionID)
 | 
			
		||||
					} else {
 | 
			
		||||
						logging.Log.Debugf("%s OVAL will be overwritten. DefID: %s", cve.CveID, defPacks.def.DefinitionID)
 | 
			
		||||
						logging.Log.Debugf("%s OVAL will be overwritten. DefID: %s", cve.CveID, defpacks.def.DefinitionID)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				logging.Log.Debugf("%s also detected by OVAL. DefID: %s", cve.CveID, defPacks.def.DefinitionID)
 | 
			
		||||
				logging.Log.Debugf("%s also detected by OVAL. DefID: %s", cve.CveID, defpacks.def.DefinitionID)
 | 
			
		||||
				cveContents = models.CveContents{}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			vinfo.Confidences.AppendIfMissing(models.OvalMatch)
 | 
			
		||||
			cveContents[ctype] = append(cveContents[ctype], ovalContent)
 | 
			
		||||
			cveContents[ovalContent.Type] = []models.CveContent{*ovalContent}
 | 
			
		||||
			vinfo.CveContents = cveContents
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		vinfo.DistroAdvisories.AppendIfMissing(
 | 
			
		||||
			o.convertToDistroAdvisory(&defPacks.def))
 | 
			
		||||
			o.convertToDistroAdvisory(&defpacks.def))
 | 
			
		||||
 | 
			
		||||
		// uniq(vinfo.AffectedPackages[].Name + defPacks.binpkgFixstat(map[string(=package name)]fixStat{}))
 | 
			
		||||
		collectBinpkgFixstat := defPacks{
 | 
			
		||||
			binpkgFixstat: map[string]fixStat{},
 | 
			
		||||
		}
 | 
			
		||||
		for packName, fixStatus := range defpacks.binpkgFixstat {
 | 
			
		||||
			collectBinpkgFixstat.binpkgFixstat[packName] = fixStatus
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
 | 
			
		||||
		for _, pack := range vinfo.AffectedPackages {
 | 
			
		||||
			if stat, ok := defPacks.binpkgFixstat[pack.Name]; !ok {
 | 
			
		||||
				defPacks.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
			if stat, ok := collectBinpkgFixstat.binpkgFixstat[pack.Name]; !ok {
 | 
			
		||||
				collectBinpkgFixstat.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
					notFixedYet: pack.NotFixedYet,
 | 
			
		||||
					fixedIn:     pack.FixedIn,
 | 
			
		||||
				}
 | 
			
		||||
			} else if stat.notFixedYet {
 | 
			
		||||
				defPacks.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
				collectBinpkgFixstat.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
					notFixedYet: true,
 | 
			
		||||
					fixedIn:     pack.FixedIn,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		vinfo.AffectedPackages = defPacks.toPackStatuses()
 | 
			
		||||
		vinfo.AffectedPackages = collectBinpkgFixstat.toPackStatuses()
 | 
			
		||||
		vinfo.AffectedPackages.Sort()
 | 
			
		||||
		r.ScannedCves[cve.CveID] = vinfo
 | 
			
		||||
	}
 | 
			
		||||
@@ -178,18 +187,19 @@ func (o RedHatBase) convertToDistroAdvisory(def *ovalmodels.Definition) *models.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
	refs := make([]models.Reference, 0, len(def.References))
 | 
			
		||||
	for _, r := range def.References {
 | 
			
		||||
		refs = append(refs, models.Reference{
 | 
			
		||||
			Link:   r.RefURL,
 | 
			
		||||
			Source: r.Source,
 | 
			
		||||
			RefID:  r.RefID,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, cve := range def.Advisory.Cves {
 | 
			
		||||
		if cve.CveID != cveID {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		var refs []models.Reference
 | 
			
		||||
		for _, r := range def.References {
 | 
			
		||||
			refs = append(refs, models.Reference{
 | 
			
		||||
				Link:   r.RefURL,
 | 
			
		||||
				Source: r.Source,
 | 
			
		||||
				RefID:  r.RefID,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		score2, vec2 := o.parseCvss2(cve.Cvss2)
 | 
			
		||||
		score3, vec3 := o.parseCvss3(cve.Cvss3)
 | 
			
		||||
 
 | 
			
		||||
@@ -129,15 +129,68 @@ func TestPackNamesOfUpdate(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: models.ScanResult{
 | 
			
		||||
				ScannedCves: models.VulnInfos{
 | 
			
		||||
					"CVE-2000-1000": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packA"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2000-1001": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packC"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			defPacks: defPacks{
 | 
			
		||||
				def: ovalmodels.Definition{
 | 
			
		||||
					Advisory: ovalmodels.Advisory{
 | 
			
		||||
						Cves: []ovalmodels.Cve{
 | 
			
		||||
							{
 | 
			
		||||
								CveID: "CVE-2000-1000",
 | 
			
		||||
							},
 | 
			
		||||
							{
 | 
			
		||||
								CveID: "CVE-2000-1001",
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				binpkgFixstat: map[string]fixStat{
 | 
			
		||||
					"packB": {
 | 
			
		||||
						notFixedYet: false,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			out: models.ScanResult{
 | 
			
		||||
				ScannedCves: models.VulnInfos{
 | 
			
		||||
					"CVE-2000-1000": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packA"},
 | 
			
		||||
							{Name: "packB", NotFixedYet: false},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2000-1001": models.VulnInfo{
 | 
			
		||||
						AffectedPackages: models.PackageFixStatuses{
 | 
			
		||||
							{Name: "packB", NotFixedYet: false},
 | 
			
		||||
							{Name: "packC"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// util.Log = util.Logger{}.NewCustomLogger()
 | 
			
		||||
	for i, tt := range tests {
 | 
			
		||||
		RedHat{}.update(&tt.in, tt.defPacks)
 | 
			
		||||
		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)
 | 
			
		||||
		for cveid := range tt.out.ScannedCves {
 | 
			
		||||
			e := tt.out.ScannedCves[cveid].AffectedPackages
 | 
			
		||||
			a := tt.in.ScannedCves[cveid].AffectedPackages
 | 
			
		||||
			if !reflect.DeepEqual(a, e) {
 | 
			
		||||
				t.Errorf("[%d] expected: %v\n  actual: %v\n", i, e, a)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								oval/suse.go
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								oval/suse.go
									
									
									
									
									
								
							@@ -55,23 +55,23 @@ func (o SUSE) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
 | 
			
		||||
	for _, vuln := range r.ScannedCves {
 | 
			
		||||
		if conts, ok := vuln.CveContents[models.SUSE]; ok {
 | 
			
		||||
			for _, cont := range conts {
 | 
			
		||||
			for i, cont := range conts {
 | 
			
		||||
				cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID
 | 
			
		||||
				vuln.CveContents[models.SUSE] = append(vuln.CveContents[models.SUSE], cont)
 | 
			
		||||
				vuln.CveContents[models.SUSE][i] = cont
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return len(relatedDefs.entries), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
 | 
			
		||||
	ovalContent := *o.convertToModel(&defPacks.def)
 | 
			
		||||
func (o SUSE) update(r *models.ScanResult, defpacks defPacks) {
 | 
			
		||||
	ovalContent := *o.convertToModel(&defpacks.def)
 | 
			
		||||
	ovalContent.Type = models.NewCveContentType(o.family)
 | 
			
		||||
	vinfo, ok := r.ScannedCves[defPacks.def.Title]
 | 
			
		||||
	vinfo, ok := r.ScannedCves[defpacks.def.Title]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		logging.Log.Debugf("%s is newly detected by OVAL", defPacks.def.Title)
 | 
			
		||||
		logging.Log.Debugf("%s is newly detected by OVAL", defpacks.def.Title)
 | 
			
		||||
		vinfo = models.VulnInfo{
 | 
			
		||||
			CveID:       defPacks.def.Title,
 | 
			
		||||
			CveID:       defpacks.def.Title,
 | 
			
		||||
			Confidences: models.Confidences{models.OvalMatch},
 | 
			
		||||
			CveContents: models.NewCveContents(ovalContent),
 | 
			
		||||
		}
 | 
			
		||||
@@ -79,26 +79,33 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
 | 
			
		||||
		cveContents := vinfo.CveContents
 | 
			
		||||
		ctype := models.NewCveContentType(o.family)
 | 
			
		||||
		if _, ok := vinfo.CveContents[ctype]; ok {
 | 
			
		||||
			logging.Log.Debugf("%s OVAL will be overwritten", defPacks.def.Title)
 | 
			
		||||
			logging.Log.Debugf("%s OVAL will be overwritten", defpacks.def.Title)
 | 
			
		||||
		} else {
 | 
			
		||||
			logging.Log.Debugf("%s is also detected by OVAL", defPacks.def.Title)
 | 
			
		||||
			logging.Log.Debugf("%s is also detected by OVAL", defpacks.def.Title)
 | 
			
		||||
			cveContents = models.CveContents{}
 | 
			
		||||
		}
 | 
			
		||||
		vinfo.Confidences.AppendIfMissing(models.OvalMatch)
 | 
			
		||||
		cveContents[ctype] = append(cveContents[ctype], ovalContent)
 | 
			
		||||
		cveContents[ctype] = []models.CveContent{ovalContent}
 | 
			
		||||
		vinfo.CveContents = cveContents
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
 | 
			
		||||
	// uniq(vinfo.AffectedPackages[].Name + defPacks.binpkgFixstat(map[string(=package name)]fixStat{}))
 | 
			
		||||
	collectBinpkgFixstat := defPacks{
 | 
			
		||||
		binpkgFixstat: map[string]fixStat{},
 | 
			
		||||
	}
 | 
			
		||||
	for packName, fixStatus := range defpacks.binpkgFixstat {
 | 
			
		||||
		collectBinpkgFixstat.binpkgFixstat[packName] = fixStatus
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, pack := range vinfo.AffectedPackages {
 | 
			
		||||
		defPacks.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
		collectBinpkgFixstat.binpkgFixstat[pack.Name] = fixStat{
 | 
			
		||||
			notFixedYet: pack.NotFixedYet,
 | 
			
		||||
			fixedIn:     pack.FixedIn,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	vinfo.AffectedPackages = defPacks.toPackStatuses()
 | 
			
		||||
	vinfo.AffectedPackages = collectBinpkgFixstat.toPackStatuses()
 | 
			
		||||
	vinfo.AffectedPackages.Sort()
 | 
			
		||||
	r.ScannedCves[defPacks.def.Title] = vinfo
 | 
			
		||||
	r.ScannedCves[defpacks.def.Title] = vinfo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o SUSE) convertToModel(def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
 
 | 
			
		||||
@@ -26,14 +26,22 @@ import (
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
 | 
			
		||||
	// Import library scanner
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/bundler"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/cargo"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/composer"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/gomod"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/npm"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/pipenv"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/poetry"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/yarn"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/dotnet/nuget"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/golang/binary"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/golang/mod"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/java/jar"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/nodejs/npm"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/nodejs/yarn"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/php/composer"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/pip"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/pipenv"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/poetry"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/ruby/bundler"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/rust/cargo"
 | 
			
		||||
 | 
			
		||||
	// _ "github.com/aquasecurity/fanal/analyzer/language/ruby/gemspec"
 | 
			
		||||
	// _ "github.com/aquasecurity/fanal/analyzer/language/nodejs/pkg"
 | 
			
		||||
	// _ "github.com/aquasecurity/fanal/analyzer/language/python/packaging"
 | 
			
		||||
 | 
			
		||||
	nmap "github.com/Ullaakut/nmap/v2"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,18 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/bundler"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/cargo"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/composer"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/npm"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/pipenv"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/poetry"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/library/yarn"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/dotnet/nuget"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/golang/binary"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/golang/mod"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/java/jar"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/nodejs/npm"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/nodejs/yarn"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/php/composer"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/pip"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/pipenv"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/python/poetry"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/ruby/bundler"
 | 
			
		||||
	_ "github.com/aquasecurity/fanal/analyzer/language/rust/cargo"
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user