Add report subcommand, change scan options. Bump up ver #239
This commit is contained in:
@@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/future-architect/vuls/cache"
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/cveapi"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
)
|
||||
@@ -179,12 +178,12 @@ func (o *debian) scanPackages() error {
|
||||
}
|
||||
o.setPackages(packs)
|
||||
|
||||
var unsecurePacks []CvePacksInfo
|
||||
var unsecurePacks []models.VulnInfo
|
||||
if unsecurePacks, err = o.scanUnsecurePackages(packs); err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages")
|
||||
return err
|
||||
}
|
||||
o.setUnsecurePackages(unsecurePacks)
|
||||
o.setVulnInfos(unsecurePacks)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -242,37 +241,41 @@ func (o *debian) checkRequiredPackagesInstalled() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *debian) scanUnsecurePackages(packs []models.PackageInfo) ([]CvePacksInfo, error) {
|
||||
func (o *debian) scanUnsecurePackages(installed []models.PackageInfo) ([]models.VulnInfo, error) {
|
||||
o.log.Infof("apt-get update...")
|
||||
cmd := util.PrependProxyEnv("apt-get update")
|
||||
if r := o.ssh(cmd, sudo); !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
|
||||
upgradablePackNames, err := o.GetUpgradablePackNames()
|
||||
// Convert the name of upgradable packages to PackageInfo struct
|
||||
upgradableNames, err := o.GetUpgradablePackNames()
|
||||
if err != nil {
|
||||
return []CvePacksInfo{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert package name to PackageInfo struct
|
||||
var unsecurePacks []models.PackageInfo
|
||||
for _, name := range upgradablePackNames {
|
||||
for _, pack := range packs {
|
||||
var upgradablePacks []models.PackageInfo
|
||||
for _, name := range upgradableNames {
|
||||
for _, pack := range installed {
|
||||
if pack.Name == name {
|
||||
unsecurePacks = append(unsecurePacks, pack)
|
||||
upgradablePacks = append(upgradablePacks, pack)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
unsecurePacks, err = o.fillCandidateVersion(unsecurePacks)
|
||||
|
||||
// Fill the candidate versions of upgradable packages
|
||||
upgradablePacks, err = o.fillCandidateVersion(upgradablePacks)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to fill candidate versions. err: %s", err)
|
||||
}
|
||||
|
||||
o.Packages.MergeNewVersion(upgradablePacks)
|
||||
|
||||
// Setup changelog cache
|
||||
current := cache.Meta{
|
||||
Name: o.getServerInfo().GetServerName(),
|
||||
Distro: o.getServerInfo().Distro,
|
||||
Packs: unsecurePacks,
|
||||
Packs: upgradablePacks,
|
||||
}
|
||||
o.log.Debugf("Ensure changelog cache: %s", current.Name)
|
||||
if err := o.ensureChangelogCache(current); err != nil {
|
||||
@@ -280,12 +283,12 @@ func (o *debian) scanUnsecurePackages(packs []models.PackageInfo) ([]CvePacksInf
|
||||
}
|
||||
|
||||
// Collect CVE information of upgradable packages
|
||||
cvePacksInfos, err := o.scanPackageCveInfos(unsecurePacks)
|
||||
vulnInfos, err := o.scanVulnInfos(upgradablePacks)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan unsecure packages. err: %s", err)
|
||||
}
|
||||
|
||||
return cvePacksInfos, nil
|
||||
return vulnInfos, nil
|
||||
}
|
||||
|
||||
func (o *debian) ensureChangelogCache(current cache.Meta) error {
|
||||
@@ -327,7 +330,7 @@ func (o *debian) fillCandidateVersion(before models.PackageInfoList) (filled []m
|
||||
cmd := fmt.Sprintf("LANGUAGE=en_US.UTF-8 apt-cache policy %s", strings.Join(names, " "))
|
||||
r := o.ssh(cmd, sudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s.", r)
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
packChangelog := o.splitAptCachePolicy(r.Stdout)
|
||||
for k, v := range packChangelog {
|
||||
@@ -398,26 +401,26 @@ func (o *debian) parseAptGetUpgrade(stdout string) (upgradableNames []string, er
|
||||
return
|
||||
}
|
||||
|
||||
func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePacksList CvePacksList, err error) {
|
||||
func (o *debian) scanVulnInfos(upgradablePacks []models.PackageInfo) (models.VulnInfos, error) {
|
||||
meta := cache.Meta{
|
||||
Name: o.getServerInfo().GetServerName(),
|
||||
Distro: o.getServerInfo().Distro,
|
||||
Packs: unsecurePacks,
|
||||
Packs: upgradablePacks,
|
||||
}
|
||||
|
||||
type strarray []string
|
||||
resChan := make(chan struct {
|
||||
models.PackageInfo
|
||||
strarray
|
||||
}, len(unsecurePacks))
|
||||
errChan := make(chan error, len(unsecurePacks))
|
||||
reqChan := make(chan models.PackageInfo, len(unsecurePacks))
|
||||
}, len(upgradablePacks))
|
||||
errChan := make(chan error, len(upgradablePacks))
|
||||
reqChan := make(chan models.PackageInfo, len(upgradablePacks))
|
||||
defer close(resChan)
|
||||
defer close(errChan)
|
||||
defer close(reqChan)
|
||||
|
||||
go func() {
|
||||
for _, pack := range unsecurePacks {
|
||||
for _, pack := range upgradablePacks {
|
||||
reqChan <- pack
|
||||
}
|
||||
}()
|
||||
@@ -425,7 +428,7 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac
|
||||
timeout := time.After(30 * 60 * time.Second)
|
||||
concurrency := 10
|
||||
tasks := util.GenWorkers(concurrency)
|
||||
for range unsecurePacks {
|
||||
for range upgradablePacks {
|
||||
tasks <- func() {
|
||||
select {
|
||||
case pack := <-reqChan:
|
||||
@@ -458,7 +461,7 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac
|
||||
// { CVE ID: [packageInfo] }
|
||||
cvePackages := make(map[string][]models.PackageInfo)
|
||||
errs := []error{}
|
||||
for i := 0; i < len(unsecurePacks); i++ {
|
||||
for i := 0; i < len(upgradablePacks); i++ {
|
||||
select {
|
||||
case pair := <-resChan:
|
||||
pack := pair.PackageInfo
|
||||
@@ -467,12 +470,11 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac
|
||||
cvePackages[cveID] = appendPackIfMissing(cvePackages[cveID], pack)
|
||||
}
|
||||
o.log.Infof("(%d/%d) Scanned %s-%s : %s",
|
||||
i+1, len(unsecurePacks), pair.Name, pair.PackageInfo.Version, cveIDs)
|
||||
i+1, len(upgradablePacks), pair.Name, pair.PackageInfo.Version, cveIDs)
|
||||
case err := <-errChan:
|
||||
errs = append(errs, err)
|
||||
case <-timeout:
|
||||
//TODO append to errs
|
||||
return nil, fmt.Errorf("Timeout scanPackageCveIDs")
|
||||
errs = append(errs, fmt.Errorf("Timeout scanPackageCveIDs"))
|
||||
}
|
||||
}
|
||||
if 0 < len(errs) {
|
||||
@@ -484,23 +486,14 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac
|
||||
cveIDs = append(cveIDs, k)
|
||||
}
|
||||
o.log.Debugf("%d Cves are found. cves: %v", len(cveIDs), cveIDs)
|
||||
|
||||
o.log.Info("Fetching CVE details...")
|
||||
cveDetails, err := cveapi.CveClient.FetchCveDetails(cveIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o.log.Info("Done")
|
||||
|
||||
for _, detail := range cveDetails {
|
||||
cvePacksList = append(cvePacksList, CvePacksInfo{
|
||||
CveID: detail.CveID,
|
||||
CveDetail: detail,
|
||||
Packs: cvePackages[detail.CveID],
|
||||
// CvssScore: cinfo.CvssScore(conf.Lang),
|
||||
var vinfos models.VulnInfos
|
||||
for k, v := range cvePackages {
|
||||
vinfos = append(vinfos, models.VulnInfo{
|
||||
CveID: k,
|
||||
Packages: v,
|
||||
})
|
||||
}
|
||||
return
|
||||
return vinfos, nil
|
||||
}
|
||||
|
||||
func (o *debian) getChangelogCache(meta cache.Meta, pack models.PackageInfo) string {
|
||||
|
||||
Reference in New Issue
Block a user