From 70b4e18b583ba1cf3060f0cdda68deabfb8cda27 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Fri, 26 Aug 2022 16:53:18 +0200 Subject: [PATCH] Treat invalid PMDs as error and stop processing if needed * Improve how PMD validation result is used when searching for a valid PMD. We now stop if no PMD can be validated against the json schema. --- cmd/csaf_aggregator/processor.go | 4 ++-- cmd/csaf_checker/processor.go | 2 +- cmd/csaf_downloader/downloader.go | 4 ++-- csaf/util.go | 25 ++++++++++++++++++------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cmd/csaf_aggregator/processor.go b/cmd/csaf_aggregator/processor.go index 5ae4f667..f08436d8 100644 --- a/cmd/csaf_aggregator/processor.go +++ b/cmd/csaf_aggregator/processor.go @@ -85,8 +85,8 @@ func (w *worker) locateProviderMetadata(domain string) error { "Looking for provider-metadata.json of '"+domain+"': "+format+"\n", args...) }) - if lpmd == nil { - return fmt.Errorf("no provider-metadata.json found for '%s'", domain) + if !lpmd.Valid() { + return fmt.Errorf("no valid provider-metadata.json found for '%s'", domain) } w.metadataProvider = lpmd.Document diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index b66fd517..53993c04 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -1062,7 +1062,7 @@ func (p *processor) checkProviderMetadata(domain string) error { lpmd := csaf.LoadProviderMetadataForDomain(client, domain, p.badProviderMetadata.warn) - if lpmd == nil { + if !lpmd.Valid() { p.badProviderMetadata.error("No valid provider-metadata.json found.") p.badProviderMetadata.error("STOPPING here - cannot perform other checks.") return errStop diff --git a/cmd/csaf_downloader/downloader.go b/cmd/csaf_downloader/downloader.go index 69e3eb1e..eee9879e 100644 --- a/cmd/csaf_downloader/downloader.go +++ b/cmd/csaf_downloader/downloader.go @@ -93,8 +93,8 @@ func (d *downloader) download(domain string) error { "Looking for provider-metadata.json of '"+domain+"': "+format+"\n", args...) }) - if lpmd == nil { - return fmt.Errorf("no provider-metadata.json found for '%s'", domain) + if !lpmd.Valid() { + return fmt.Errorf("no valid provider-metadata.json found for '%s'", domain) } base, err := url.Parse(lpmd.URL) diff --git a/csaf/util.go b/csaf/util.go index c66c0210..adf41151 100644 --- a/csaf/util.go +++ b/csaf/util.go @@ -34,6 +34,11 @@ type LoadedProviderMetadata struct { Messages []string } +// Valid returns true if the loaded document is valid. +func (lpm *LoadedProviderMetadata) Valid() bool { + return lpm != nil && lpm.Document != nil && lpm.Hash != nil +} + // defaultLogging generates a logging function if given is nil. func defaultLogging( logging func(format string, args ...interface{}), @@ -80,15 +85,17 @@ func LoadProviderMetadataFromURL( tee := io.TeeReader(res.Body, hash) - err = json.NewDecoder(tee).Decode(&result.Document) + var doc interface{} + + err = json.NewDecoder(tee).Decode(&doc) // Before checking the err lets check if we had the same // document before. If so it will have failed parsing before. - result.Hash = hash.Sum(nil) + sum := hash.Sum(nil) var key string if already != nil { - key = string(result.Hash) + key = string(sum) if r, ok := already[key]; ok { return r } @@ -108,7 +115,7 @@ func LoadProviderMetadataFromURL( return &result } - switch errors, err := ValidateProviderMetadata(result.Document); { + switch errors, err := ValidateProviderMetadata(doc); { case err != nil: result.Messages = []string{ fmt.Sprintf("%s: Validating against JSON schema failed: %v", url, err)} @@ -119,6 +126,10 @@ func LoadProviderMetadataFromURL( for _, msg := range errors { result.Messages = append(result.Messages, strings.ReplaceAll(msg, `%`, `%%`)) } + default: + // Only store in result if validation passed. + result.Document = doc + result.Hash = sum } storeLoaded() @@ -164,7 +175,7 @@ func LoadProviderMetadatasFromSecurity( for _, url := range urls { if result := LoadProviderMetadataFromURL( client, url, already, logging, - ); result != nil { + ); result.Valid() { results = append(results, result) } } @@ -224,7 +235,7 @@ func LoadProviderMetadataForDomain( lg(wellknownResult, wellknownURL) // We have a candidate. - if wellknownResult != nil { + if wellknownResult.Valid() { wellknownGood = wellknownResult } @@ -233,7 +244,7 @@ func LoadProviderMetadataForDomain( secResults := LoadProviderMetadatasFromSecurity( client, secURL, already, logging) - if secResults == nil { + if len(secResults) == 0 { logging("%s failed to load.", secURL) } else { // Filter out the results which are valid.