refactor(detector): standardize db.NewDB to db.CloseDB (#1380)
* feat(subcmds/report,server): read environment variables when configPath is "" * refactor: standardize db.NewDB to db.CloseDB * chore: clean up import * chore: error wrap * chore: update goval-dictionary * fix(oval): return Pseudo instead of nil for client * chore: fix comment * fix: lint error
This commit is contained in:
@@ -4,10 +4,12 @@
|
||||
package oval
|
||||
|
||||
import (
|
||||
"github.com/future-architect/vuls/config"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/constant"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
)
|
||||
|
||||
// Alpine is the struct of Alpine Linux
|
||||
@@ -16,11 +18,12 @@ type Alpine struct {
|
||||
}
|
||||
|
||||
// NewAlpine creates OVAL client for SUSE
|
||||
func NewAlpine(cnf config.VulnDictInterface) Alpine {
|
||||
func NewAlpine(driver ovaldb.DB, baseURL string) Alpine {
|
||||
return Alpine{
|
||||
Base{
|
||||
family: constant.Alpine,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Alpine,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -28,23 +31,13 @@ func NewAlpine(cnf config.VulnDictInterface) Alpine {
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o Alpine) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
|
||||
var relatedDefs ovalResult
|
||||
if o.Cnf.IsFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.Cnf.GetURL()); err != nil {
|
||||
return 0, err
|
||||
if o.driver == nil {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.baseURL); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions via HTTP. err: %w", err)
|
||||
}
|
||||
} else {
|
||||
driver, err := newOvalDB(o.Cnf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
|
||||
return 0, err
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(r, o.driver); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions from DB. err: %w", err)
|
||||
}
|
||||
}
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
|
||||
@@ -7,11 +7,13 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/constant"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
ovalmodels "github.com/vulsio/goval-dictionary/models"
|
||||
)
|
||||
|
||||
@@ -122,12 +124,13 @@ type Debian struct {
|
||||
}
|
||||
|
||||
// NewDebian creates OVAL client for Debian
|
||||
func NewDebian(cnf config.VulnDictInterface) Debian {
|
||||
func NewDebian(driver ovaldb.DB, baseURL string) Debian {
|
||||
return Debian{
|
||||
DebianBase{
|
||||
Base{
|
||||
family: constant.Debian,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Debian,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -157,23 +160,13 @@ func (o Debian) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
|
||||
}
|
||||
|
||||
var relatedDefs ovalResult
|
||||
if o.Cnf.IsFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.Cnf.GetURL()); err != nil {
|
||||
return 0, err
|
||||
if o.driver == nil {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.baseURL); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions via HTTP. err: %w", err)
|
||||
}
|
||||
} else {
|
||||
driver, err := newOvalDB(o.Cnf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
|
||||
return 0, err
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(r, o.driver); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions from DB. err: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,12 +206,13 @@ type Ubuntu struct {
|
||||
}
|
||||
|
||||
// NewUbuntu creates OVAL client for Debian
|
||||
func NewUbuntu(cnf config.VulnDictInterface) Ubuntu {
|
||||
func NewUbuntu(driver ovaldb.DB, baseURL string) Ubuntu {
|
||||
return Ubuntu{
|
||||
DebianBase{
|
||||
Base{
|
||||
family: constant.Ubuntu,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Ubuntu,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -471,23 +465,13 @@ func (o Ubuntu) fillWithOval(r *models.ScanResult, kernelNamesInOval []string) (
|
||||
}
|
||||
|
||||
var relatedDefs ovalResult
|
||||
if o.Cnf.IsFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.Cnf.GetURL()); err != nil {
|
||||
return 0, err
|
||||
if o.driver == nil {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.baseURL); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions via HTTP. err: %w", err)
|
||||
}
|
||||
} else {
|
||||
driver, err := newOvalDB(o.Cnf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
|
||||
return 0, err
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(r, o.driver); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions from DB. err: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
102
oval/oval.go
102
oval/oval.go
@@ -8,14 +8,15 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/constant"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"github.com/vulsio/goval-dictionary/db"
|
||||
"golang.org/x/xerrors"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
)
|
||||
|
||||
// Client is the interface of OVAL client.
|
||||
@@ -23,51 +24,56 @@ type Client interface {
|
||||
FillWithOval(*models.ScanResult) (int, error)
|
||||
CheckIfOvalFetched(string, string) (bool, error)
|
||||
CheckIfOvalFresh(string, string) (bool, error)
|
||||
CloseDB() error
|
||||
}
|
||||
|
||||
// Base is a base struct
|
||||
type Base struct {
|
||||
family string
|
||||
Cnf config.VulnDictInterface
|
||||
driver ovaldb.DB
|
||||
baseURL string
|
||||
family string
|
||||
}
|
||||
|
||||
// CloseDB close a DB connection
|
||||
func (b Base) CloseDB() error {
|
||||
if b.driver == nil {
|
||||
return nil
|
||||
}
|
||||
return b.driver.CloseDB()
|
||||
}
|
||||
|
||||
// CheckIfOvalFetched checks if oval entries are in DB by family, release.
|
||||
func (b Base) CheckIfOvalFetched(osFamily, release string) (fetched bool, err error) {
|
||||
func (b Base) CheckIfOvalFetched(osFamily, release string) (bool, error) {
|
||||
ovalFamily, err := GetFamilyInOval(osFamily)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
|
||||
}
|
||||
if ovalFamily == "" {
|
||||
return false, nil
|
||||
}
|
||||
ovalRelease := release
|
||||
if osFamily == constant.CentOS {
|
||||
ovalRelease = strings.TrimPrefix(release, "stream")
|
||||
}
|
||||
if !b.Cnf.IsFetchViaHTTP() {
|
||||
driver, err := newOvalDB(b.Cnf)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
count, err := driver.CountDefs(ovalFamily, ovalRelease)
|
||||
var count int
|
||||
if b.driver == nil {
|
||||
url, err := util.URLPathJoin(b.baseURL, "count", ovalFamily, ovalRelease)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to join URLPath. err: %w", err)
|
||||
}
|
||||
resp, body, errs := gorequest.New().Timeout(10 * time.Second).Get(url).End()
|
||||
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
|
||||
return false, xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %+v", url, resp, errs)
|
||||
}
|
||||
if err := json.Unmarshal([]byte(body), &count); err != nil {
|
||||
return false, xerrors.Errorf("Failed to Unmarshal. body: %s, err: %w", body, err)
|
||||
}
|
||||
} else {
|
||||
count, err = b.driver.CountDefs(ovalFamily, ovalRelease)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to count OVAL defs: %s, %s, %w", ovalFamily, ovalRelease, err)
|
||||
}
|
||||
logging.Log.Infof("OVAL %s %s found. defs: %d", ovalFamily, ovalRelease, count)
|
||||
return 0 < count, nil
|
||||
}
|
||||
|
||||
url, _ := util.URLPathJoin(config.Conf.OvalDict.URL, "count", ovalFamily, ovalRelease)
|
||||
resp, body, errs := gorequest.New().Timeout(10 * time.Second).Get(url).End()
|
||||
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
|
||||
return false, xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %+v", url, resp, errs)
|
||||
}
|
||||
count := 0
|
||||
if err := json.Unmarshal([]byte(body), &count); err != nil {
|
||||
return false, xerrors.Errorf("Failed to Unmarshal. body: %s, err: %w", body, err)
|
||||
}
|
||||
logging.Log.Infof("OVAL %s %s found. defs: %d", ovalFamily, ovalRelease, count)
|
||||
return 0 < count, nil
|
||||
@@ -79,35 +85,32 @@ func (b Base) CheckIfOvalFresh(osFamily, release string) (ok bool, err error) {
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to GetFamilyInOval. err: %w", err)
|
||||
}
|
||||
if ovalFamily == "" {
|
||||
return false, nil
|
||||
}
|
||||
ovalRelease := release
|
||||
if osFamily == constant.CentOS {
|
||||
ovalRelease = strings.TrimPrefix(release, "stream")
|
||||
}
|
||||
|
||||
var lastModified time.Time
|
||||
if !b.Cnf.IsFetchViaHTTP() {
|
||||
driver, err := newOvalDB(b.Cnf)
|
||||
if b.driver == nil {
|
||||
url, err := util.URLPathJoin(b.baseURL, "lastmodified", ovalFamily, ovalRelease)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("Failed to join URLPath. err: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
lastModified, err = driver.GetLastModified(ovalFamily, ovalRelease)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to GetLastModified: %w", err)
|
||||
}
|
||||
} else {
|
||||
url, _ := util.URLPathJoin(config.Conf.OvalDict.URL, "lastmodified", ovalFamily, ovalRelease)
|
||||
resp, body, errs := gorequest.New().Timeout(10 * time.Second).Get(url).End()
|
||||
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
|
||||
return false, xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %+v", url, resp, errs)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(body), &lastModified); err != nil {
|
||||
return false, xerrors.Errorf("Failed to Unmarshal. body: %s, err: %w", body, err)
|
||||
}
|
||||
} else {
|
||||
lastModified, err = b.driver.GetLastModified(ovalFamily, ovalRelease)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("Failed to GetLastModified: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
since := time.Now()
|
||||
@@ -122,23 +125,20 @@ func (b Base) CheckIfOvalFresh(osFamily, release string) (ok bool, err error) {
|
||||
}
|
||||
|
||||
// NewOvalDB returns oval db client
|
||||
func newOvalDB(cnf config.VulnDictInterface) (driver db.DB, err error) {
|
||||
func newOvalDB(cnf config.VulnDictInterface) (ovaldb.DB, error) {
|
||||
if cnf.IsFetchViaHTTP() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
path := cnf.GetURL()
|
||||
if cnf.GetType() == "sqlite3" {
|
||||
path = cnf.GetSQLite3Path()
|
||||
}
|
||||
|
||||
driver, locked, err := db.NewDB(cnf.GetType(), path, cnf.GetDebugSQL(), db.Option{})
|
||||
driver, locked, err := ovaldb.NewDB(cnf.GetType(), path, cnf.GetDebugSQL(), ovaldb.Option{})
|
||||
if err != nil {
|
||||
if locked {
|
||||
err = xerrors.Errorf("SQLite3: %s is locked. err: %w", cnf.GetSQLite3Path(), err)
|
||||
return nil, xerrors.Errorf("Failed to init OVAL DB. SQLite3: %s is locked. err: %w, ", cnf.GetSQLite3Path(), err)
|
||||
}
|
||||
err = xerrors.Errorf("Failed to new OVAL DB. err: %w", err)
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("Failed to init OVAL DB. DB Path: %s, err: %w", path, err)
|
||||
}
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
23
oval/pseudo.go
Normal file
23
oval/pseudo.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package oval
|
||||
|
||||
import "github.com/future-architect/vuls/models"
|
||||
|
||||
// Pseudo is OVAL client for Windows, FreeBSD and Pseudo
|
||||
type Pseudo struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// NewPseudo creates OVAL client for Windows, FreeBSD and Pseudo
|
||||
func NewPseudo(family string) Pseudo {
|
||||
return Pseudo{
|
||||
Base{
|
||||
driver: nil,
|
||||
baseURL: "",
|
||||
family: family,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (pse Pseudo) FillWithOval(_ *models.ScanResult) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/constant"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
ovalmodels "github.com/vulsio/goval-dictionary/models"
|
||||
)
|
||||
|
||||
@@ -22,23 +24,13 @@ type RedHatBase struct {
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o RedHatBase) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
|
||||
var relatedDefs ovalResult
|
||||
if o.Cnf.IsFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.Cnf.GetURL()); err != nil {
|
||||
return 0, err
|
||||
if o.driver == nil {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.baseURL); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions via HTTP. err: %w", err)
|
||||
}
|
||||
} else {
|
||||
driver, err := newOvalDB(o.Cnf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
|
||||
return 0, err
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(r, o.driver); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions from DB. err: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,12 +259,13 @@ type RedHat struct {
|
||||
}
|
||||
|
||||
// NewRedhat creates OVAL client for Redhat
|
||||
func NewRedhat(cnf config.VulnDictInterface) RedHat {
|
||||
func NewRedhat(driver ovaldb.DB, baseURL string) RedHat {
|
||||
return RedHat{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.RedHat,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.RedHat,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -284,12 +277,13 @@ type CentOS struct {
|
||||
}
|
||||
|
||||
// NewCentOS creates OVAL client for CentOS
|
||||
func NewCentOS(cnf config.VulnDictInterface) CentOS {
|
||||
func NewCentOS(driver ovaldb.DB, baseURL string) CentOS {
|
||||
return CentOS{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.CentOS,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.CentOS,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -301,12 +295,13 @@ type Oracle struct {
|
||||
}
|
||||
|
||||
// NewOracle creates OVAL client for Oracle
|
||||
func NewOracle(cnf config.VulnDictInterface) Oracle {
|
||||
func NewOracle(driver ovaldb.DB, baseURL string) Oracle {
|
||||
return Oracle{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.Oracle,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Oracle,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -319,12 +314,13 @@ type Amazon struct {
|
||||
}
|
||||
|
||||
// NewAmazon creates OVAL client for Amazon Linux
|
||||
func NewAmazon(cnf config.VulnDictInterface) Amazon {
|
||||
func NewAmazon(driver ovaldb.DB, baseURL string) Amazon {
|
||||
return Amazon{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.Amazon,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Amazon,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -337,12 +333,13 @@ type Alma struct {
|
||||
}
|
||||
|
||||
// NewAlma creates OVAL client for Alma Linux
|
||||
func NewAlma(cnf config.VulnDictInterface) Alma {
|
||||
func NewAlma(driver ovaldb.DB, baseURL string) Alma {
|
||||
return Alma{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.Alma,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Alma,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -355,12 +352,13 @@ type Rocky struct {
|
||||
}
|
||||
|
||||
// NewRocky creates OVAL client for Rocky Linux
|
||||
func NewRocky(cnf config.VulnDictInterface) Rocky {
|
||||
func NewRocky(driver ovaldb.DB, baseURL string) Rocky {
|
||||
return Rocky{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.Rocky,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Rocky,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -373,12 +371,13 @@ type Fedora struct {
|
||||
}
|
||||
|
||||
// NewFedora creates OVAL client for Fedora Linux
|
||||
func NewFedora(cnf config.VulnDictInterface) Fedora {
|
||||
func NewFedora(driver ovaldb.DB, baseURL string) Fedora {
|
||||
return Fedora{
|
||||
RedHatBase{
|
||||
Base{
|
||||
family: constant.Fedora,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: constant.Fedora,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
32
oval/suse.go
32
oval/suse.go
@@ -6,9 +6,11 @@ package oval
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
ovalmodels "github.com/vulsio/goval-dictionary/models"
|
||||
)
|
||||
|
||||
@@ -18,11 +20,13 @@ type SUSE struct {
|
||||
}
|
||||
|
||||
// NewSUSE creates OVAL client for SUSE
|
||||
func NewSUSE(cnf config.VulnDictInterface, family string) SUSE {
|
||||
func NewSUSE(driver ovaldb.DB, baseURL, family string) SUSE {
|
||||
// TODO implement other family
|
||||
return SUSE{
|
||||
Base{
|
||||
family: family,
|
||||
Cnf: cnf,
|
||||
driver: driver,
|
||||
baseURL: baseURL,
|
||||
family: family,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -30,23 +34,13 @@ func NewSUSE(cnf config.VulnDictInterface, family string) SUSE {
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o SUSE) FillWithOval(r *models.ScanResult) (nCVEs int, err error) {
|
||||
var relatedDefs ovalResult
|
||||
if o.Cnf.IsFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.Cnf.GetURL()); err != nil {
|
||||
return 0, err
|
||||
if o.driver == nil {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r, o.baseURL); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions via HTTP. err: %w", err)
|
||||
}
|
||||
} else {
|
||||
driver, err := newOvalDB(o.Cnf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(driver, r); err != nil {
|
||||
return 0, err
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(r, o.driver); err != nil {
|
||||
return 0, xerrors.Errorf("Failed to get Definitions from DB. err: %w", err)
|
||||
}
|
||||
}
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
|
||||
67
oval/util.go
67
oval/util.go
@@ -14,18 +14,20 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
apkver "github.com/knqyf263/go-apk-version"
|
||||
debver "github.com/knqyf263/go-deb-version"
|
||||
rpmver "github.com/knqyf263/go-rpm-version"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/constant"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
apkver "github.com/knqyf263/go-apk-version"
|
||||
debver "github.com/knqyf263/go-deb-version"
|
||||
rpmver "github.com/knqyf263/go-rpm-version"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"github.com/vulsio/goval-dictionary/db"
|
||||
ovaldb "github.com/vulsio/goval-dictionary/db"
|
||||
ovallog "github.com/vulsio/goval-dictionary/log"
|
||||
ovalmodels "github.com/vulsio/goval-dictionary/models"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type ovalResult struct {
|
||||
@@ -245,7 +247,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
|
||||
}
|
||||
}
|
||||
|
||||
func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDefs ovalResult, err error) {
|
||||
func getDefsByPackNameFromOvalDB(r *models.ScanResult, driver ovaldb.DB) (relatedDefs ovalResult, err error) {
|
||||
requests := []request{}
|
||||
for _, pack := range r.Packages {
|
||||
requests = append(requests, request{
|
||||
@@ -441,22 +443,22 @@ func lessThan(family, newVer string, packInOVAL ovalmodels.Package) (bool, error
|
||||
constant.Raspbian:
|
||||
vera, err := debver.NewVersion(newVer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("Failed to parse version. version: %s, err: %w", newVer, err)
|
||||
}
|
||||
verb, err := debver.NewVersion(packInOVAL.Version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("Failed to parse version. version: %s, err: %w", packInOVAL.Version, err)
|
||||
}
|
||||
return vera.LessThan(verb), nil
|
||||
|
||||
case constant.Alpine:
|
||||
vera, err := apkver.NewVersion(newVer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("Failed to parse version. version: %s, err: %w", newVer, err)
|
||||
}
|
||||
verb, err := apkver.NewVersion(packInOVAL.Version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, xerrors.Errorf("Failed to parse version. version: %s, err: %w", packInOVAL.Version, err)
|
||||
}
|
||||
return vera.LessThan(verb), nil
|
||||
|
||||
@@ -491,40 +493,49 @@ func rhelRebuildOSVersionToRHEL(ver string) string {
|
||||
}
|
||||
|
||||
// NewOVALClient returns a client for OVAL database
|
||||
func NewOVALClient(family string, cnf config.GovalDictConf) (Client, error) {
|
||||
func NewOVALClient(family string, cnf config.GovalDictConf, o logging.LogOpts) (Client, error) {
|
||||
if err := ovallog.SetLogger(o.LogToFile, o.LogDir, o.Debug, o.LogJSON); err != nil {
|
||||
return nil, xerrors.Errorf("Failed to set goval-dictionary logger. err: %w", err)
|
||||
}
|
||||
|
||||
driver, err := newOvalDB(&cnf)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("Failed to newOvalDB. err: %w", err)
|
||||
}
|
||||
|
||||
switch family {
|
||||
case constant.Debian, constant.Raspbian:
|
||||
return NewDebian(&cnf), nil
|
||||
return NewDebian(driver, cnf.GetURL()), nil
|
||||
case constant.Ubuntu:
|
||||
return NewUbuntu(&cnf), nil
|
||||
return NewUbuntu(driver, cnf.GetURL()), nil
|
||||
case constant.RedHat:
|
||||
return NewRedhat(&cnf), nil
|
||||
return NewRedhat(driver, cnf.GetURL()), nil
|
||||
case constant.CentOS:
|
||||
return NewCentOS(&cnf), nil
|
||||
return NewCentOS(driver, cnf.GetURL()), nil
|
||||
case constant.Alma:
|
||||
return NewAlma(&cnf), nil
|
||||
return NewAlma(driver, cnf.GetURL()), nil
|
||||
case constant.Rocky:
|
||||
return NewRocky(&cnf), nil
|
||||
return NewRocky(driver, cnf.GetURL()), nil
|
||||
case constant.Oracle:
|
||||
return NewOracle(&cnf), nil
|
||||
return NewOracle(driver, cnf.GetURL()), nil
|
||||
case constant.OpenSUSE:
|
||||
return NewSUSE(&cnf, constant.OpenSUSE), nil
|
||||
return NewSUSE(driver, cnf.GetURL(), constant.OpenSUSE), nil
|
||||
case constant.OpenSUSELeap:
|
||||
return NewSUSE(&cnf, constant.OpenSUSELeap), nil
|
||||
return NewSUSE(driver, cnf.GetURL(), constant.OpenSUSELeap), nil
|
||||
case constant.SUSEEnterpriseServer:
|
||||
return NewSUSE(&cnf, constant.SUSEEnterpriseServer), nil
|
||||
return NewSUSE(driver, cnf.GetURL(), constant.SUSEEnterpriseServer), nil
|
||||
case constant.SUSEEnterpriseDesktop:
|
||||
return NewSUSE(&cnf, constant.SUSEEnterpriseDesktop), nil
|
||||
return NewSUSE(driver, cnf.GetURL(), constant.SUSEEnterpriseDesktop), nil
|
||||
case constant.Alpine:
|
||||
return NewAlpine(&cnf), nil
|
||||
return NewAlpine(driver, cnf.GetURL()), nil
|
||||
case constant.Amazon:
|
||||
return NewAmazon(&cnf), nil
|
||||
return NewAmazon(driver, cnf.GetURL()), nil
|
||||
case constant.Fedora:
|
||||
return NewFedora(&cnf), nil
|
||||
return NewFedora(driver, cnf.GetURL()), nil
|
||||
case constant.FreeBSD, constant.Windows:
|
||||
return nil, nil
|
||||
return NewPseudo(family), nil
|
||||
case constant.ServerTypePseudo:
|
||||
return nil, nil
|
||||
return NewPseudo(family), nil
|
||||
default:
|
||||
if family == "" {
|
||||
return nil, xerrors.New("Probably an error occurred during scanning. Check the error message")
|
||||
|
||||
Reference in New Issue
Block a user