Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: select advisories #406

Merged
merged 2 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ Select from DB where package name is golang.

<details>
<summary>
`$ goval-dictionary select --by-package redhat 7 golang x86_64`
`$ goval-dictionary select package redhat 7 golang`
</summary>

```bash
$ goval-dictionary select --by-package redhat 7 golang x86_64
$ goval-dictionary select package redhat 7 golang
[Apr 10 10:22:43] INFO Opening DB (sqlite3).
CVE-2015-5739
{3399 319 golang 0:1.6.3-1.el7_2.1}
Expand Down Expand Up @@ -422,7 +422,7 @@ CVE-YYYY-NNNN
</summary>

```bash
$ goval-dictionary select --by-cveid redhat 7 CVE-2017-6009
$ goval-dictionary select cve-id redhat 7 CVE-2017-6009
[Apr 12 12:12:36] INFO Opening DB (sqlite3).
RHSA-2017:0837: icoutils security update (Important)
Important
Expand Down Expand Up @@ -625,6 +625,37 @@ Upper part format:
```
</details>

### Usage: select advisories

<details>
<summary>
`Select Advisories from DB`
</summary>

```bash
$ goval-dictionary select advisories redhat 9
map[string][]string{
"RHSA-2023:6482": []string{
"CVE-2023-35789",
},
"RHSA-2022:8418": []string{
"CVE-2021-28153",
},
"RHSA-2024:0811": []string{
"CVE-2023-28486",
"CVE-2023-28487",
"CVE-2023-42465",
"CVE-2023-28486",
"CVE-2023-28487",
"CVE-2023-42465",
"CVE-2023-28486",
"CVE-2023-28487",
"CVE-2023-42465",
},
...
}
```

### Usage: Start goval-dictionary as server mode

```bash
Expand Down
248 changes: 134 additions & 114 deletions commands/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/vulsio/goval-dictionary/config"
"github.com/vulsio/goval-dictionary/db"
"github.com/vulsio/goval-dictionary/log"
"github.com/vulsio/goval-dictionary/models"
)

Expand All @@ -19,124 +18,145 @@ var selectCmd = &cobra.Command{
Use: "select",
Short: "Select from DB",
Long: `Select from DB`,
RunE: executeSelect,
}

func init() {
RootCmd.AddCommand(selectCmd)

selectCmd.PersistentFlags().Bool("by-package", false, "select OVAL by package name")
_ = viper.BindPFlag("by-package", selectCmd.PersistentFlags().Lookup("by-package"))
selectCmd.AddCommand(
&cobra.Command{
Use: "package <family> <release> <package name> (<arch>)",
Short: "Select OVAL by package name",
Args: cobra.RangeArgs(3, 4),
RunE: func(_ *cobra.Command, args []string) error {
arch := ""
if len(args) == 4 {
switch args[0] {
case config.Amazon, config.Oracle, config.Fedora:
arch = args[3]
default:
return xerrors.Errorf("Family: %s cannot use the Architecture argument.", args[0])
}
}

selectCmd.PersistentFlags().Bool("by-cveid", false, "select OVAL by CVE-ID")
_ = viper.BindPFlag("by-cveid", selectCmd.PersistentFlags().Lookup("by-cveid"))
}
driver, err := db.NewDB(viper.GetString("dbtype"), viper.GetString("dbpath"), viper.GetBool("debug-sql"), db.Option{})
if err != nil {
if xerrors.Is(err, db.ErrDBLocked) {
return xerrors.Errorf("Failed to open DB. Close DB connection before fetching. err: %w", err)
}
return xerrors.Errorf("Failed to open DB. err: %w", err)
}

fetchMeta, err := driver.GetFetchMeta()
if err != nil {
return xerrors.Errorf("Failed to get FetchMeta from DB. err: %w", err)
}
if fetchMeta.OutDated() {
return xerrors.Errorf("Failed to select command. err: SchemaVersion is old. SchemaVersion: %+v", map[string]uint{"latest": models.LatestSchemaVersion, "DB": fetchMeta.SchemaVersion})
}

dfs, err := driver.GetByPackName(args[0], args[1], args[2], arch)
if err != nil {
return xerrors.Errorf("Failed to get cve by package. err: %w", err)
}

for _, d := range dfs {
for _, cve := range d.Advisory.Cves {
fmt.Printf("%s\n", cve.CveID)
for _, pack := range d.AffectedPacks {
fmt.Printf(" %v\n", pack)
}
}
}
fmt.Println("------------------")
pp.ColoringEnabled = false
_, _ = pp.Println(dfs)

return nil
},
Example: `$ goval-dictionary select package ubuntu 24.04 bash
$ goval-dictionary select package oracle 9 bash x86_64`,
},
&cobra.Command{
Use: "cve-id <family> <release> <cve id> (<arch>)",
Short: "Select OVAL by CVE-ID",
Args: cobra.RangeArgs(3, 4),
RunE: func(_ *cobra.Command, args []string) error {
arch := ""
if len(args) == 4 {
switch args[0] {
case config.Amazon, config.Oracle, config.Fedora:
arch = args[3]
default:
return xerrors.Errorf("Family: %s cannot use the Architecture argument.", args[0])
}
}

driver, err := db.NewDB(viper.GetString("dbtype"), viper.GetString("dbpath"), viper.GetBool("debug-sql"), db.Option{})
if err != nil {
if xerrors.Is(err, db.ErrDBLocked) {
return xerrors.Errorf("Failed to open DB. Close DB connection before fetching. err: %w", err)
}
return xerrors.Errorf("Failed to open DB. err: %w", err)
}

fetchMeta, err := driver.GetFetchMeta()
if err != nil {
return xerrors.Errorf("Failed to get FetchMeta from DB. err: %w", err)
}
if fetchMeta.OutDated() {
return xerrors.Errorf("Failed to select command. err: SchemaVersion is old. SchemaVersion: %+v", map[string]uint{"latest": models.LatestSchemaVersion, "DB": fetchMeta.SchemaVersion})
}

dfs, err := driver.GetByCveID(args[0], args[1], args[2], arch)
if err != nil {
return xerrors.Errorf("Failed to get cve by cveID. err: %w", err)
}
for _, d := range dfs {
fmt.Printf("%s\n", d.Title)
fmt.Printf("%v\n", d.Advisory.Cves)
}
fmt.Println("------------------")
pp.ColoringEnabled = false
_, _ = pp.Println(dfs)

return nil
},
Example: `$ goval-dictionary select cve-id ubuntu 24.04 CVE-2024-6387
$ goval-dictionary select cve-id oracle 9 CVE-2024-6387 x86_64`,
},
&cobra.Command{
Use: "advisories <family> <release>",
Short: "List Advisories and Releated CVE-IDs",
Args: cobra.ExactArgs(2),
RunE: func(_ *cobra.Command, args []string) error {
driver, err := db.NewDB(viper.GetString("dbtype"), viper.GetString("dbpath"), viper.GetBool("debug-sql"), db.Option{})
if err != nil {
if xerrors.Is(err, db.ErrDBLocked) {
return xerrors.Errorf("Failed to open DB. Close DB connection before fetching. err: %w", err)
}
return xerrors.Errorf("Failed to open DB. err: %w", err)
}

fetchMeta, err := driver.GetFetchMeta()
if err != nil {
return xerrors.Errorf("Failed to get FetchMeta from DB. err: %w", err)
}
if fetchMeta.OutDated() {
return xerrors.Errorf("Failed to select command. err: SchemaVersion is old. SchemaVersion: %+v", map[string]uint{"latest": models.LatestSchemaVersion, "DB": fetchMeta.SchemaVersion})
}

m, err := driver.GetAdvisories(args[0], args[1])
if err != nil {
return xerrors.Errorf("Failed to get cve by cveID. err: %w", err)
}
pp.ColoringEnabled = false
_, _ = pp.Println(m)

return nil
},
Example: `$ goval-dictionary select advisories ubuntu 24.04`,
},
)

func executeSelect(_ *cobra.Command, args []string) error {
if err := log.SetLogger(viper.GetBool("log-to-file"), viper.GetString("log-dir"), viper.GetBool("debug"), viper.GetBool("log-json")); err != nil {
return xerrors.Errorf("Failed to SetLogger. err: %w", err)
}

flagPkg := viper.GetBool("by-package")
flagCveID := viper.GetBool("by-cveid")

if (!flagPkg && !flagCveID) || (flagPkg && flagCveID) {
return xerrors.New("Failed to select command. err: specify --by-package or --by-cveid")
}

if len(args) < 3 {
if flagPkg {
return xerrors.Errorf(`
Usage:
select OVAL by package name
$ goval-dictionary select --by-package [osFamily] [osVersion] [Package Name] [Optional: Architecture (Oracle, Amazon Only)]
`)
}
if flagCveID {
return xerrors.Errorf(`
Usage:
select OVAL by CVE-ID
$ goval-dictionary select --by-cveid [osFamily] [osVersion] [CVE-ID] [Optional: Architecture (Oracle, Amazon Only)]
`)
}
} else if len(args) > 4 {
if flagPkg {
return xerrors.Errorf(`
Usage:
select OVAL by package name
$ goval-dictionary select --by-package [osFamily] [osVersion] [Package Name] [Optional: Architecture (Oracle, Amazon Only)]
`)
}
if flagCveID {
return xerrors.Errorf(`
Usage:
select OVAL by CVE-ID
$ goval-dictionary select --by-cveid [osFamily] [osVersion] [CVE-ID] [Optional: Architecture (Oracle, Amazon Only)]
`)
}
}

family := args[0]
release := args[1]
arg := args[2]
arch := ""
if len(args) == 4 {
switch family {
case config.Amazon, config.Oracle, config.Fedora:
arch = args[3]
default:
return xerrors.Errorf("Family: %s cannot use the Architecture argument.", family)
}
}

driver, err := db.NewDB(viper.GetString("dbtype"), viper.GetString("dbpath"), viper.GetBool("debug-sql"), db.Option{})
if err != nil {
if xerrors.Is(err, db.ErrDBLocked) {
return xerrors.Errorf("Failed to open DB. Close DB connection before fetching. err: %w", err)
}
return xerrors.Errorf("Failed to open DB. err: %w", err)
}

fetchMeta, err := driver.GetFetchMeta()
if err != nil {
return xerrors.Errorf("Failed to get FetchMeta from DB. err: %w", err)
}
if fetchMeta.OutDated() {
return xerrors.Errorf("Failed to select command. err: SchemaVersion is old. SchemaVersion: %+v", map[string]uint{"latest": models.LatestSchemaVersion, "DB": fetchMeta.SchemaVersion})
}

if flagPkg {
dfs, err := driver.GetByPackName(family, release, arg, arch)
if err != nil {
return xerrors.Errorf("Failed to get cve by package. err: %w", err)
}

for _, d := range dfs {
for _, cve := range d.Advisory.Cves {
fmt.Printf("%s\n", cve.CveID)
for _, pack := range d.AffectedPacks {
fmt.Printf(" %v\n", pack)
}
}
}
fmt.Println("------------------")
pp.ColoringEnabled = false
_, _ = pp.Println(dfs)
}

if flagCveID {
dfs, err := driver.GetByCveID(family, release, arg, arch)
if err != nil {
return xerrors.Errorf("Failed to get cve by cveID. err: %w", err)
}
for _, d := range dfs {
fmt.Printf("%s\n", d.Title)
fmt.Printf("%v\n", d.Advisory.Cves)
}
fmt.Println("------------------")
pp.ColoringEnabled = false
_, _ = pp.Println(dfs)
}

return nil
}
1 change: 1 addition & 0 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type DB interface {

GetByPackName(family string, osVer string, packName string, arch string) ([]models.Definition, error)
GetByCveID(family string, osVer string, cveID string, arch string) ([]models.Definition, error)
GetAdvisories(family string, osVer string) (map[string][]string, error)
InsertOval(*models.Root) error
CountDefs(string, string) (int, error)
GetLastModified(string, string) (time.Time, error)
Expand Down
Loading
Loading