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:
parent
57f8f06257
commit
8e16650512
2 changed files with 72 additions and 3 deletions
|
|
@ -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/")
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue