Change ScanResult.Packages structure to Map
This commit is contained in:
		@@ -181,7 +181,10 @@ func (o *debian) scanPackages() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) scanInstalledPackages() (installed models.Packages, upgradable models.Packages, err error) {
 | 
			
		||||
func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, error) {
 | 
			
		||||
	installed := models.Packages{}
 | 
			
		||||
	upgradable := models.Packages{}
 | 
			
		||||
 | 
			
		||||
	r := o.exec("dpkg-query -W", noSudo)
 | 
			
		||||
	if !r.isSuccess() {
 | 
			
		||||
		return nil, nil, fmt.Errorf("Failed to SSH: %s", r)
 | 
			
		||||
@@ -198,10 +201,10 @@ func (o *debian) scanInstalledPackages() (installed models.Packages, upgradable
 | 
			
		||||
				return nil, nil, fmt.Errorf(
 | 
			
		||||
					"Debian: Failed to parse package line: %s", line)
 | 
			
		||||
			}
 | 
			
		||||
			installed = append(installed, models.Package{
 | 
			
		||||
			installed[name] = models.Package{
 | 
			
		||||
				Name:    name,
 | 
			
		||||
				Version: version,
 | 
			
		||||
			})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -212,20 +215,20 @@ func (o *debian) scanInstalledPackages() (installed models.Packages, upgradable
 | 
			
		||||
	for _, name := range upgradableNames {
 | 
			
		||||
		for _, pack := range installed {
 | 
			
		||||
			if pack.Name == name {
 | 
			
		||||
				upgradable = append(upgradable, pack)
 | 
			
		||||
				upgradable[name] = pack
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fill the candidate versions of upgradable packages
 | 
			
		||||
	upgradable, err = o.fillCandidateVersion(upgradable)
 | 
			
		||||
	err = o.fillCandidateVersion(upgradable)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, fmt.Errorf("Failed to fill candidate versions. err: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	installed.MergeNewVersion(upgradable)
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
	return installed, upgradable, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var packageLinePattern = regexp.MustCompile(`^([^\t']+)\t(.+)$`)
 | 
			
		||||
@@ -254,7 +257,7 @@ func (o *debian) aptGetUpdate() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) scanUnsecurePackages(upgradable []models.Package) ([]models.VulnInfo, error) {
 | 
			
		||||
func (o *debian) scanUnsecurePackages(upgradable models.Packages) ([]models.VulnInfo, error) {
 | 
			
		||||
 | 
			
		||||
	o.aptGetUpdate()
 | 
			
		||||
 | 
			
		||||
@@ -315,28 +318,28 @@ func (o *debian) ensureChangelogCache(current cache.Meta) (*cache.Meta, error) {
 | 
			
		||||
	return &cached, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) fillCandidateVersion(before models.Packages) (filled []models.Package, err error) {
 | 
			
		||||
func (o *debian) fillCandidateVersion(packages models.Packages) (err error) {
 | 
			
		||||
	names := []string{}
 | 
			
		||||
	for _, p := range before {
 | 
			
		||||
		names = append(names, p.Name)
 | 
			
		||||
	for name := range packages {
 | 
			
		||||
		names = append(names, name)
 | 
			
		||||
	}
 | 
			
		||||
	cmd := fmt.Sprintf("LANGUAGE=en_US.UTF-8 apt-cache policy %s", strings.Join(names, " "))
 | 
			
		||||
	r := o.exec(cmd, noSudo)
 | 
			
		||||
	if !r.isSuccess() {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to SSH: %s", r)
 | 
			
		||||
		return fmt.Errorf("Failed to SSH: %s", r)
 | 
			
		||||
	}
 | 
			
		||||
	packChangelog := o.splitAptCachePolicy(r.Stdout)
 | 
			
		||||
	for k, v := range packChangelog {
 | 
			
		||||
		ver, err := o.parseAptCachePolicy(v, k)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("Failed to parse %s", err)
 | 
			
		||||
			return fmt.Errorf("Failed to parse %s", err)
 | 
			
		||||
		}
 | 
			
		||||
		p, found := before.FindByName(k)
 | 
			
		||||
		if !found {
 | 
			
		||||
			return nil, fmt.Errorf("Not found: %s", k)
 | 
			
		||||
		pack, ok := packages[k]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return fmt.Errorf("Not found: %s", k)
 | 
			
		||||
		}
 | 
			
		||||
		p.NewVersion = ver.Candidate
 | 
			
		||||
		filled = append(filled, p)
 | 
			
		||||
		pack.NewVersion = ver.Candidate
 | 
			
		||||
		packages[k] = pack
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -394,7 +397,7 @@ func (o *debian) parseAptGetUpgrade(stdout string) (upgradableNames []string, er
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) scanVulnInfos(upgradablePacks []models.Package, meta *cache.Meta) (models.VulnInfos, error) {
 | 
			
		||||
func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta) (models.VulnInfos, error) {
 | 
			
		||||
	resChan := make(chan struct {
 | 
			
		||||
		models.Package
 | 
			
		||||
		DetectedCveIDs
 | 
			
		||||
@@ -412,7 +415,7 @@ func (o *debian) scanVulnInfos(upgradablePacks []models.Package, meta *cache.Met
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	timeout := time.After(30 * 60 * time.Second)
 | 
			
		||||
	concurrency := 10
 | 
			
		||||
	concurrency := 1
 | 
			
		||||
	tasks := util.GenWorkers(concurrency)
 | 
			
		||||
	for range upgradablePacks {
 | 
			
		||||
		tasks <- func() {
 | 
			
		||||
@@ -446,18 +449,23 @@ func (o *debian) scanVulnInfos(upgradablePacks []models.Package, meta *cache.Met
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// { DetectedCveID{} : [package] }
 | 
			
		||||
	cvePackages := make(map[DetectedCveID][]models.Package)
 | 
			
		||||
	cvePackages := make(map[DetectedCveID]models.Packages)
 | 
			
		||||
	errs := []error{}
 | 
			
		||||
	for i := 0; i < len(upgradablePacks); i++ {
 | 
			
		||||
		select {
 | 
			
		||||
		case pair := <-resChan:
 | 
			
		||||
			pack := pair.Package
 | 
			
		||||
			cveIDs := pair.DetectedCveIDs
 | 
			
		||||
			for _, cveID := range cveIDs {
 | 
			
		||||
				cvePackages[cveID] = appendPackIfMissing(cvePackages[cveID], pack)
 | 
			
		||||
			cves := pair.DetectedCveIDs
 | 
			
		||||
			for _, cve := range cves {
 | 
			
		||||
				packs, ok := cvePackages[cve]
 | 
			
		||||
				if ok {
 | 
			
		||||
					packs[cve.CveID] = pair.Package
 | 
			
		||||
				} else {
 | 
			
		||||
					packs = models.Packages{}
 | 
			
		||||
				}
 | 
			
		||||
				cvePackages[cve] = packs
 | 
			
		||||
			}
 | 
			
		||||
			o.log.Infof("(%d/%d) Scanned %s-%s : %s",
 | 
			
		||||
				i+1, len(upgradablePacks), pair.Name, pair.Package.Version, cveIDs)
 | 
			
		||||
				i+1, len(upgradablePacks), pair.Name, pair.Package.Version, cves)
 | 
			
		||||
		case err := <-errChan:
 | 
			
		||||
			errs = append(errs, err)
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
@@ -492,7 +500,7 @@ func (o *debian) scanVulnInfos(upgradablePacks []models.Package, meta *cache.Met
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *debian) getChangelogCache(meta *cache.Meta, pack models.Package) string {
 | 
			
		||||
	cachedPack, found := meta.FindPack(pack.Name)
 | 
			
		||||
	cachedPack, found := meta.Packs[pack.Name]
 | 
			
		||||
	if !found {
 | 
			
		||||
		o.log.Debugf("Not found: %s", pack.Name)
 | 
			
		||||
		return ""
 | 
			
		||||
@@ -602,14 +610,12 @@ func (o *debian) getCveIDsFromChangelog(
 | 
			
		||||
	// Only logging the error.
 | 
			
		||||
	o.log.Error(err)
 | 
			
		||||
 | 
			
		||||
	for i, p := range o.Packages {
 | 
			
		||||
		if p.Name == name {
 | 
			
		||||
			o.Packages[i].Changelog = models.Changelog{
 | 
			
		||||
				Contents: "",
 | 
			
		||||
				Method:   models.FailedToFindVersionInChangelog,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	pack := o.Packages[name]
 | 
			
		||||
	pack.Changelog = models.Changelog{
 | 
			
		||||
		Contents: "",
 | 
			
		||||
		Method:   models.FailedToFindVersionInChangelog,
 | 
			
		||||
	}
 | 
			
		||||
	o.Packages[name] = pack
 | 
			
		||||
 | 
			
		||||
	// If the version is not in changelog, return entire changelog to put into cache
 | 
			
		||||
	return []DetectedCveID{}, models.Changelog{
 | 
			
		||||
@@ -666,11 +672,9 @@ func (o *debian) parseChangelog(changelog, name, ver string, confidence models.C
 | 
			
		||||
		Method:   string(confidence.DetectionMethod),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, p := range o.Packages {
 | 
			
		||||
		if p.Name == name {
 | 
			
		||||
			o.Packages[i].Changelog = clog
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	pack := o.Packages[name]
 | 
			
		||||
	pack.Changelog = clog
 | 
			
		||||
	o.Packages[name] = pack
 | 
			
		||||
 | 
			
		||||
	cves := []DetectedCveID{}
 | 
			
		||||
	for _, id := range cveIDs {
 | 
			
		||||
@@ -729,14 +733,3 @@ func (o *debian) parseAptCachePolicy(stdout, name string) (packCandidateVer, err
 | 
			
		||||
	}
 | 
			
		||||
	return ver, fmt.Errorf("Unknown Format: %s", stdout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func appendPackIfMissing(slice []models.Package, s models.Package) []models.Package {
 | 
			
		||||
	for _, ele := range slice {
 | 
			
		||||
		if ele.Name == s.Name &&
 | 
			
		||||
			ele.Version == s.Version &&
 | 
			
		||||
			ele.Release == s.Release {
 | 
			
		||||
			return slice
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return append(slice, s)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user