Skip to content
Open
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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A [Claircore](https://github.com/quay/claircore)-based CVE manager (see also [cl

# Build

Install Go development tools and libraries (`goland`) and GNU `make`.
Install Go development tools and libraries (`golang`) and GNU `make`.
Run
```
$ make build
Expand All @@ -20,22 +20,22 @@ and filled with CVE records.

Run
```
$ ./cvetool update --db-path=./matcher.db
$ ./cvetool update
```
to create or update the DB (SQLite).

The `--db-path` argument is the path to the database location.

> [!IMPORTANT]
> If the parameter is omitted the tool creates ephemeral (in-memory) database, which will be discarded after the tool finishes its job.
> [!NOTE]
> If the parameter is omitted the tool creates database for the user in `~/.local/share/cvetool/matcher.db`.

The initial update procedure could take up to 30 minutes. Further incremental updates will be significantly faster.

## Scan Local System

Run
```
$ ./cvetool report --root-path=/ --db-path=./matcher.db
$ ./cvetool scan --root-path=/
```
to scan the underlying system and generate vulnerabilities report.

Expand All @@ -49,15 +49,15 @@ The `--root-path` argument defines root directory of the target file system.

Run
```
$ ./cvetool report --image-path=./rhel-10-ubi.tar --db-path=./matcher.db
$ ./cvetool scan --image-path=./rhel-10-ubi.tar
```
to scan a `podman/docker image save ...`-compatible `.tar` image and generate vulnerabilities report.

## Scan a Remote Container Image

Run
```
$ ./cvetool report --image-ref=registry.access.redhat.com/ubi10/ubi --db-path=./matcher.db
$ ./cvetool scan --image-ref=registry.access.redhat.com/ubi10/ubi
```
to pull and scan an image from a repository and generate vulnerabilities report.

Expand All @@ -69,7 +69,7 @@ Run
```
$ mkdir -p ./rhel10-vm
$ guestmount -a ~/.local/share/gnome-boxes/images/rhel10.0 -i --ro ./rhel10-vm
$ ./cvetool report --root-path=./rhel10-vm --db-path=./matcher.db
$ ./cvetool scan --root-path=./rhel10-vm --db-path=./matcher.db
```
to mount the file system, scan and generate vulnerabilities report.

Expand Down
3 changes: 1 addition & 2 deletions cmd/cvetool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ func main() {
},

Commands: []*cli.Command{
reportCmd,
scanCmd,
updateCmd,
convertCmd,
},
Flags: []cli.Flag{
&cli.StringFlag{
Expand Down
55 changes: 25 additions & 30 deletions cmd/cvetool/report.go → cmd/cvetool/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,20 @@ import (
output "github.com/ComplianceAsCode/cvetool/output"
)

var defaultDBPath = filepath.Join(os.TempDir(), "matcher.db")

type EnumValue struct {
Enum []string
Default string
selected string
}

func getDefaultDBPath() (string, error) {
homeFolder, err := os.UserHomeDir()
if err != nil || homeFolder == "" {
return "", fmt.Errorf("home folder not set, DB path must be specified")
}
return filepath.Join(homeFolder, ".local", "share", "cvetool", "matcher.db"), nil
}

func (e *EnumValue) Set(value string) error {
if slices.Contains(e.Enum, value) {
e.selected = value
Expand All @@ -59,15 +65,15 @@ const (
plainFmt = "plain"
)

var reportCmd = &cli.Command{
Name: "report",
Aliases: []string{"r"},
Usage: "report on a manifest",
Action: report,
var scanCmd = &cli.Command{
Name: "scan",
Aliases: []string{"s"},
Usage: "scan a system",
Action: scan,
Flags: []cli.Flag{
&cli.PathFlag{
Name: "root-path",
Value: "",
Value: "/",
Usage: "where to look for the local filesystem root",
EnvVars: []string{"ROOT_PATH"},
},
Expand All @@ -83,18 +89,6 @@ var reportCmd = &cli.Command{
Usage: "where to look for the matcher DB",
EnvVars: []string{"DB_PATH"},
},
&cli.StringFlag{
Name: "image-ref",
Value: "",
Usage: "the remote location of the image",
EnvVars: []string{"IMAGE_REF"},
},
&cli.StringFlag{
Name: "db-url",
Value: "",
Usage: "the remote location of the sqlite zstd DB",
EnvVars: []string{"DB_URL"},
},
&cli.GenericFlag{
Name: "format",
Aliases: []string{"f"},
Expand All @@ -112,16 +106,10 @@ var reportCmd = &cli.Command{
Usage: "what status code to return when vulnerabilites are found",
EnvVars: []string{"RETURN_CODE"},
},
&cli.StringFlag{
Name: "docker-config-dir",
Value: "",
Usage: "Docker config dir for the image registry where --image-ref is stored",
EnvVars: []string{"DOCKER_CONFIG_DIR"},
},
},
}

func report(c *cli.Context) error {
func scan(c *cli.Context) error {
ctx := c.Context

var (
Expand Down Expand Up @@ -170,14 +158,21 @@ func report(c *cli.Context) error {
switch {
case dbPath != "":
case dbURL != "":
dbPath = defaultDBPath
var err error
err = datastore.DownloadDB(ctx, dbURL, defaultDBPath)
err = datastore.DownloadDB(ctx, dbURL, "")
if err != nil {
return fmt.Errorf("could not download database: %v", err)
}
default:
return fmt.Errorf("no $DB_PATH / --db-path or $DB_URL / --db-url set")
var err error
dbPath, err = getDefaultDBPath()
if err != nil {
return err
}
}

if _, err := os.Stat(dbPath); err != nil {
return fmt.Errorf("unable to get database path")
}

matcherStore, err := datastore.NewSQLiteMatcherStore(dbPath, true)
Expand Down
15 changes: 15 additions & 0 deletions cmd/cvetool/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"fmt"
"net/http"
"os"
"path/filepath"
"time"

"github.com/ComplianceAsCode/cvetool/datastore"
Expand All @@ -29,6 +31,19 @@ var updateCmd = &cli.Command{
func update(c *cli.Context) error {
ctx := c.Context
dbPath := c.String("db-path")
if dbPath == "" {
var err error
dbPath, err = getDefaultDBPath()
if err != nil {
return err
}
if _, err := os.Stat(dbPath); err != nil {
dbDirPath := filepath.Dir(dbPath)
if err := os.MkdirAll(dbDirPath, 0755); err != nil {
return fmt.Errorf("unable to create database path, %s", err)
}
}
}
matcherStore, err := datastore.NewSQLiteMatcherStore(dbPath, true)
if err != nil {
return fmt.Errorf("error creating sqlite backend: %v", err)
Expand Down