Unify the models of NVD, JVN, OVAL
This commit is contained in:
		@@ -7,7 +7,6 @@ import (
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	ver "github.com/knqyf263/go-deb-version"
 | 
			
		||||
	cve "github.com/kotakanbe/go-cve-dictionary/models"
 | 
			
		||||
	ovalconf "github.com/kotakanbe/goval-dictionary/config"
 | 
			
		||||
	db "github.com/kotakanbe/goval-dictionary/db"
 | 
			
		||||
	ovalmodels "github.com/kotakanbe/goval-dictionary/models"
 | 
			
		||||
@@ -62,54 +61,78 @@ func (o Debian) FillCveInfoFromOvalDB(r *models.ScanResult) (*models.ScanResult,
 | 
			
		||||
func (o Debian) fillOvalInfo(r *models.ScanResult, definition *ovalmodels.Definition) *models.ScanResult {
 | 
			
		||||
	// Update ScannedCves by OVAL info
 | 
			
		||||
	found := false
 | 
			
		||||
	cves := []models.VulnInfo{}
 | 
			
		||||
	for _, cve := range r.ScannedCves {
 | 
			
		||||
		if cve.CveID == definition.Debian.CveID {
 | 
			
		||||
	updatedCves := []models.VulnInfo{}
 | 
			
		||||
 | 
			
		||||
	// Update scanned confidence to ovalmatch
 | 
			
		||||
	for _, scanned := range r.ScannedCves {
 | 
			
		||||
		if scanned.CveID == definition.Debian.CveID {
 | 
			
		||||
			found = true
 | 
			
		||||
			if cve.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
				cve.Confidence = models.OvalMatch
 | 
			
		||||
			if scanned.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
				scanned.Confidence = models.OvalMatch
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		cves = append(cves, cve)
 | 
			
		||||
		updatedCves = append(updatedCves, scanned)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packageInfoList := getPackageInfoList(r, definition)
 | 
			
		||||
	vuln := models.VulnInfo{
 | 
			
		||||
		CveID:      definition.Debian.CveID,
 | 
			
		||||
		Confidence: models.OvalMatch,
 | 
			
		||||
		Packages:   packageInfoList,
 | 
			
		||||
		Packages:   getPackageInfoList(r, definition),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !found {
 | 
			
		||||
		cves = append(cves, vuln)
 | 
			
		||||
		util.Log.Debugf("%s is newly detected by OVAL", vuln.CveID)
 | 
			
		||||
		updatedCves = append(updatedCves, vuln)
 | 
			
		||||
	}
 | 
			
		||||
	r.ScannedCves = cves
 | 
			
		||||
	r.ScannedCves = updatedCves
 | 
			
		||||
 | 
			
		||||
	// Update KnownCves by OVAL info
 | 
			
		||||
	cveInfo, ok := r.KnownCves.Get(definition.Debian.CveID)
 | 
			
		||||
	ovalContent := *o.convertToModel(definition)
 | 
			
		||||
	ovalContent.Type = models.CveContentType(r.Family)
 | 
			
		||||
	cInfo, ok := r.KnownCves.Get(definition.Debian.CveID)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		cveInfo.CveDetail = cve.CveDetail{
 | 
			
		||||
			CveID: definition.Debian.CveID,
 | 
			
		||||
		}
 | 
			
		||||
		cveInfo.VulnInfo = vuln
 | 
			
		||||
		cInfo.VulnInfo = vuln
 | 
			
		||||
		cInfo.CveContents = []models.CveContent{ovalContent}
 | 
			
		||||
	}
 | 
			
		||||
	cveInfo.OvalDetail = *definition
 | 
			
		||||
	if cveInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
		cveInfo.Confidence = models.OvalMatch
 | 
			
		||||
	if !cInfo.Update(ovalContent) {
 | 
			
		||||
		cInfo.Insert(ovalContent)
 | 
			
		||||
	}
 | 
			
		||||
	r.KnownCves.Upsert(cveInfo)
 | 
			
		||||
	if cInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
		cInfo.Confidence = models.OvalMatch
 | 
			
		||||
	}
 | 
			
		||||
	r.KnownCves.Upsert(cInfo)
 | 
			
		||||
 | 
			
		||||
	// Update UnknownCves by OVAL info
 | 
			
		||||
	cveInfo, ok = r.UnknownCves.Get(definition.Debian.CveID)
 | 
			
		||||
	cInfo, ok = r.UnknownCves.Get(definition.Debian.CveID)
 | 
			
		||||
	if ok {
 | 
			
		||||
		cveInfo.OvalDetail = *definition
 | 
			
		||||
		if cveInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
			cveInfo.Confidence = models.OvalMatch
 | 
			
		||||
		}
 | 
			
		||||
		r.UnknownCves.Delete(definition.Debian.CveID)
 | 
			
		||||
		r.KnownCves.Upsert(cveInfo)
 | 
			
		||||
 | 
			
		||||
		// Insert new CveInfo
 | 
			
		||||
		if !cInfo.Update(ovalContent) {
 | 
			
		||||
			cInfo.Insert(ovalContent)
 | 
			
		||||
		}
 | 
			
		||||
		if cInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
			cInfo.Confidence = models.OvalMatch
 | 
			
		||||
		}
 | 
			
		||||
		r.KnownCves.Upsert(cInfo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Debian) convertToModel(def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
	var refs []models.Reference
 | 
			
		||||
	for _, r := range def.References {
 | 
			
		||||
		refs = append(refs, models.Reference{
 | 
			
		||||
			Link:   r.RefURL,
 | 
			
		||||
			Source: r.Source,
 | 
			
		||||
			RefID:  r.RefID,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return &models.CveContent{
 | 
			
		||||
		CveID:      def.Debian.CveID,
 | 
			
		||||
		Title:      def.Title,
 | 
			
		||||
		Summary:    def.Description,
 | 
			
		||||
		References: refs,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ func getPackageInfoList(r *models.ScanResult, d *ovalmodels.Definition) models.P
 | 
			
		||||
	for _, pack := range d.AffectedPacks {
 | 
			
		||||
		for _, p := range r.Packages {
 | 
			
		||||
			if pack.Name == p.Name {
 | 
			
		||||
				p.Changelog = models.Changelog{}
 | 
			
		||||
				packageInfoList = append(packageInfoList, p)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										102
									
								
								oval/redhat.go
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								oval/redhat.go
									
									
									
									
									
								
							@@ -7,7 +7,6 @@ import (
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	ver "github.com/knqyf263/go-deb-version"
 | 
			
		||||
	cve "github.com/kotakanbe/go-cve-dictionary/models"
 | 
			
		||||
	ovalconf "github.com/kotakanbe/goval-dictionary/config"
 | 
			
		||||
	db "github.com/kotakanbe/goval-dictionary/db"
 | 
			
		||||
	ovalmodels "github.com/kotakanbe/goval-dictionary/models"
 | 
			
		||||
@@ -56,69 +55,108 @@ func (o Redhat) FillCveInfoFromOvalDB(r *models.ScanResult) (*models.ScanResult,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Redhat) fillOvalInfo(r *models.ScanResult, definition *ovalmodels.Definition) *models.ScanResult {
 | 
			
		||||
	found := make(map[string]bool)
 | 
			
		||||
	vulnInfos := make(map[string]models.VulnInfo)
 | 
			
		||||
	packageInfoList := getPackageInfoList(r, definition)
 | 
			
		||||
	cveIDSet := make(map[string]bool)
 | 
			
		||||
	cveID2VulnInfo := make(map[string]models.VulnInfo)
 | 
			
		||||
	for _, cve := range definition.Advisory.Cves {
 | 
			
		||||
		found[cve.CveID] = false
 | 
			
		||||
		vulnInfos[cve.CveID] = models.VulnInfo{
 | 
			
		||||
		cveIDSet[cve.CveID] = false
 | 
			
		||||
		cveID2VulnInfo[cve.CveID] = models.VulnInfo{
 | 
			
		||||
			CveID:      cve.CveID,
 | 
			
		||||
			Confidence: models.OvalMatch,
 | 
			
		||||
			Packages:   packageInfoList,
 | 
			
		||||
			Packages:   getPackageInfoList(r, definition),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update ScannedCves by OVAL info
 | 
			
		||||
	cves := []models.VulnInfo{}
 | 
			
		||||
	for _, scannedCve := range r.ScannedCves {
 | 
			
		||||
	updatedCves := []models.VulnInfo{}
 | 
			
		||||
	for _, scanned := range r.ScannedCves {
 | 
			
		||||
		// Update scanned confidence to ovalmatch
 | 
			
		||||
		for _, c := range definition.Advisory.Cves {
 | 
			
		||||
			if scannedCve.CveID == c.CveID {
 | 
			
		||||
				found[c.CveID] = true
 | 
			
		||||
				if scannedCve.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
					scannedCve.Confidence = models.OvalMatch
 | 
			
		||||
			if scanned.CveID == c.CveID {
 | 
			
		||||
				cveIDSet[c.CveID] = true
 | 
			
		||||
				if scanned.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
					scanned.Confidence = models.OvalMatch
 | 
			
		||||
				}
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		cves = append(cves, scannedCve)
 | 
			
		||||
		updatedCves = append(updatedCves, scanned)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for cveID, found := range found {
 | 
			
		||||
	for cveID, found := range cveIDSet {
 | 
			
		||||
		if !found {
 | 
			
		||||
			cves = append(cves, vulnInfos[cveID])
 | 
			
		||||
			util.Log.Debugf("%s is newly detected by OVAL", cveID)
 | 
			
		||||
			updatedCves = append(updatedCves, cveID2VulnInfo[cveID])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	r.ScannedCves = cves
 | 
			
		||||
	r.ScannedCves = updatedCves
 | 
			
		||||
 | 
			
		||||
	// Update KnownCves by OVAL info
 | 
			
		||||
	for _, c := range definition.Advisory.Cves {
 | 
			
		||||
		cveInfo, ok := r.KnownCves.Get(c.CveID)
 | 
			
		||||
		ovalContent := *o.convertToModel(c.CveID, definition)
 | 
			
		||||
		cInfo, ok := r.KnownCves.Get(c.CveID)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			cveInfo.CveDetail = cve.CveDetail{
 | 
			
		||||
				CveID: c.CveID,
 | 
			
		||||
			}
 | 
			
		||||
			cveInfo.VulnInfo = vulnInfos[c.CveID]
 | 
			
		||||
			cInfo.VulnInfo = cveID2VulnInfo[c.CveID]
 | 
			
		||||
			cInfo.CveContents = []models.CveContent{ovalContent}
 | 
			
		||||
		}
 | 
			
		||||
		cveInfo.OvalDetail = *definition
 | 
			
		||||
		if cveInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
			cveInfo.Confidence = models.OvalMatch
 | 
			
		||||
		if !cInfo.Update(ovalContent) {
 | 
			
		||||
			cInfo.Insert(ovalContent)
 | 
			
		||||
		}
 | 
			
		||||
		r.KnownCves.Upsert(cveInfo)
 | 
			
		||||
		if cInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
			cInfo.Confidence = models.OvalMatch
 | 
			
		||||
		}
 | 
			
		||||
		r.KnownCves.Upsert(cInfo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update UnknownCves by OVAL info
 | 
			
		||||
	for _, c := range definition.Advisory.Cves {
 | 
			
		||||
		cveInfo, ok := r.UnknownCves.Get(c.CveID)
 | 
			
		||||
		cInfo, ok := r.UnknownCves.Get(c.CveID)
 | 
			
		||||
		if ok {
 | 
			
		||||
			cveInfo.OvalDetail = *definition
 | 
			
		||||
			if cveInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
				cveInfo.Confidence = models.OvalMatch
 | 
			
		||||
			}
 | 
			
		||||
			r.UnknownCves.Delete(c.CveID)
 | 
			
		||||
			r.KnownCves.Upsert(cveInfo)
 | 
			
		||||
 | 
			
		||||
			// Insert new CveInfo
 | 
			
		||||
			ovalContent := *o.convertToModel(c.CveID, definition)
 | 
			
		||||
			if !cInfo.Update(ovalContent) {
 | 
			
		||||
				cInfo.Insert(ovalContent)
 | 
			
		||||
			}
 | 
			
		||||
			if cInfo.VulnInfo.Confidence.Score < models.OvalMatch.Score {
 | 
			
		||||
				cInfo.Confidence = models.OvalMatch
 | 
			
		||||
			}
 | 
			
		||||
			r.KnownCves.Upsert(cInfo)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Redhat) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
 | 
			
		||||
	for _, cve := range def.Advisory.Cves {
 | 
			
		||||
		if cve.CveID != cveID {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		var refs []models.Reference
 | 
			
		||||
		//TODO RHSAのリンクを入れる
 | 
			
		||||
		for _, r := range def.References {
 | 
			
		||||
			refs = append(refs, models.Reference{
 | 
			
		||||
				Link:   r.RefURL,
 | 
			
		||||
				Source: r.Source,
 | 
			
		||||
				RefID:  r.RefID,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//  util.ParseCvss2()
 | 
			
		||||
 | 
			
		||||
		return &models.CveContent{
 | 
			
		||||
			Type:     models.RedHat,
 | 
			
		||||
			CveID:    cve.CveID,
 | 
			
		||||
			Title:    def.Title,
 | 
			
		||||
			Summary:  def.Description,
 | 
			
		||||
			Severity: def.Advisory.Severity,
 | 
			
		||||
			//  V2Score:    v2Score,   // TODO divide into score and vector
 | 
			
		||||
			Cvss2Vector: cve.Cvss2, // TODO divide into score and vector
 | 
			
		||||
			Cvss3Vector: cve.Cvss3, // TODO divide into score and vector
 | 
			
		||||
			References:  refs,
 | 
			
		||||
			CweID:       cve.Cwe,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user