From bbb8fcbb42600e7bde7abd6d5ae3d2d119e1260e Mon Sep 17 00:00:00 2001 From: MaineK00n Date: Tue, 1 Aug 2023 16:42:23 +0900 Subject: [PATCH] refactor(amazon): version determination, parseInstalledPackagesLine --- oval/util.go | 42 +++------- scanner/redhatbase.go | 67 +++++----------- scanner/redhatbase_test.go | 155 +++++++++++++------------------------ scanner/windows.go | 1 + 4 files changed, 84 insertions(+), 181 deletions(-) diff --git a/oval/util.go b/oval/util.go index fc6c71d3..4a6a202e 100644 --- a/oval/util.go +++ b/oval/util.go @@ -113,24 +113,13 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult, url string) (relatedDefs ova ovalRelease = strings.TrimPrefix(r.Release, "stream") case constant.Amazon: switch s := strings.Fields(r.Release)[0]; s { - case "1": - ovalRelease = "1" - case "2": - ovalRelease = "2" - case "2022": - ovalRelease = "2022" - case "2023": - ovalRelease = "2023" - case "2025": - ovalRelease = "2025" - case "2027": - ovalRelease = "2027" - case "2029": - ovalRelease = "2029" + case "1", "2", "2022", "2023", "2025", "2027", "2029": + ovalRelease = s default: - if _, err := time.Parse("2006.01", s); err == nil { - ovalRelease = "1" + if _, err := time.Parse("2006.01", s); err != nil { + return relatedDefs, xerrors.Errorf(`Failed to detect amazon version. err: unexpected Amazon Linux 1 version format. expected: "yyyy.MM", actual: "%s". err: %w`, s, err) } + ovalRelease = "1" } } @@ -287,24 +276,13 @@ func getDefsByPackNameFromOvalDB(r *models.ScanResult, driver ovaldb.DB) (relate ovalRelease = strings.TrimPrefix(r.Release, "stream") case constant.Amazon: switch s := strings.Fields(r.Release)[0]; s { - case "1": - ovalRelease = "1" - case "2": - ovalRelease = "2" - case "2022": - ovalRelease = "2022" - case "2023": - ovalRelease = "2023" - case "2025": - ovalRelease = "2025" - case "2027": - ovalRelease = "2027" - case "2029": - ovalRelease = "2029" + case "1", "2", "2022", "2023", "2025", "2027", "2029": + ovalRelease = s default: - if _, err := time.Parse("2006.01", s); err == nil { - ovalRelease = "1" + if _, err := time.Parse("2006.01", s); err != nil { + return relatedDefs, xerrors.Errorf(`Failed to detect amazon version. err: unexpected Amazon Linux 1 version format. expected: "yyyy.MM", actual: "%s". err: %w`, s, err) } + ovalRelease = "1" } } diff --git a/scanner/redhatbase.go b/scanner/redhatbase.go index 468bce2a..b80e9e0f 100644 --- a/scanner/redhatbase.go +++ b/scanner/redhatbase.go @@ -519,28 +519,7 @@ func (o *redhatBase) parseInstalledPackages(stdout string) (models.Packages, mod continue } - var ( - pack *models.Package - err error - ) - switch o.getDistro().Family { - case constant.Amazon: - switch strings.Fields(o.getDistro().Release)[0] { - case "2": - switch len(strings.Fields(line)) { - case 5: - pack, err = o.parseInstalledPackagesLine(line) - case 6: - pack, err = o.parseInstalledPackagesLineFromRepoquery(line) - default: - return nil, nil, xerrors.Errorf("Failed to parse package line: %s", line) - } - default: - pack, err = o.parseInstalledPackagesLine(line) - } - default: - pack, err = o.parseInstalledPackagesLine(line) - } + pack, err := o.parseInstalledPackagesLine(line) if err != nil { return nil, nil, err } @@ -572,30 +551,7 @@ func (o *redhatBase) parseInstalledPackages(stdout string) (models.Packages, mod func (o *redhatBase) parseInstalledPackagesLine(line string) (*models.Package, error) { fields := strings.Fields(line) - if len(fields) != 5 { - return nil, - xerrors.Errorf("Failed to parse package line: %s", line) - } - - ver := "" - epoch := fields[1] - if epoch == "0" || epoch == "(none)" { - ver = fields[2] - } else { - ver = fmt.Sprintf("%s:%s", epoch, fields[2]) - } - - return &models.Package{ - Name: fields[0], - Version: ver, - Release: fields[3], - Arch: fields[4], - }, nil -} - -func (o *redhatBase) parseInstalledPackagesLineFromRepoquery(line string) (*models.Package, error) { - fields := strings.Fields(line) - if len(fields) != 6 { + if len(fields) < 5 { return nil, xerrors.Errorf("Failed to parse package line: %s", line) } @@ -607,9 +563,22 @@ func (o *redhatBase) parseInstalledPackagesLineFromRepoquery(line string) (*mode ver = fmt.Sprintf("%s:%s", epoch, fields[2]) } - repo := strings.TrimPrefix(fields[5], "@") - if repo == "installed" { - repo = "amzn2-core" + var repo string + switch o.getDistro().Family { + case constant.Amazon: + switch strings.Fields(o.getDistro().Release)[0] { + case "2": + if len(fields) == 5 { + break + } + if fields[5] == "installed" { + repo = "amzn2-core" + break + } + repo = strings.TrimPrefix(fields[5], "@") + default: + } + default: } return &models.Package{ diff --git a/scanner/redhatbase_test.go b/scanner/redhatbase_test.go index 14216c15..07f8128d 100644 --- a/scanner/redhatbase_test.go +++ b/scanner/redhatbase_test.go @@ -118,32 +118,6 @@ kernel-devel 0 2.6.32 695.20.3.el6 x86_64`, }, }, }, - { - in: `openssl 0 1.0.1e 30.el6.11 x86_64 -Percona-Server-shared-56 1 5.6.19 rel67.0.el6 x84_64 -kernel 0 2.6.32 696.20.1.el6 x86_64 -kernel 0 2.6.32 696.20.3.el6 x86_64 -kernel 0 2.6.32 695.20.3.el6 x86_64`, - distro: config.Distro{Family: constant.Amazon, Release: "2 (Karoo)"}, - kernel: models.Kernel{}, - packages: models.Packages{ - "openssl": models.Package{ - Name: "openssl", - Version: "1.0.1e", - Release: "30.el6.11", - }, - "Percona-Server-shared-56": models.Package{ - Name: "Percona-Server-shared-56", - Version: "1:5.6.19", - Release: "rel67.0.el6", - }, - "kernel": models.Package{ - Name: "kernel", - Version: "2.6.32", - Release: "696.20.3.el6", - }, - }, - }, { in: `yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed @@ -195,67 +169,52 @@ java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8` } } } - } -func TestParseInstalledPackagesLine(t *testing.T) { - r := newRHEL(config.ServerInfo{}) - var packagetests = []struct { - in string - pack models.Package - err bool +func Test_redhatBase_parseInstalledPackagesLine(t *testing.T) { + tests := []struct { + name string + distro config.Distro + line string + want *models.Package + wantErr bool }{ { - "openssl 0 1.0.1e 30.el6.11 x86_64", - models.Package{ + name: "rpm -qa redhat 6.11 1", + distro: config.Distro{ + Family: constant.RedHat, + Release: "6.11", + }, + line: "openssl 0 1.0.1e 30.el6.11 x86_64", + want: &models.Package{ Name: "openssl", Version: "1.0.1e", Release: "30.el6.11", + Arch: "x86_64", }, - false, }, { - "Percona-Server-shared-56 1 5.6.19 rel67.0.el6 x84_64", - models.Package{ + name: "rpm -qa redhat 6.11 2", + distro: config.Distro{ + Family: constant.RedHat, + Release: "6.11", + }, + line: "Percona-Server-shared-56 1 5.6.19 rel67.0.el6 x84_64", + want: &models.Package{ Name: "Percona-Server-shared-56", Version: "1:5.6.19", Release: "rel67.0.el6", + Arch: "x84_64", }, - false, }, - } - - for i, tt := range packagetests { - p, err := r.parseInstalledPackagesLine(tt.in) - if err == nil && tt.err { - t.Errorf("Expected err not occurred: %d", i) - } - if err != nil && !tt.err { - t.Errorf("UnExpected err not occurred: %d", i) - } - if p.Name != tt.pack.Name { - t.Errorf("name: expected %s, actual %s", tt.pack.Name, p.Name) - } - if p.Version != tt.pack.Version { - t.Errorf("version: expected %s, actual %s", tt.pack.Version, p.Version) - } - if p.Release != tt.pack.Release { - t.Errorf("release: expected %s, actual %s", tt.pack.Release, p.Release) - } - } -} - -func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) { - r := newRHEL(config.ServerInfo{}) - - var packagetests = []struct { - in string - pack models.Package - err bool - }{ { - in: "yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core", - pack: models.Package{ + name: "rpmquery amazonlinux 2 1", + distro: config.Distro{ + Family: constant.Amazon, + Release: "2", + }, + line: "yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core", + want: &models.Package{ Name: "yum-utils", Version: "1.1.31", Release: "46.amzn2.0.1", @@ -264,8 +223,13 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) { }, }, { - in: "zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed", - pack: models.Package{ + name: "rpmquery amazonlinux 2 2", + distro: config.Distro{ + Family: constant.Amazon, + Release: "2", + }, + line: "zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed", + want: &models.Package{ Name: "zlib", Version: "1.2.7", Release: "19.amzn2.0.1", @@ -274,8 +238,13 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) { }, }, { - in: "java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8", - pack: models.Package{ + name: "rpmquery amazonlinux 2 3", + distro: config.Distro{ + Family: constant.Amazon, + Release: "2", + }, + line: "java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8", + want: &models.Package{ Name: "java-1.8.0-amazon-corretto", Version: "1:1.8.0_192.b12", Release: "1.amzn2", @@ -284,32 +253,18 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) { }, }, } - - for i, tt := range packagetests { - p, err := r.parseInstalledPackagesLineFromRepoquery(tt.in) - if err == nil && tt.err { - t.Errorf("Expected err not occurred: %d", i) - } - if err != nil && !tt.err { - t.Errorf("UnExpected err not occurred: %d", i) - } - if p.Name != tt.pack.Name { - t.Errorf("name: expected %s, actual %s", tt.pack.Name, p.Name) - } - if p.Version != tt.pack.Version { - t.Errorf("version: expected %s, actual %s", tt.pack.Version, p.Version) - } - if p.Release != tt.pack.Release { - t.Errorf("release: expected %s, actual %s", tt.pack.Release, p.Release) - } - if p.Arch != tt.pack.Arch { - t.Errorf("arch: expected %s, actual %s", tt.pack.Arch, p.Arch) - } - if p.Repository != tt.pack.Repository { - t.Errorf("repository: expected %s, actual %s", tt.pack.Repository, p.Repository) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := (&redhatBase{base: base{Distro: tt.distro}}).parseInstalledPackagesLine(tt.line) + if (err != nil) != tt.wantErr { + t.Errorf("redhatBase.parseInstalledPackagesLine() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("redhatBase.parseInstalledPackagesLine() = %v, want %v", got, tt.want) + } + }) } - } func TestParseYumCheckUpdateLine(t *testing.T) { diff --git a/scanner/windows.go b/scanner/windows.go index 9b294188..bfb2ef11 100644 --- a/scanner/windows.go +++ b/scanner/windows.go @@ -4399,6 +4399,7 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{ }, } +// DetectKBsFromKernelVersion : func DetectKBsFromKernelVersion(release, kernelVersion string) (models.WindowsKB, error) { switch ss := strings.Split(kernelVersion, "."); len(ss) { case 3: