From 8b57851486c0ef9d88dec6ba67b23ae85caa73a4 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Mon, 18 Jul 2022 17:59:38 +0200 Subject: [PATCH] Moved direct loading of pmd from downloader to library. (#233) * Moved direct loading of pmd from downloader to library, so aggregator and checker gain the ability. * Disabled some checks if we were given a direct PMD URL. --- cmd/csaf_checker/processor.go | 37 +++++++++++++++++---- cmd/csaf_downloader/downloader.go | 54 +++---------------------------- csaf/util.go | 38 ++++++++++++++-------- docs/examples/aggregator.toml | 2 +- 4 files changed, 61 insertions(+), 70 deletions(-) diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index 5750f9d..11c73b0 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -215,20 +215,43 @@ func (p *processor) run(reporters []reporter, domains []string) (*Report, error) return &report, nil } -func (p *processor) checkDomain(domain string) error { +// domainChecks compiles a list of checks which should be performed +// for a given domain. +func (p *processor) domainChecks(domain string) []func(*processor, string) error { - // TODO: Implement me! - for _, check := range []func(*processor, string) error{ + // If we have a direct domain url we dont need to + // perform certain checks. + direct := strings.HasPrefix(domain, "https://") + + checks := []func(*processor, string) error{ (*processor).checkProviderMetadata, (*processor).checkPGPKeys, - (*processor).checkSecurity, + } + + if !direct { + checks = append(checks, (*processor).checkSecurity) + } + + checks = append(checks, (*processor).checkCSAFs, (*processor).checkMissing, (*processor).checkInvalid, (*processor).checkListing, - (*processor).checkWellknownMetadataReporter, - (*processor).checkDNSPathReporter, - } { + ) + + if !direct { + checks = append(checks, + (*processor).checkWellknownMetadataReporter, + (*processor).checkDNSPathReporter, + ) + } + + return checks +} + +func (p *processor) checkDomain(domain string) error { + + for _, check := range p.domainChecks(domain) { if err := check(p, domain); err != nil && err != errContinue { if err == errStop { return nil diff --git a/cmd/csaf_downloader/downloader.go b/cmd/csaf_downloader/downloader.go index d21a745..7f7d8db 100644 --- a/cmd/csaf_downloader/downloader.go +++ b/cmd/csaf_downloader/downloader.go @@ -85,57 +85,13 @@ func (d *downloader) httpClient() util.Client { return d.client } -func (d *downloader) loadProviderMetadataDirectly(path string) *csaf.LoadedProviderMetadata { - client := d.httpClient() - resp, err := client.Get(path) - if err != nil { - log.Printf("Error fetching '%s': %v\n", path, err) - return nil - } - if resp.StatusCode != http.StatusOK { - log.Printf( - "Error fetching '%s': %s (%d)\n", path, resp.Status, resp.StatusCode) - return nil - } - defer resp.Body.Close() - - var doc interface{} - if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil { - log.Printf("Decoding '%s' as JSON failed: %v\n", path, err) - return nil - } - - errors, err := csaf.ValidateProviderMetadata(doc) - if err != nil { - log.Printf("Schema validation of '%s' failed: %v\n", path, err) - return nil - } - - if len(errors) > 0 { - log.Printf( - "Schema validation of '%s' leads to %d issues.\n", path, len(errors)) - return nil - } - - return &csaf.LoadedProviderMetadata{ - Document: doc, - URL: path, - } -} - func (d *downloader) download(domain string) error { - var lpmd *csaf.LoadedProviderMetadata - - if strings.HasPrefix(domain, "https://") { - lpmd = d.loadProviderMetadataDirectly(domain) - } else { - lpmd = csaf.LoadProviderMetadataForDomain( - d.httpClient(), domain, func(format string, args ...interface{}) { - log.Printf( - "Looking for provider-metadata.json of '"+domain+"': "+format+"\n", args...) - }) - } + lpmd := csaf.LoadProviderMetadataForDomain( + d.httpClient(), domain, func(format string, args ...interface{}) { + log.Printf( + "Looking for provider-metadata.json of '"+domain+"': "+format+"\n", args...) + }) if lpmd == nil { return fmt.Errorf("no provider-metadata.json found for '%s'", domain) diff --git a/csaf/util.go b/csaf/util.go index c221f99..c5997ac 100644 --- a/csaf/util.go +++ b/csaf/util.go @@ -117,8 +117,10 @@ func LoadProviderMetadatasFromSecurity(client util.Client, path string) []*Loade } // LoadProviderMetadataForDomain loads a provider metadata for a given domain. -// Returns nil if no provider metadata was found. -// The logging can be use to track the errors happening while loading. +// Returns nil if no provider metadata (PMD) was found. +// If the domain starts with `https://` it only attemps to load +// the data from that URL. +// The logging can be used to track the errors happening while loading. func LoadProviderMetadataForDomain( client util.Client, domain string, @@ -131,22 +133,33 @@ func LoadProviderMetadataForDomain( } } + lg := func(result *LoadedProviderMetadata, url string) { + if result == nil { + logging("%s not found.", url) + } else { + for _, msg := range result.Messages { + logging(msg) + } + } + } + + // check direct path + if strings.HasPrefix(domain, "https://") { + result := LoadProviderMetadataFromURL(client, domain) + lg(result, domain) + return result + } + // Valid provider metadata under well-known. var wellknownGood *LoadedProviderMetadata // First try well-know path wellknownURL := "https://" + domain + "/.well-known/csaf/provider-metadata.json" wellknownResult := LoadProviderMetadataFromURL(client, wellknownURL) + lg(wellknownResult, wellknownURL) - if wellknownResult == nil { - logging("%s not found.", wellknownURL) - } else if len(wellknownResult.Messages) > 0 { - // There are issues - for _, msg := range wellknownResult.Messages { - logging(msg) - } - } else { - // We have a candidate. + // We have a candidate. + if wellknownResult != nil { wellknownGood = wellknownResult } @@ -207,8 +220,7 @@ func LoadProviderMetadataForDomain( return wellknownGood } - // Last resort fall back to DNS. - + // Last resort: fall back to DNS. dnsURL := "https://csaf.data.security." + domain dnsResult := LoadProviderMetadataFromURL(client, dnsURL) diff --git a/docs/examples/aggregator.toml b/docs/examples/aggregator.toml index 638c104..e7c0a77 100644 --- a/docs/examples/aggregator.toml +++ b/docs/examples/aggregator.toml @@ -28,7 +28,7 @@ insecure = true [[providers]] name = "local-dev-provider2" - domain = "localhost" + domain = "https://localhost:8443/.well-known/csaf/provider-metadata.json" # rate = 1.2 # insecure = true write_indices = true