From 0bf12412d6488c305ea4887c88bf956d40fe3c0d Mon Sep 17 00:00:00 2001 From: Norihiro NAKAOKA Date: Thu, 8 Jul 2021 05:39:48 +0900 Subject: [PATCH] fix(rocky): fix Scan in Rocky Linux (#1266) * fix(rocky): fix OVAL scan in Rocky Linux * chore: add FreeBSD13 EOL, fix #1245 * chore(rocky): add Rocky Linux EOL tests * feat(rocky): implement with reference to CentOS * feat(raspbian): add Raspbian to Server mode * feat(rocky): support gost scan * fix(rocky): rocky support lessThan * chore: update doc and comment --- README.md | 8 +- config/config.go | 2 +- config/os.go | 5 + config/os_test.go | 33 +++ constant/constant.go | 2 +- gost/gost.go | 2 +- models/cvecontents.go | 2 +- models/scanresults_test.go | 5 + oval/redhat.go | 22 +- oval/util.go | 27 +-- oval/util_test.go | 479 ++++++++++++++++++++++++++++++++++++- scanner/centos.go | 4 +- scanner/redhatbase.go | 10 +- scanner/rhel.go | 2 +- scanner/rocky.go | 6 +- scanner/serverapi.go | 4 +- scanner/utils.go | 2 +- 17 files changed, 577 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index f0131840..5da51494 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Vuls is a tool created to solve the problems listed above. It has the following [Supports major Linux/FreeBSD](https://vuls.io/docs/en/supported-os.html) -- Alpine, Amazon Linux, CentOS, Debian, Oracle Linux, Raspbian, RHEL, SUSE Enterprise Linux, and Ubuntu +- Alpine, Amazon Linux, CentOS, Rocky Linux, Debian, Oracle Linux, Raspbian, RHEL, SUSE Enterprise Linux, and Ubuntu - FreeBSD - Cloud, on-premise, Running Docker Container @@ -100,15 +100,15 @@ Vuls is a tool created to solve the problems listed above. It has the following - Scan without root privilege, no dependencies - Almost no load on the scan target server -- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu) +- Offline mode scan with no internet access. (CentOS, Rocky Linux, Debian, Oracle Linux, Red Hat, and Ubuntu) [Fast Root Scan](https://vuls.io/docs/en/architecture-fast-root-scan.html) - Scan with root privilege - Almost no load on the scan target server -- Detect processes affected by update using yum-ps (Amazon Linux, CentOS, Oracle Linux, and RedHat) +- Detect processes affected by update using yum-ps (Amazon Linux, CentOS, Rocky Linux, Oracle Linux, and RedHat) - Detect processes which updated before but not restarting yet using checkrestart of debian-goodies (Debian and Ubuntu) -- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu) +- Offline mode scan with no internet access. (CentOS, Rocky Linux, Debian, Oracle Linux, Red Hat, and Ubuntu) ### [Remote, Local scan mode, Server mode](https://vuls.io/docs/en/architecture-remote-local.html) diff --git a/config/config.go b/config/config.go index 2edc9a14..7907622b 100644 --- a/config/config.go +++ b/config/config.go @@ -230,7 +230,7 @@ type ServerInfo struct { GitHubRepos map[string]GitHubConf `toml:"githubs" json:"githubs,omitempty"` // key: owner/repo UUIDs map[string]string `toml:"uuids,omitempty" json:"uuids,omitempty"` Memo string `toml:"memo,omitempty" json:"memo,omitempty"` - Enablerepo []string `toml:"enablerepo,omitempty" json:"enablerepo,omitempty"` // For CentOS, RHEL, Amazon + Enablerepo []string `toml:"enablerepo,omitempty" json:"enablerepo,omitempty"` // For CentOS, Rocky, RHEL, Amazon Optional map[string]interface{} `toml:"optional,omitempty" json:"optional,omitempty"` // Optional key-value set that will be outputted to JSON Lockfiles []string `toml:"lockfiles,omitempty" json:"lockfiles,omitempty"` // ie) path/to/package-lock.json FindLock bool `toml:"findLock,omitempty" json:"findLock,omitempty"` diff --git a/config/os.go b/config/os.go index fe0d4796..25d3dc75 100644 --- a/config/os.go +++ b/config/os.go @@ -75,6 +75,10 @@ func GetEOL(family, release string) (eol EOL, found bool) { "7": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)}, "8": {StandardSupportUntil: time.Date(2021, 12, 31, 23, 59, 59, 0, time.UTC)}, }[major(release)] + case constant.Rocky: + eol, found = map[string]EOL{ + "8": {StandardSupportUntil: time.Date(2029, 5, 31, 23, 59, 59, 0, time.UTC)}, + }[major(release)] case constant.Oracle: eol, found = map[string]EOL{ // Source: @@ -179,6 +183,7 @@ func GetEOL(family, release string) (eol EOL, found bool) { "10": {Ended: true}, "11": {StandardSupportUntil: time.Date(2021, 9, 30, 23, 59, 59, 0, time.UTC)}, "12": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)}, + "13": {StandardSupportUntil: time.Date(2026, 1, 31, 23, 59, 59, 0, time.UTC)}, }[major(release)] } return diff --git a/config/os_test.go b/config/os_test.go index a27d3b2f..fd48ef84 100644 --- a/config/os_test.go +++ b/config/os_test.go @@ -111,6 +111,31 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) { extEnded: false, found: false, }, + // Rocky + { + name: "Rocky Linux 8 supported", + fields: fields{family: Rocky, release: "8"}, + now: time.Date(2021, 7, 2, 23, 59, 59, 0, time.UTC), + stdEnded: false, + extEnded: false, + found: true, + }, + { + name: "Rocky Linux 8 EOL", + fields: fields{family: Rocky, release: "8"}, + now: time.Date(2026, 2, 1, 0, 0, 0, 0, time.UTC), + stdEnded: false, + extEnded: false, + found: true, + }, + { + name: "Rocky Linux 9 Not Found", + fields: fields{family: Rocky, release: "9"}, + now: time.Date(2021, 7, 2, 23, 59, 59, 0, time.UTC), + stdEnded: false, + extEnded: false, + found: false, + }, //Oracle { name: "Oracle Linux 7 supported", @@ -308,6 +333,14 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) { extEnded: false, found: true, }, + { + name: "freebsd 13 supported", + fields: fields{family: FreeBSD, release: "13"}, + now: time.Date(2021, 7, 2, 23, 59, 59, 0, time.UTC), + stdEnded: false, + extEnded: false, + found: true, + }, { name: "freebsd 10 eol", fields: fields{family: FreeBSD, release: "10"}, diff --git a/constant/constant.go b/constant/constant.go index e0d2e1f0..6a27cffc 100644 --- a/constant/constant.go +++ b/constant/constant.go @@ -18,7 +18,7 @@ const ( CentOS = "centos" // Rocky is - Rocky = "Rocky" + Rocky = "rocky" // Fedora is // Fedora = "fedora" diff --git a/gost/gost.go b/gost/gost.go index b9093340..3b251505 100644 --- a/gost/gost.go +++ b/gost/gost.go @@ -65,7 +65,7 @@ func NewClient(cnf config.GostConf, family string) (Client, error) { driver := DBDriver{DB: db, Cnf: &cnf} switch family { - case constant.RedHat, constant.CentOS: + case constant.RedHat, constant.CentOS, constant.Rocky: return RedHat{Base{DBDriver: driver}}, nil case constant.Debian, constant.Raspbian: return Debian{Base{DBDriver: driver}}, nil diff --git a/models/cvecontents.go b/models/cvecontents.go index 983aa8b3..cdf1ae1f 100644 --- a/models/cvecontents.go +++ b/models/cvecontents.go @@ -233,7 +233,7 @@ func NewCveContentType(name string) CveContentType { return Nvd case "jvn": return Jvn - case "redhat", "centos": + case "redhat", "centos", "rocky": return RedHat case "oracle": return Oracle diff --git a/models/scanresults_test.go b/models/scanresults_test.go index e761e2c3..c08a1923 100644 --- a/models/scanresults_test.go +++ b/models/scanresults_test.go @@ -56,6 +56,11 @@ func TestIsDisplayUpdatableNum(t *testing.T) { family: constant.CentOS, expected: true, }, + { + mode: []byte{config.Fast}, + family: constant.Rocky, + expected: true, + }, { mode: []byte{config.Fast}, family: constant.Amazon, diff --git a/oval/redhat.go b/oval/redhat.go index 92c7a301..a5c137fc 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -14,7 +14,7 @@ import ( ovalmodels "github.com/kotakanbe/goval-dictionary/models" ) -// RedHatBase is the base struct for RedHat and CentOS +// RedHatBase is the base struct for RedHat, CentOS and Rocky type RedHatBase struct { Base } @@ -155,7 +155,7 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int) func (o RedHatBase) convertToDistroAdvisory(def *ovalmodels.Definition) *models.DistroAdvisory { advisoryID := def.Title switch o.family { - case constant.RedHat, constant.CentOS, constant.Oracle: + case constant.RedHat, constant.CentOS, constant.Rocky, constant.Oracle: if def.Title != "" { ss := strings.Fields(def.Title) advisoryID = strings.TrimSuffix(ss[0], ":") @@ -322,3 +322,21 @@ func NewAmazon(cnf config.VulnDictInterface) Amazon { }, } } + +// Rocky is the interface for RedhatBase OVAL +type Rocky struct { + // Base + RedHatBase +} + +// NewRocky creates OVAL client for Rocky Linux +func NewRocky(cnf config.VulnDictInterface) Rocky { + return Rocky{ + RedHatBase{ + Base{ + family: constant.Rocky, + Cnf: cnf, + }, + }, + } +} diff --git a/oval/util.go b/oval/util.go index 6dc03e6b..76051ebb 100644 --- a/oval/util.go +++ b/oval/util.go @@ -337,7 +337,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru if running.Release != "" { switch family { - case constant.RedHat, constant.CentOS, constant.Oracle: + case constant.RedHat, constant.CentOS, constant.Rocky, constant.Oracle: // For kernel related packages, ignore OVAL information with different major versions if _, ok := kernelRelatedPackNames[ovalPack.Name]; ok { if util.Major(ovalPack.Version) != util.Major(running.Release) { @@ -377,7 +377,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru return true, false, ovalPack.Version, nil } - // But CentOS can't judge whether fixed or unfixed. + // But CentOS/Rocky can't judge whether fixed or unfixed. // Because fixed state in RHEL OVAL is different. // So, it have to be judged version comparison. @@ -435,9 +435,10 @@ func lessThan(family, newVer string, packInOVAL ovalmodels.Package) (bool, error return vera.LessThan(verb), nil case constant.RedHat, - constant.CentOS: - vera := rpmver.NewVersion(centOSVersionToRHEL(newVer)) - verb := rpmver.NewVersion(centOSVersionToRHEL(packInOVAL.Version)) + constant.CentOS, + constant.Rocky: + vera := rpmver.NewVersion(rhelDownStreamOSVersionToRHEL(newVer)) + verb := rpmver.NewVersion(rhelDownStreamOSVersionToRHEL(packInOVAL.Version)) return vera.LessThan(verb), nil default: @@ -445,10 +446,10 @@ func lessThan(family, newVer string, packInOVAL ovalmodels.Package) (bool, error } } -var centosVerPattern = regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`) +var rhelDownStreamOSVerPattern = regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.(centos|rocky))?`) -func centOSVersionToRHEL(ver string) string { - return centosVerPattern.ReplaceAllString(ver, ".el$1") +func rhelDownStreamOSVersionToRHEL(ver string) string { + return rhelDownStreamOSVerPattern.ReplaceAllString(ver, ".el$1") } // NewOVALClient returns a client for OVAL database @@ -461,8 +462,9 @@ func NewOVALClient(family string, cnf config.GovalDictConf) (Client, error) { case constant.RedHat: return NewRedhat(&cnf), nil case constant.CentOS: - //use RedHat's OVAL return NewCentOS(&cnf), nil + case constant.Rocky: + return NewRocky(&cnf), nil case constant.Oracle: return NewOracle(&cnf), nil case constant.SUSEEnterpriseServer: @@ -485,17 +487,14 @@ func NewOVALClient(family string, cnf config.GovalDictConf) (Client, error) { } // GetFamilyInOval returns the OS family name in OVAL -// For example, CentOS uses Red Hat's OVAL, so return 'redhat' +// For example, CentOS/Rocky uses Red Hat's OVAL, so return 'redhat' func GetFamilyInOval(familyInScanResult string) (string, error) { switch familyInScanResult { case constant.Debian, constant.Raspbian: return constant.Debian, nil case constant.Ubuntu: return constant.Ubuntu, nil - case constant.RedHat: - return constant.RedHat, nil - case constant.CentOS: - //use RedHat's OVAL + case constant.RedHat, constant.CentOS, constant.Rocky: return constant.RedHat, nil case constant.Oracle: return constant.Oracle, nil diff --git a/oval/util_test.go b/oval/util_test.go index 97f5f325..6de1d650 100644 --- a/oval/util_test.go +++ b/oval/util_test.go @@ -1078,6 +1078,472 @@ func TestIsOvalDefAffected(t *testing.T) { notFixedYet: false, fixedIn: "3.1.0", }, + // Rocky Linux + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.7", + newVersionRelease: "", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.8", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.9", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.6", + newVersionRelease: "0:1.2.3-45.el6.rocky.7", + }, + }, + affected: true, + notFixedYet: true, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.6", + newVersionRelease: "0:1.2.3-45.el6.rocky.8", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.rocky.6", + newVersionRelease: "0:1.2.3-45.el6.rocky.9", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.8", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6_7.8", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.7", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.8", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.9", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.6", + newVersionRelease: "0:1.2.3-45.sl6.7", + }, + }, + affected: true, + notFixedYet: true, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.6", + newVersionRelease: "0:1.2.3-45.sl6.8", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.sl6.6", + newVersionRelease: "0:1.2.3-45.sl6.9", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "0:1.2.3-45.el6_7.8", + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6_7.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6.8", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: "rocky", + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "a", + NotFixedYet: false, + }, + { + Name: "b", + NotFixedYet: false, + Version: "0:1.2.3-45.el6.8", + }, + }, + }, + req: request{ + packName: "b", + isSrcPack: false, + versionRelease: "0:1.2.3-45.el6_7.8", + }, + }, + affected: false, + notFixedYet: false, + }, + // For kernel related packages, ignore OVAL with different major versions + { + in: in{ + family: constant.Rocky, + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "kernel", + Version: "4.1.0", + NotFixedYet: false, + }, + }, + }, + req: request{ + packName: "kernel", + versionRelease: "3.0.0", + newVersionRelease: "3.2.0", + }, + kernel: models.Kernel{ + Release: "3.0.0", + }, + }, + affected: false, + notFixedYet: false, + }, + { + in: in{ + family: constant.Rocky, + def: ovalmodels.Definition{ + AffectedPacks: []ovalmodels.Package{ + { + Name: "kernel", + Version: "3.1.0", + NotFixedYet: false, + }, + }, + }, + req: request{ + packName: "kernel", + versionRelease: "3.0.0", + newVersionRelease: "3.2.0", + }, + kernel: models.Kernel{ + Release: "3.0.0", + }, + }, + affected: true, + notFixedYet: false, + fixedIn: "3.1.0", + }, // dnf module { in: in{ @@ -1326,7 +1792,7 @@ func TestIsOvalDefAffected(t *testing.T) { } } -func Test_centOSVersionToRHEL(t *testing.T) { +func Test_rhelDownStreamOSVersionToRHEL(t *testing.T) { type args struct { ver string } @@ -1342,6 +1808,13 @@ func Test_centOSVersionToRHEL(t *testing.T) { }, want: "grub2-tools-2.02-0.80.el7.x86_64", }, + { + name: "remove rocky.", + args: args{ + ver: "platform-python-3.6.8-37.el8.rocky.x86_64", + }, + want: "platform-python-3.6.8-37.el8.x86_64", + }, { name: "noop", args: args{ @@ -1359,8 +1832,8 @@ func Test_centOSVersionToRHEL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := centOSVersionToRHEL(tt.args.ver); got != tt.want { - t.Errorf("centOSVersionToRHEL() = %v, want %v", got, tt.want) + if got := rhelDownStreamOSVersionToRHEL(tt.args.ver); got != tt.want { + t.Errorf("rhelDownStreamOSVersionToRHEL() = %v, want %v", got, tt.want) } }) } diff --git a/scanner/centos.go b/scanner/centos.go index e65955e1..e5e8e8ca 100644 --- a/scanner/centos.go +++ b/scanner/centos.go @@ -49,7 +49,7 @@ func (o *centos) depsFast() []string { } // repoquery - // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8 + // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky8 return []string{"yum-utils"} } @@ -59,7 +59,7 @@ func (o *centos) depsFastRoot() []string { } // repoquery - // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8 + // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky8 return []string{"yum-utils"} } diff --git a/scanner/redhatbase.go b/scanner/redhatbase.go index 60d481f6..40cd12e4 100644 --- a/scanner/redhatbase.go +++ b/scanner/redhatbase.go @@ -100,10 +100,14 @@ func detectRedhat(c config.ServerInfo) (bool, osTypeInterface) { release := result[2] switch strings.ToLower(result[1]) { - case "centos", "centos linux": + case "centos", "centos linux", "centos stream": cent := newCentOS(c) cent.setDistro(constant.CentOS, release) return true, cent + case "rocky", "rocky linux": + rocky := newRocky(c) + rocky.setDistro(constant.Rocky, release) + return true, rocky default: // RHEL rhel := newRHEL(c) @@ -476,7 +480,7 @@ func (o *redhatBase) isExecNeedsRestarting() bool { // TODO zypper ps // https://github.com/future-architect/vuls/issues/696 return false - case constant.RedHat, constant.CentOS, constant.Oracle: + case constant.RedHat, constant.CentOS, constant.Rocky, constant.Oracle: majorVersion, err := o.Distro.MajorVersion() if err != nil || majorVersion < 6 { o.log.Errorf("Not implemented yet: %s, err: %+v", o.Distro, err) @@ -655,7 +659,7 @@ func (o *redhatBase) rpmQf() string { func (o *redhatBase) detectEnabledDnfModules() ([]string, error) { switch o.Distro.Family { - case constant.RedHat, constant.CentOS: + case constant.RedHat, constant.CentOS, constant.Rocky: //TODO OracleLinux default: return nil, nil diff --git a/scanner/rhel.go b/scanner/rhel.go index 22afdfd0..42348c25 100644 --- a/scanner/rhel.go +++ b/scanner/rhel.go @@ -55,7 +55,7 @@ func (o *rhel) depsFastRoot() []string { } // repoquery - // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8 + // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky8 return []string{"yum-utils"} } diff --git a/scanner/rocky.go b/scanner/rocky.go index 922ff71b..5985e08e 100644 --- a/scanner/rocky.go +++ b/scanner/rocky.go @@ -11,7 +11,7 @@ type rocky struct { redhatBase } -// NewAmazon is constructor +// NewRocky is constructor func newRocky(c config.ServerInfo) *rocky { r := &rocky{ redhatBase{ @@ -49,7 +49,7 @@ func (o *rocky) depsFast() []string { } // repoquery - // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky + // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky8 return []string{"yum-utils"} } @@ -59,7 +59,7 @@ func (o *rocky) depsFastRoot() []string { } // repoquery - // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky + // `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8, Rocky8 return []string{"yum-utils"} } diff --git a/scanner/serverapi.go b/scanner/serverapi.go index b9e3c50f..d096c67e 100644 --- a/scanner/serverapi.go +++ b/scanner/serverapi.go @@ -211,12 +211,14 @@ func ParseInstalledPkgs(distro config.Distro, kernel models.Kernel, pkgList stri var osType osTypeInterface switch distro.Family { - case constant.Debian, constant.Ubuntu: + case constant.Debian, constant.Ubuntu, constant.Raspbian: osType = &debian{base: base} case constant.RedHat: osType = &rhel{redhatBase: redhatBase{base: base}} case constant.CentOS: osType = ¢os{redhatBase: redhatBase{base: base}} + case constant.Rocky: + osType = &rocky{redhatBase: redhatBase{base: base}} case constant.Oracle: osType = &oracle{redhatBase: redhatBase{base: base}} case constant.Amazon: diff --git a/scanner/utils.go b/scanner/utils.go index ae463821..36be0caf 100644 --- a/scanner/utils.go +++ b/scanner/utils.go @@ -26,7 +26,7 @@ func isRunningKernel(pack models.Package, family string, kernel models.Kernel) ( } return false, false - case constant.RedHat, constant.Oracle, constant.CentOS, constant.Amazon: + case constant.RedHat, constant.Oracle, constant.CentOS, constant.Rocky, constant.Amazon: switch pack.Name { case "kernel", "kernel-devel", "kernel-core", "kernel-modules", "kernel-uek": ver := fmt.Sprintf("%s-%s.%s", pack.Version, pack.Release, pack.Arch)