From 63dfe8a9525bcc36607929eb16b36095d149805d Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Fri, 6 Jan 2017 13:31:10 +0900 Subject: [PATCH] Support RHEL5 --- README.ja.md | 4 +-- README.md | 4 +-- config/config.go | 11 ++++++ scan/redhat.go | 87 ++++++++++++++++++++---------------------------- 4 files changed, 52 insertions(+), 54 deletions(-) diff --git a/README.ja.md b/README.ja.md index 7a4069ca..85190fd2 100644 --- a/README.ja.md +++ b/README.ja.md @@ -379,7 +379,7 @@ web/app server in the same configuration under the load balancer |:------------|-------------------:| | Ubuntu | 12, 14, 16| | Debian | 7, 8| -| RHEL | 6, 7| +| RHEL | 5, 6, 7| | CentOS | 5, 6, 7| | Amazon Linux| All| | FreeBSD | 10| @@ -613,7 +613,7 @@ Prepareサブコマンドは、Vuls内部で利用する以下のパッケージ | CentOS | 5| yum-changelog | | CentOS | 6, 7| yum-plugin-changelog | | Amazon | All | - | -| RHEL | 6, 7 | - | +| RHEL | 5, 6, 7 | - | | FreeBSD | 10 | - | diff --git a/README.md b/README.md index 48715b4b..e57689d4 100644 --- a/README.md +++ b/README.md @@ -380,7 +380,7 @@ If there is a staging environment with the same configuration as the production |:------------|-------------------:| | Ubuntu | 12, 14, 16| | Debian | 7, 8| -| RHEL | 6, 7| +| RHEL | 5, 6, 7| | CentOS | 5, 6, 7| | Amazon Linux| All| | FreeBSD | 10| @@ -616,7 +616,7 @@ Prepare subcommand installs required packages on each server. | CentOS | 5| yum-changelog | | CentOS | 6, 7| yum-plugin-changelog | | Amazon | All | - | -| RHEL | 6, 7 | - | +| RHEL | 5, 6, 7 | - | | FreeBSD | 10 | - | diff --git a/config/config.go b/config/config.go index f50d861c..3d0322ff 100644 --- a/config/config.go +++ b/config/config.go @@ -20,6 +20,7 @@ package config import ( "fmt" "runtime" + "strconv" "strings" log "github.com/Sirupsen/logrus" @@ -369,6 +370,16 @@ func (l Distro) String() string { return fmt.Sprintf("%s %s", l.Family, l.Release) } +// MajorVersion returns Major version +func (l Distro) MajorVersion() (ver int, err error) { + if 0 < len(l.Release) { + ver, err = strconv.Atoi(strings.Split(l.Release, ".")[0]) + } else { + err = fmt.Errorf("Release is empty") + } + return +} + // IsContainer returns whether this ServerInfo is about container func (s ServerInfo) IsContainer() bool { return 0 < len(s.Container.ContainerID) diff --git a/scan/redhat.go b/scan/redhat.go index 7091b24d..81a6548e 100644 --- a/scan/redhat.go +++ b/scan/redhat.go @@ -21,7 +21,6 @@ import ( "fmt" "regexp" "sort" - "strconv" "strings" "time" @@ -118,11 +117,9 @@ func (o *redhat) checkDependencies() error { return nil case "centos": - var majorVersion int - if 0 < len(o.Distro.Release) { - majorVersion, _ = strconv.Atoi(strings.Split(o.Distro.Release, ".")[0]) - } else { - return fmt.Errorf("Not implemented yet: %s", o.Distro) + majorVersion, err := o.Distro.MajorVersion() + if err != nil { + return fmt.Errorf("Not implemented yet: %s, err: %s", o.Distro, err) } var name = "yum-plugin-changelog" @@ -155,11 +152,9 @@ func (o *redhat) install() error { func (o *redhat) checkRequiredPackagesInstalled() error { if o.Distro.Family == "centos" { - var majorVersion int - if 0 < len(o.Distro.Release) { - majorVersion, _ = strconv.Atoi(strings.Split(o.Distro.Release, ".")[0]) - } else { - msg := fmt.Sprintf("Not implemented yet: %s", o.Distro) + majorVersion, err := o.Distro.MajorVersion() + if err != nil { + msg := fmt.Sprintf("Not implemented yet: %s, err: %s", o.Distro, err) o.log.Errorf(msg) return fmt.Errorf(msg) } @@ -450,17 +445,18 @@ func (o *redhat) getChangelogCVELines(rpm2changelog map[string]*string, packInfo func (o *redhat) parseAllChangelog(allChangelog string) (map[string]*string, error) { var majorVersion int - if 0 < len(o.Distro.Release) && o.Distro.Family == "centos" { - majorVersion, _ = strconv.Atoi(strings.Split(o.Distro.Release, ".")[0]) - } else { - return nil, fmt.Errorf("Not implemented yet: %s", o.getDistro()) + var err error + if o.Distro.Family == "centos" { + majorVersion, err = o.Distro.MajorVersion() + if err != nil { + return nil, fmt.Errorf("Not implemented yet: %s, err: %s", o.Distro, err) + } } orglines := strings.Split(allChangelog, "\n") tmpline := "" var lines []string var prev, now bool - var err error for i := range orglines { if majorVersion == 5 { /* for CentOS5 (yum-util < 1.1.20) */ @@ -578,7 +574,21 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos, } // get advisoryID(RHSA, ALAS) - package name,version - cmd = "yum --color=never updateinfo list available --security" + major, err := (o.Distro.MajorVersion()) + if err != nil { + return nil, fmt.Errorf("Not implemented yet: %s, err: %s", o.Distro, err) + } + + switch major { + case 5: + { + cmd = "yum --color=never list-security --security" + } + case 6, 7: + { + cmd = "yum --color=never updateinfo list available --security" + } + } r = o.ssh(util.PrependProxyEnv(cmd), o.sudo()) if !r.isSuccess() { return nil, fmt.Errorf("Failed to SSH: %s", r) @@ -618,7 +628,16 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos, } // get advisoryID(RHSA, ALAS) - CVE IDs - cmd = "yum --color=never updateinfo --security update" + switch major { + case 5: + { + cmd = "yum --color=never info-sec" + } + case 6, 7: + { + cmd = "yum --color=never updateinfo --security update" + } + } r = o.ssh(util.PrependProxyEnv(cmd), o.sudo()) if !r.isSuccess() { return nil, fmt.Errorf("Failed to SSH: %s", r) @@ -793,38 +812,6 @@ func (o *redhat) isRpmPackageNameLine(line string) (bool, error) { return true, nil } -// see test case -func (o *redhat) parseYumUpdateinfoHeaderCentOS(line string) (packs []models.PackageInfo, err error) { - pkgs := strings.Split(strings.TrimSpace(line), ",") - for _, pkg := range pkgs { - packs = append(packs, models.PackageInfo{}) - s := strings.Split(pkg, "-") - if len(s) == 3 { - packs[len(packs)-1].Name = s[0] - packs[len(packs)-1].Version = s[1] - packs[len(packs)-1].Release = s[2] - } else { - return packs, fmt.Errorf("CentOS: Unknown Header format: %s", line) - } - } - return -} - -var yumHeaderPattern = regexp.MustCompile(`(ALAS-.+): (.+) priority package update for (.+)$`) - -func (o *redhat) parseYumUpdateinfoHeaderAmazon(line string) (a models.DistroAdvisory, names []string, err error) { - result := yumHeaderPattern.FindStringSubmatch(line) - if len(result) == 4 { - a.AdvisoryID = result[1] - a.Severity = result[2] - spaceSeparatedPacknames := result[3] - names = strings.Fields(spaceSeparatedPacknames) - return - } - err = fmt.Errorf("Amazon Linux: Unknown Header Format. %s", line) - return -} - var yumCveIDPattern = regexp.MustCompile(`(CVE-\d{4}-\d{4,})`) func (o *redhat) parseYumUpdateinfoLineToGetCveIDs(line string) []string {