Skip to content

Commit

Permalink
Merge pull request #473 from cintek/main
Browse files Browse the repository at this point in the history
Adding advisory model
  • Loading branch information
JanHoefelmeyer authored Oct 25, 2023
2 parents 455010d + 5215d78 commit 0905824
Show file tree
Hide file tree
Showing 9 changed files with 2,769 additions and 1 deletion.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Can be used for automated forwarding of CSAF documents.
### [csaf_validator](docs/csaf_validator.md)
is a tool to validate local advisories files against the JSON Schema and an optional remote validator.

### [csaf_searcher](docs/csaf_searcher.md)
is a tool to search through local advisories. It finds PURLs based on the product ID of an advisory.

## Tools for advisory providers

### [csaf_provider](docs/csaf_provider.md)
Expand Down Expand Up @@ -56,6 +59,12 @@ Download the binaries from the most recent release assets on Github.

Binaries will be placed in directories named like `bin-linux-amd64/` and `bin-windows-amd64/`.

- Maintainers only: No need to do this if you have cloned this repository for unmodified usage only.
```
go generate ./...
```
will update the machine generated code.


### Setup (Trusted Provider)

Expand Down
126 changes: 126 additions & 0 deletions cmd/csaf_searcher/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Package main implements a simple demo program to
// work with the csaf_distribution library.
package main

import (
"flag"
"fmt"
"log"
"os"
"slices"
"strings"

"github.com/csaf-poc/csaf_distribution/v3/csaf"
)

func main() {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(),
"Usage:\n %s [OPTIONS] files...\n\nOptions:\n", os.Args[0])
flag.PrintDefaults()
}
idsString := flag.String("p", "", "ID1,ID2,...")
flag.Parse()

files := flag.Args()
if len(files) == 0 {
log.Println("No files given.")
return
}
if err := run(files, *idsString); err != nil {
log.Fatalf("error: %v\n", err)
}
}

// run prints PURLs belonging to the given Product IDs.
func run(files []string, ids string) error {

uf := newURLFinder(strings.Split(ids, ","))

for _, file := range files {
adv, err := csaf.LoadAdvisory(file)
if err != nil {
return fmt.Errorf("loading %q failed: %w", file, err)
}
uf.findURLs(adv)
uf.dumpURLs()
uf.clear()
}

return nil
}

// urlFinder helps to find the URLs of a set of product ids in advisories.
type urlFinder struct {
ids []csaf.ProductID
urls [][]csaf.PURL
}

// newURLFinder creates a new urlFinder for given ids.
func newURLFinder(ids []string) *urlFinder {
uf := &urlFinder{
ids: make([]csaf.ProductID, len(ids)),
urls: make([][]csaf.PURL, len(ids)),
}
for i := range uf.ids {
uf.ids[i] = csaf.ProductID(ids[i])
}
return uf
}

// clear resets the url finder after a run on an advisory.
func (uf *urlFinder) clear() {
clear(uf.urls)
}

// dumpURLs dumps the found URLs to stdout.
func (uf *urlFinder) dumpURLs() {
for i, urls := range uf.urls {
if len(urls) == 0 {
continue
}
fmt.Printf("Found URLs for %s:\n", uf.ids[i])
for j, url := range urls {
fmt.Printf("%d. %s\n", j+1, url)
}
}
}

// findURLs find the URLs in an advisory.
func (uf *urlFinder) findURLs(adv *csaf.Advisory) {
tree := adv.ProductTree
if tree == nil {
return
}

// If we have found it and we have a valid URL add unique.
add := func(idx int, h *csaf.ProductIdentificationHelper) {
if idx != -1 && h != nil && h.PURL != nil &&
!slices.Contains(uf.urls[idx], *h.PURL) {
uf.urls[idx] = append(uf.urls[idx], *h.PURL)
}
}

// First iterate over full product names.
if names := tree.FullProductNames; names != nil {
for _, name := range *names {
if name != nil && name.ProductID != nil {
add(slices.Index(uf.ids, *name.ProductID), name.ProductIdentificationHelper)
}
}
}

// Second traverse the branches recursively.
var recBranch func(*csaf.Branch)
recBranch = func(b *csaf.Branch) {
if p := b.Product; p != nil && p.ProductID != nil {
add(slices.Index(uf.ids, *p.ProductID), p.ProductIdentificationHelper)
}
for _, c := range b.Branches {
recBranch(c)
}
}
for _, b := range tree.Branches {
recBranch(b)
}
}
Loading

0 comments on commit 0905824

Please sign in to comment.