From 9adab139482a3da43f60115439f63b66286f0d70 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Wed, 12 Jan 2022 19:48:33 +0100 Subject: [PATCH] Do not report success on checks which were not performed. Second part of the Fix of issue #24. --- cmd/csaf_checker/processor.go | 48 +++++++++++++++++++++++++++-------- cmd/csaf_checker/reporters.go | 36 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index ce5b4e8..3e8d403 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -107,8 +107,6 @@ func (wt whereType) String() string { func newProcessor(opts *options) *processor { return &processor{ opts: opts, - redirects: map[string]string{}, - noneTLS: map[string]struct{}{}, alreadyChecked: map[string]whereType{}, builder: gval.Full(jsonpath.Language()), exprs: map[string]gval.Evaluable{}, @@ -116,12 +114,8 @@ func newProcessor(opts *options) *processor { } func (p *processor) clean() { - for k := range p.redirects { - delete(p.redirects, k) - } - for k := range p.noneTLS { - delete(p.noneTLS, k) - } + p.redirects = nil + p.noneTLS = nil for k := range p.alreadyChecked { delete(p.alreadyChecked, k) } @@ -137,16 +131,14 @@ func (p *processor) clean() { p.badIndices = nil p.badChanges = nil } - func (p *processor) run(reporters []reporter, domains []string) (*Report, error) { var report Report -domainsLoop: for _, d := range domains { if err := p.checkDomain(d); err != nil { if err == errContinue || err == errStop { - continue domainsLoop + continue } return nil, err } @@ -198,6 +190,9 @@ func (p *processor) jsonPath(expr string, doc interface{}) (interface{}, error) } func (p *processor) checkTLS(u string) { + if p.noneTLS == nil { + p.noneTLS = map[string]struct{}{} + } if x, err := url.Parse(u); err == nil && x.Scheme != "https" { p.noneTLS[u] = struct{}{} } @@ -220,6 +215,9 @@ func (p *processor) checkRedirect(r *http.Request, via []*http.Request) error { } url := r.URL.String() p.checkTLS(url) + if p.redirects == nil { + p.redirects = map[string]string{} + } p.redirects[url] = path.String() if len(via) > 10 { @@ -249,6 +247,16 @@ func (p *processor) httpClient() *http.Client { return p.client } +func use(s *[]string) { + if *s == nil { + *s = []string{} + } +} + +func used(s []string) bool { + return s != nil +} + func (p *processor) badIntegrity(format string, args ...interface{}) { p.badIntegrities = append(p.badIntegrities, fmt.Sprintf(format, args...)) } @@ -345,6 +353,8 @@ func (p *processor) integrity( } // Check if file is in the right folder. + use(&p.badFolders) + if date, err := p.jsonPath( `$.document.tracking.initial_release_date`, doc); err != nil { p.badFolder( @@ -361,6 +371,8 @@ func (p *processor) integrity( } // Check hashes + use(&p.badIntegrities) + for _, x := range []struct { ext string hash []byte @@ -401,6 +413,8 @@ func (p *processor) integrity( sigFile := u + ".asc" p.checkTLS(sigFile) + use(&p.badSignatures) + if res, err = client.Get(sigFile); err != nil { p.badSignature("Fetching %s failed: %v.", sigFile, err) continue @@ -498,6 +512,9 @@ func (p *processor) checkIndex(base string, mask whereType) error { client := p.httpClient() index := base + "/index.txt" p.checkTLS(index) + + use(&p.badIndices) + res, err := client.Get(index) if err != nil { p.badIndex("Fetching %s failed: %v", index, err) @@ -534,6 +551,9 @@ func (p *processor) checkChanges(base string, mask whereType) error { changes := base + "/changes.csv" p.checkTLS(changes) res, err := client.Get(changes) + + use(&p.badChanges) + if err != nil { p.badChange("Fetching %s failed: %v", changes, err) return errContinue @@ -687,6 +707,8 @@ func (p *processor) checkProviderMetadata(domain string) error { url := "https://" + domain + "/.well-known/csaf/provider-metadata.json" + use(&p.badProviderMetadatas) + res, err := client.Get(url) if err != nil { p.badProviderMetadata("Fetching %s: %v.", url, err) @@ -730,6 +752,8 @@ func (p *processor) checkSecurity(domain string) error { client := p.httpClient() + use(&p.badSecurities) + path := "https://" + domain + "/.well-known/security.txt" res, err := client.Get(path) if err != nil { @@ -804,6 +828,8 @@ func (p *processor) checkSecurity(domain string) error { func (p *processor) checkPGPKeys(domain string) error { + use(&p.badPGPs) + src, err := p.jsonPath("$.pgp_keys", p.pmd) if err != nil { p.badPGP("No PGP keys found: %v.", err) diff --git a/cmd/csaf_checker/reporters.go b/cmd/csaf_checker/reporters.go index 3b3999f..173c84b 100644 --- a/cmd/csaf_checker/reporters.go +++ b/cmd/csaf_checker/reporters.go @@ -44,6 +44,10 @@ func (bc *baseReporter) requirement(domain *Domain) *Requirement { func (r *tlsReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if p.noneTLS == nil { + req.message("No TLS checks performed.") + return + } if len(p.noneTLS) == 0 { req.message("All tested URLs were https.") return @@ -82,6 +86,10 @@ func (r *redirectsReporter) report(p *processor, domain *Domain) { func (r *providerMetadataReport) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badProviderMetadatas) { + req.message("No provider-metadata.json checked.") + return + } if len(p.badProviderMetadatas) == 0 { req.message("No problems with provider metadata.") return @@ -91,6 +99,10 @@ func (r *providerMetadataReport) report(p *processor, domain *Domain) { func (r *securityReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badSecurities) { + req.message("No security.txt checked.") + return + } if len(p.badSecurities) == 0 { req.message("No problems with security.txt found.") return @@ -112,6 +124,10 @@ func (r *dnsPathReporter) report(_ *processor, domain *Domain) { func (r *oneFolderPerYearReport) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badFolders) { + req.message("No checks if file are in right folders were performed.") + return + } if len(p.badFolders) == 0 { req.message("All CSAF files are in the right folders.") return @@ -121,6 +137,10 @@ func (r *oneFolderPerYearReport) report(p *processor, domain *Domain) { func (r *indexReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badIndices) { + req.message("No index.txt checked.") + return + } if len(p.badIndices) == 0 { req.message("No problems with index.txt found.") return @@ -130,6 +150,10 @@ func (r *indexReporter) report(p *processor, domain *Domain) { func (r *changesReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badChanges) { + req.message("No changes.csv checked.") + return + } if len(p.badChanges) == 0 { req.message("No problems with changes.csv found.") return @@ -145,6 +169,10 @@ func (r *directoryListingsReporter) report(_ *processor, domain *Domain) { func (r *integrityReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badIntegrities) { + req.message("No checksums checked.") + return + } if len(p.badIntegrities) == 0 { req.message("All checksums match.") return @@ -154,6 +182,10 @@ func (r *integrityReporter) report(p *processor, domain *Domain) { func (r *signaturesReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badSignatures) { + req.message("No signatures checked.") + return + } req.Messages = p.badSignatures if len(p.badSignatures) == 0 { req.message("All signatures verified.") @@ -162,6 +194,10 @@ func (r *signaturesReporter) report(p *processor, domain *Domain) { func (r *publicPGPKeyReporter) report(p *processor, domain *Domain) { req := r.requirement(domain) + if !used(p.badPGPs) { + req.message("No PGP keys loaded.") + return + } req.Messages = p.badPGPs if len(p.keys) > 0 { req.message(fmt.Sprintf("%d PGP key(s) loaded successfully.", len(p.keys)))