Skip to content

Commit

Permalink
feat(oval): support EPEL
Browse files Browse the repository at this point in the history
  • Loading branch information
MaineK00n committed Mar 7, 2022
1 parent ec31c54 commit 43dade9
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 40 deletions.
3 changes: 3 additions & 0 deletions constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const (
// Oracle is
Oracle = "oracle"

// EPEL is
EPEL = "epel"

// FreeBSD is
FreeBSD = "freebsd"

Expand Down
1 change: 1 addition & 0 deletions models/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type Package struct {
NewVersion string `json:"newVersion"`
NewRelease string `json:"newRelease"`
Arch string `json:"arch"`
Vendor string `json:"vendor"`
Repository string `json:"repository"`
Changelog *Changelog `json:"changelog,omitempty"`
AffectedProcs []AffectedProcess `json:",omitempty"`
Expand Down
111 changes: 85 additions & 26 deletions oval/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ func (e *ovalResult) Sort() {
}

type request struct {
family string
release string
packName string
versionRelease string
newVersionRelease string
Expand All @@ -110,18 +112,54 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult, url string) (relatedDefs ova
defer close(resChan)
defer close(errChan)

ovalFamily, err := GetFamilyInOval(r.Family)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
}
ovalRelease := r.Release
if r.Family == constant.CentOS {
ovalRelease = strings.TrimPrefix(r.Release, "stream")
}
go func() {
for _, pack := range r.Packages {
reqChan <- request{
req := request{
family: ovalFamily,
release: ovalRelease,
packName: pack.Name,
versionRelease: pack.FormatVer(),
newVersionRelease: pack.FormatVer(),
isSrcPack: false,
newVersionRelease: pack.FormatNewVer(),
arch: pack.Arch,
isSrcPack: false,
}

switch ovalFamily {
case constant.RedHat, constant.Alma, constant.Rocky, constant.Oracle:
if pack.Vendor == "Fedora Project" {
switch util.Major(ovalRelease) {
case "7", "8":
req.family = constant.EPEL
default:
continue
}
}
case constant.Amazon:
if pack.Vendor == "Fedora Project" {
switch strings.Fields(ovalRelease)[0] {
case "2":
req.family = constant.EPEL
req.release = "7"
default:
continue
}
}
}

reqChan <- req
}
for _, pack := range r.SrcPackages {
reqChan <- request{
family: ovalFamily,
release: ovalRelease,
packName: pack.Name,
binaryPackNames: pack.BinaryNames,
versionRelease: pack.Version,
Expand All @@ -131,14 +169,6 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult, url string) (relatedDefs ova
}
}()

ovalFamily, err := GetFamilyInOval(r.Family)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
}
ovalRelease := r.Release
if r.Family == constant.CentOS {
ovalRelease = strings.TrimPrefix(r.Release, "stream")
}
concurrency := 10
tasks := util.GenWorkers(concurrency)
for i := 0; i < nReq; i++ {
Expand All @@ -148,8 +178,8 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult, url string) (relatedDefs ova
url, err := util.URLPathJoin(
url,
"packs",
ovalFamily,
ovalRelease,
req.family,
req.release,
req.packName,
)
if err != nil {
Expand Down Expand Up @@ -248,18 +278,55 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
}

func getDefsByPackNameFromOvalDB(r *models.ScanResult, driver ovaldb.DB) (relatedDefs ovalResult, err error) {
ovalFamily, err := GetFamilyInOval(r.Family)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
}
ovalRelease := r.Release
if r.Family == constant.CentOS {
ovalRelease = strings.TrimPrefix(r.Release, "stream")
}

requests := []request{}
for _, pack := range r.Packages {
requests = append(requests, request{
req := request{
family: ovalFamily,
release: ovalRelease,
packName: pack.Name,
versionRelease: pack.FormatVer(),
newVersionRelease: pack.FormatNewVer(),
arch: pack.Arch,
isSrcPack: false,
})
}

switch ovalFamily {
case constant.RedHat, constant.Alma, constant.Rocky, constant.Oracle:
if pack.Vendor == "Fedora Project" {
switch util.Major(ovalRelease) {
case "7", "8":
req.family = constant.EPEL
default:
continue
}
}
case constant.Amazon:
if pack.Vendor == "Fedora Project" {
switch strings.Fields(ovalRelease)[0] {
case "2":
req.family = constant.EPEL
req.release = "7"
default:
continue
}
}
}

requests = append(requests, req)
}
for _, pack := range r.SrcPackages {
requests = append(requests, request{
family: ovalFamily,
release: ovalRelease,
packName: pack.Name,
binaryPackNames: pack.BinaryNames,
versionRelease: pack.Version,
Expand All @@ -268,16 +335,8 @@ func getDefsByPackNameFromOvalDB(r *models.ScanResult, driver ovaldb.DB) (relate
})
}

ovalFamily, err := GetFamilyInOval(r.Family)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
}
ovalRelease := r.Release
if r.Family == constant.CentOS {
ovalRelease = strings.TrimPrefix(r.Release, "stream")
}
for _, req := range requests {
definitions, err := driver.GetByPackName(ovalFamily, ovalRelease, req.packName, req.arch)
definitions, err := driver.GetByPackName(req.family, req.release, req.packName, req.arch)
if err != nil {
return relatedDefs, xerrors.Errorf("Failed to get %s OVAL info by package: %#v, err: %w", r.Family, req, err)
}
Expand Down Expand Up @@ -321,9 +380,9 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
}

switch family {
case constant.Oracle, constant.Amazon, constant.Fedora:
case constant.Oracle, constant.Amazon, constant.Fedora, constant.EPEL:
if ovalPack.Arch == "" {
logging.Log.Infof("Arch is needed to detect Vulns for Amazon Linux, Oracle Linux and Fedora, but empty. You need refresh OVAL maybe. oval: %#v, defID: %s", ovalPack, def.DefinitionID)
logging.Log.Infof("Arch is needed to detect Vulns for Amazon Linux, Oracle Linux, Fedora and EPEL, but empty. You need refresh OVAL maybe. oval: %#v, defID: %s", ovalPack, def.DefinitionID)
continue
}
}
Expand Down
28 changes: 14 additions & 14 deletions scanner/redhatbase.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,25 +500,25 @@ 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)
ss := strings.SplitN(line, " ", 6)
if len(ss) != 6 {
return nil, xerrors.Errorf("Failed to parse package line: %s", line)
}

ver := ""
epoch := fields[1]
epoch := ss[1]
if epoch == "0" || epoch == "(none)" {
ver = fields[2]
ver = ss[2]
} else {
ver = fmt.Sprintf("%s:%s", epoch, fields[2])
ver = fmt.Sprintf("%s:%s", epoch, ss[2])
}

return &models.Package{
Name: fields[0],
Name: ss[0],
Version: ver,
Release: fields[3],
Arch: fields[4],
Release: ss[3],
Arch: ss[4],
Vendor: strings.TrimSuffix(ss[5], "\r"),
}, nil
}

Expand Down Expand Up @@ -783,8 +783,8 @@ func (o *redhatBase) getOwnerPkgs(paths []string) (names []string, _ error) {
}

func (o *redhatBase) rpmQa() string {
const old = `rpm -qa --queryformat "%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n"`
const new = `rpm -qa --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n"`
const old = `rpm -qa --queryformat "%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH} %{VENDOR}\n"`
const new = `rpm -qa --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH} %{VENDOR}\n"`
switch o.Distro.Family {
case constant.OpenSUSE:
if o.Distro.Release == "tumbleweed" {
Expand All @@ -807,8 +807,8 @@ func (o *redhatBase) rpmQa() string {
}

func (o *redhatBase) rpmQf() string {
const old = `rpm -qf --queryformat "%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n" `
const new = `rpm -qf --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n" `
const old = `rpm -qf --queryformat "%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH} %{VENDOR}\n" `
const new = `rpm -qf --queryformat "%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH} %{VENDOR}\n" `
switch o.Distro.Family {
case constant.OpenSUSE:
if o.Distro.Release == "tumbleweed" {
Expand Down

0 comments on commit 43dade9

Please sign in to comment.