1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 18:15:42 +01:00

Implemented changes.csv check.

This commit is contained in:
Sascha L. Teichmann 2021-12-16 01:17:23 +01:00
parent 57f8f06257
commit 8e16650512
2 changed files with 72 additions and 3 deletions

View file

@ -15,13 +15,16 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"crypto/tls" "crypto/tls"
"encoding/csv"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
"sort"
"strings" "strings"
"time"
"github.com/PaesslerAG/gval" "github.com/PaesslerAG/gval"
"github.com/PaesslerAG/jsonpath" "github.com/PaesslerAG/jsonpath"
@ -48,6 +51,7 @@ type processor struct {
badProviderMetadatas []string badProviderMetadatas []string
badSecurities []string badSecurities []string
badIndices []string badIndices []string
badChanges []string
builder gval.Language builder gval.Language
exprs map[string]gval.Evaluable exprs map[string]gval.Evaluable
@ -98,6 +102,7 @@ func (p *processor) clean() {
p.badProviderMetadatas = nil p.badProviderMetadatas = nil
p.badSecurities = nil p.badSecurities = nil
p.badIndices = nil p.badIndices = nil
p.badChanges = nil
} }
func (p *processor) run(reporters []reporter, domains []string) (*Report, error) { func (p *processor) run(reporters []reporter, domains []string) (*Report, error) {
@ -231,6 +236,10 @@ func (p *processor) badIndex(format string, args ...interface{}) {
p.badIndices = append(p.badIndices, fmt.Sprintf(format, args...)) p.badIndices = append(p.badIndices, fmt.Sprintf(format, args...))
} }
func (p *processor) badChange(format string, args ...interface{}) {
p.badChanges = append(p.badChanges, fmt.Sprintf(format, args...))
}
func (p *processor) integrity( func (p *processor) integrity(
files []string, files []string,
base string, base string,
@ -419,6 +428,10 @@ func (p *processor) processFeed(feed string) error {
return err return err
} }
if err := p.checkChanges(base, rolieChangesMask); err != nil && err != errContinue {
return err
}
return nil return nil
} }
@ -454,6 +467,59 @@ func (p *processor) checkIndex(base string, mask byte) error {
return p.integrity(files, base, mask, p.badIndex) return p.integrity(files, base, mask, p.badIndex)
} }
func (p *processor) checkChanges(base string, mask byte) error {
client := p.httpClient()
changes := base + "/changes.csv"
p.checkTLS(changes)
res, err := client.Get(changes)
if err != nil {
p.badChange("Fetching %s failed: %v", changes, err)
return errContinue
}
if res.StatusCode != http.StatusOK {
p.badChange("Fetching %s failed. Status code %d (%s)",
changes, res.StatusCode, res.Status)
return errContinue
}
times, files, err := func() ([]time.Time, []string, error) {
defer res.Body.Close()
var times []time.Time
var files []string
c := csv.NewReader(res.Body)
for {
r, err := c.Read()
if err == io.EOF {
break
}
if err != nil {
return nil, nil, err
}
if len(r) < 2 {
return nil, nil, errors.New("not enough columns")
}
t, err := time.Parse(time.RFC3339, r[0])
if err != nil {
return nil, nil, err
}
times, files = append(times, t), append(files, r[1])
}
return times, files, nil
}()
if err != nil {
p.badChange("Reading %s failed: %v", changes, err)
return errContinue
}
if !sort.SliceIsSorted(times, func(i, j int) bool {
return times[j].Before(times[i])
}) {
p.badChange("%s is not sorted in descending order", changes)
}
return p.integrity(files, base, mask, p.badChange)
}
func (p *processor) processFeeds(domain string, feeds [][]csaf.Feed) error { func (p *processor) processFeeds(domain string, feeds [][]csaf.Feed) error {
base, err := url.Parse("https://" + domain + "/.well-known/csaf/") base, err := url.Parse("https://" + domain + "/.well-known/csaf/")

View file

@ -125,10 +125,13 @@ func (r *indexReporter) report(p *processor, domain *Domain) {
req.Messages = p.badIndices req.Messages = p.badIndices
} }
func (r *changesReporter) report(_ *processor, domain *Domain) { func (r *changesReporter) report(p *processor, domain *Domain) {
// TODO: Implement me!
req := r.requirement(domain) req := r.requirement(domain)
_ = req if len(p.badChanges) == 0 {
req.message("No problems with changes.txt found.")
return
}
req.Messages = p.badChanges
} }
func (r *directoryListingsReporter) report(_ *processor, domain *Domain) { func (r *directoryListingsReporter) report(_ *processor, domain *Domain) {