nosudo on CentOS and Fetch Changelogs on Amazon, RHEL (#448)
* Use repoquery for no sudo and avoid unintended line feed of yum or rpm. #444 * Change data type of enablerepo in config.toml. string to array * Fetch yum changelogs at once then grep CVE-IDs * Fix changelog parse logic and Update Gopkg
This commit is contained in:
@@ -167,7 +167,7 @@ func (o *debian) checkDependencies() error {
|
||||
}
|
||||
|
||||
func (o *debian) scanPackages() error {
|
||||
installed, upgradable, err := o.scanInstalledPackages()
|
||||
installed, updatable, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages")
|
||||
return err
|
||||
@@ -178,7 +178,7 @@ func (o *debian) scanPackages() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
unsecure, err := o.scanUnsecurePackages(upgradable)
|
||||
unsecure, err := o.scanUnsecurePackages(updatable)
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages")
|
||||
return err
|
||||
@@ -189,7 +189,7 @@ func (o *debian) scanPackages() error {
|
||||
|
||||
func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, error) {
|
||||
installed := models.Packages{}
|
||||
upgradable := models.Packages{}
|
||||
updatable := models.Packages{}
|
||||
|
||||
r := o.exec("dpkg-query -W", noSudo)
|
||||
if !r.isSuccess() {
|
||||
@@ -214,27 +214,27 @@ func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, erro
|
||||
}
|
||||
}
|
||||
|
||||
upgradableNames, err := o.GetUpgradablePackNames()
|
||||
updatableNames, err := o.getUpdatablePackNames()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, name := range upgradableNames {
|
||||
for _, name := range updatableNames {
|
||||
for _, pack := range installed {
|
||||
if pack.Name == name {
|
||||
upgradable[name] = pack
|
||||
updatable[name] = pack
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the candidate versions of upgradable packages
|
||||
err = o.fillCandidateVersion(upgradable)
|
||||
err = o.fillCandidateVersion(updatable)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to fill candidate versions. err: %s", err)
|
||||
}
|
||||
installed.MergeNewVersion(upgradable)
|
||||
installed.MergeNewVersion(updatable)
|
||||
|
||||
return installed, upgradable, nil
|
||||
return installed, updatable, nil
|
||||
}
|
||||
|
||||
var packageLinePattern = regexp.MustCompile(`^([^\t']+)\t(.+)$`)
|
||||
@@ -263,14 +263,14 @@ func (o *debian) aptGetUpdate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *debian) scanUnsecurePackages(upgradable models.Packages) (models.VulnInfos, error) {
|
||||
func (o *debian) scanUnsecurePackages(updatable models.Packages) (models.VulnInfos, error) {
|
||||
o.aptGetUpdate()
|
||||
|
||||
// Setup changelog cache
|
||||
current := cache.Meta{
|
||||
Name: o.getServerInfo().GetServerName(),
|
||||
Distro: o.getServerInfo().Distro,
|
||||
Packs: upgradable,
|
||||
Packs: updatable,
|
||||
}
|
||||
|
||||
o.log.Debugf("Ensure changelog cache: %s", current.Name)
|
||||
@@ -280,7 +280,7 @@ func (o *debian) scanUnsecurePackages(upgradable models.Packages) (models.VulnIn
|
||||
}
|
||||
|
||||
// Collect CVE information of upgradable packages
|
||||
vulnInfos, err := o.scanVulnInfos(upgradable, meta)
|
||||
vulnInfos, err := o.scanVulnInfos(updatable, meta)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan unsecure packages. err: %s", err)
|
||||
}
|
||||
@@ -349,7 +349,7 @@ func (o *debian) fillCandidateVersion(packages models.Packages) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *debian) GetUpgradablePackNames() (packNames []string, err error) {
|
||||
func (o *debian) getUpdatablePackNames() (packNames []string, err error) {
|
||||
cmd := util.PrependProxyEnv("LANGUAGE=en_US.UTF-8 apt-get upgrade --dry-run")
|
||||
r := o.exec(cmd, noSudo)
|
||||
if r.isSuccess(0, 1) {
|
||||
@@ -360,7 +360,7 @@ func (o *debian) GetUpgradablePackNames() (packNames []string, err error) {
|
||||
cmd, r.ExitStatus, r.Stdout, r.Stderr)
|
||||
}
|
||||
|
||||
func (o *debian) parseAptGetUpgrade(stdout string) (upgradableNames []string, err error) {
|
||||
func (o *debian) parseAptGetUpgrade(stdout string) (updatableNames []string, err error) {
|
||||
startRe := regexp.MustCompile(`The following packages will be upgraded:`)
|
||||
stopRe := regexp.MustCompile(`^(\d+) upgraded.*`)
|
||||
startLineFound, stopLineFound := false, false
|
||||
@@ -375,21 +375,21 @@ func (o *debian) parseAptGetUpgrade(stdout string) (upgradableNames []string, er
|
||||
}
|
||||
result := stopRe.FindStringSubmatch(line)
|
||||
if len(result) == 2 {
|
||||
numUpgradablePacks, err := strconv.Atoi(result[1])
|
||||
nUpdatable, err := strconv.Atoi(result[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Failed to scan upgradable packages number. line: %s", line)
|
||||
}
|
||||
if numUpgradablePacks != len(upgradableNames) {
|
||||
if nUpdatable != len(updatableNames) {
|
||||
return nil, fmt.Errorf(
|
||||
"Failed to scan upgradable packages, expected: %s, detected: %d",
|
||||
result[1], len(upgradableNames))
|
||||
result[1], len(updatableNames))
|
||||
}
|
||||
stopLineFound = true
|
||||
o.log.Debugf("Found the stop line. line: %s", line)
|
||||
break
|
||||
}
|
||||
upgradableNames = append(upgradableNames, strings.Fields(line)...)
|
||||
updatableNames = append(updatableNames, strings.Fields(line)...)
|
||||
}
|
||||
if !startLineFound {
|
||||
// no upgrades
|
||||
@@ -410,20 +410,20 @@ type DetectedCveID struct {
|
||||
Confidence models.Confidence
|
||||
}
|
||||
|
||||
func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta) (models.VulnInfos, error) {
|
||||
func (o *debian) scanVulnInfos(updatablePacks models.Packages, meta *cache.Meta) (models.VulnInfos, error) {
|
||||
type response struct {
|
||||
pack *models.Package
|
||||
DetectedCveIDs []DetectedCveID
|
||||
}
|
||||
resChan := make(chan response, len(upgradablePacks))
|
||||
errChan := make(chan error, len(upgradablePacks))
|
||||
reqChan := make(chan models.Package, len(upgradablePacks))
|
||||
resChan := make(chan response, len(updatablePacks))
|
||||
errChan := make(chan error, len(updatablePacks))
|
||||
reqChan := make(chan models.Package, len(updatablePacks))
|
||||
defer close(resChan)
|
||||
defer close(errChan)
|
||||
defer close(reqChan)
|
||||
|
||||
go func() {
|
||||
for _, pack := range upgradablePacks {
|
||||
for _, pack := range updatablePacks {
|
||||
reqChan <- pack
|
||||
}
|
||||
}()
|
||||
@@ -431,7 +431,7 @@ func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta
|
||||
timeout := time.After(30 * 60 * time.Second)
|
||||
concurrency := 10
|
||||
tasks := util.GenWorkers(concurrency)
|
||||
for range upgradablePacks {
|
||||
for range updatablePacks {
|
||||
tasks <- func() {
|
||||
select {
|
||||
case pack := <-reqChan:
|
||||
@@ -459,7 +459,7 @@ func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta
|
||||
// { DetectedCveID{} : [package] }
|
||||
cvePackages := make(map[DetectedCveID][]string)
|
||||
errs := []error{}
|
||||
for i := 0; i < len(upgradablePacks); i++ {
|
||||
for i := 0; i < len(updatablePacks); i++ {
|
||||
select {
|
||||
case response := <-resChan:
|
||||
o.Packages[response.pack.Name] = *response.pack
|
||||
@@ -474,7 +474,7 @@ func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta
|
||||
cvePackages[cve] = packNames
|
||||
}
|
||||
o.log.Infof("(%d/%d) Scanned %s: %s",
|
||||
i+1, len(upgradablePacks), response.pack.Name, cves)
|
||||
i+1, len(updatablePacks), response.pack.Name, cves)
|
||||
case err := <-errChan:
|
||||
errs = append(errs, err)
|
||||
case <-timeout:
|
||||
@@ -500,7 +500,7 @@ func (o *debian) scanVulnInfos(upgradablePacks models.Packages, meta *cache.Meta
|
||||
}
|
||||
|
||||
// Update meta package information of changelog cache to the latest one.
|
||||
meta.Packs = upgradablePacks
|
||||
meta.Packs = updatablePacks
|
||||
if err := cache.DB.RefreshMeta(*meta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -664,7 +664,7 @@ func (o *debian) parseChangelog(changelog, name, ver string, confidence models.C
|
||||
|
||||
clog := models.Changelog{
|
||||
Contents: strings.Join(buf, "\n"),
|
||||
Method: string(confidence.DetectionMethod),
|
||||
Method: confidence.DetectionMethod,
|
||||
}
|
||||
pack := o.Packages[name]
|
||||
pack.Changelog = clog
|
||||
|
||||
Reference in New Issue
Block a user