mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 18:15:42 +01:00
Merge pull request #254 from csaf-poc/dedup-pmd-loading-error-checking
Avoid duplicate errors checking and logging when loading pmds.
This commit is contained in:
commit
52724d0a4a
1 changed files with 61 additions and 24 deletions
81
csaf/util.go
81
csaf/util.go
|
|
@ -36,7 +36,11 @@ type LoadedProviderMetadata struct {
|
||||||
|
|
||||||
// LoadProviderMetadataFromURL loads a provider metadata from a given URL.
|
// LoadProviderMetadataFromURL loads a provider metadata from a given URL.
|
||||||
// Returns nil if the document was not found.
|
// Returns nil if the document was not found.
|
||||||
func LoadProviderMetadataFromURL(client util.Client, url string) *LoadedProviderMetadata {
|
func LoadProviderMetadataFromURL(
|
||||||
|
client util.Client,
|
||||||
|
url string,
|
||||||
|
already map[string]*LoadedProviderMetadata,
|
||||||
|
) *LoadedProviderMetadata {
|
||||||
|
|
||||||
res, err := client.Get(url)
|
res, err := client.Get(url)
|
||||||
|
|
||||||
|
|
@ -56,21 +60,40 @@ func LoadProviderMetadataFromURL(client util.Client, url string) *LoadedProvider
|
||||||
|
|
||||||
tee := io.TeeReader(res.Body, hash)
|
tee := io.TeeReader(res.Body, hash)
|
||||||
|
|
||||||
if err := json.NewDecoder(tee).Decode(&result.Document); err != nil {
|
err = json.NewDecoder(tee).Decode(&result.Document)
|
||||||
result.Messages = []string{fmt.Sprintf("%s: Decoding JSON failed: %v", url, err)}
|
// Before checking the err lets check if we had the same
|
||||||
return &result
|
// document before. If so it will have failed parsing before.
|
||||||
}
|
|
||||||
|
|
||||||
result.Hash = hash.Sum(nil)
|
result.Hash = hash.Sum(nil)
|
||||||
|
|
||||||
errors, err := ValidateProviderMetadata(result.Document)
|
var key string
|
||||||
|
if already != nil {
|
||||||
|
key = string(result.Hash)
|
||||||
|
if r, ok := already[key]; ok {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write it back as loaded
|
||||||
|
storeLoaded := func() {
|
||||||
|
if already != nil {
|
||||||
|
already[key] = &result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have loaded it the first time.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Messages = []string{
|
result.Messages = []string{fmt.Sprintf("%s: Decoding JSON failed: %v", url, err)}
|
||||||
fmt.Sprintf("%s: Validating against JSON schema failed: %v", url, err)}
|
storeLoaded()
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
switch errors, err := ValidateProviderMetadata(result.Document); {
|
||||||
|
case err != nil:
|
||||||
|
result.Messages = []string{
|
||||||
|
fmt.Sprintf("%s: Validating against JSON schema failed: %v", url, err)}
|
||||||
|
|
||||||
|
case len(errors) > 0:
|
||||||
result.Messages = []string{
|
result.Messages = []string{
|
||||||
fmt.Sprintf("%s: Validating against JSON schema failed: %v", url, err)}
|
fmt.Sprintf("%s: Validating against JSON schema failed: %v", url, err)}
|
||||||
for _, msg := range errors {
|
for _, msg := range errors {
|
||||||
|
|
@ -78,13 +101,18 @@ func LoadProviderMetadataFromURL(client util.Client, url string) *LoadedProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storeLoaded()
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadProviderMetadatasFromSecurity loads a secturity.txt,
|
// LoadProviderMetadatasFromSecurity loads a secturity.txt,
|
||||||
// extracts and the CSAF urls from the document.
|
// extracts and the CSAF urls from the document.
|
||||||
// Returns nil if no url was successfully found.
|
// Returns nil if no url was successfully found.
|
||||||
func LoadProviderMetadatasFromSecurity(client util.Client, path string) []*LoadedProviderMetadata {
|
func LoadProviderMetadatasFromSecurity(
|
||||||
|
client util.Client,
|
||||||
|
path string,
|
||||||
|
already map[string]*LoadedProviderMetadata,
|
||||||
|
) []*LoadedProviderMetadata {
|
||||||
|
|
||||||
res, err := client.Get(path)
|
res, err := client.Get(path)
|
||||||
|
|
||||||
|
|
@ -108,7 +136,7 @@ func LoadProviderMetadatasFromSecurity(client util.Client, path string) []*Loade
|
||||||
|
|
||||||
// Load the URLs
|
// Load the URLs
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
if result := LoadProviderMetadataFromURL(client, url); result != nil {
|
if result := LoadProviderMetadataFromURL(client, url, already); result != nil {
|
||||||
results = append(results, result)
|
results = append(results, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,23 +157,34 @@ func LoadProviderMetadataForDomain(
|
||||||
|
|
||||||
if logging == nil {
|
if logging == nil {
|
||||||
logging = func(format string, args ...interface{}) {
|
logging = func(format string, args ...interface{}) {
|
||||||
log.Printf("FindProviderMetadata: "+format+"\n", args...)
|
log.Printf("LoadProviderMetadataForDomain: "+format+"\n", args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As many URLs may lead to the same content only log once per content.
|
||||||
|
alreadyLogged := map[*LoadedProviderMetadata]string{}
|
||||||
|
|
||||||
lg := func(result *LoadedProviderMetadata, url string) {
|
lg := func(result *LoadedProviderMetadata, url string) {
|
||||||
if result == nil {
|
if result == nil {
|
||||||
logging("%s not found.", url)
|
logging("%q not found.", url)
|
||||||
} else {
|
return
|
||||||
|
}
|
||||||
|
if other := alreadyLogged[result]; other != "" {
|
||||||
|
logging("%q is same %q.", url, other)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
alreadyLogged[result] = url
|
||||||
for _, msg := range result.Messages {
|
for _, msg := range result.Messages {
|
||||||
logging(msg)
|
logging(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// keey track of already loaded pmds.
|
||||||
|
already := map[string]*LoadedProviderMetadata{}
|
||||||
|
|
||||||
// check direct path
|
// check direct path
|
||||||
if strings.HasPrefix(domain, "https://") {
|
if strings.HasPrefix(domain, "https://") {
|
||||||
result := LoadProviderMetadataFromURL(client, domain)
|
result := LoadProviderMetadataFromURL(client, domain, already)
|
||||||
lg(result, domain)
|
lg(result, domain)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +194,7 @@ func LoadProviderMetadataForDomain(
|
||||||
|
|
||||||
// First try well-know path
|
// First try well-know path
|
||||||
wellknownURL := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
|
wellknownURL := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
|
||||||
wellknownResult := LoadProviderMetadataFromURL(client, wellknownURL)
|
wellknownResult := LoadProviderMetadataFromURL(client, wellknownURL, already)
|
||||||
lg(wellknownResult, wellknownURL)
|
lg(wellknownResult, wellknownURL)
|
||||||
|
|
||||||
// We have a candidate.
|
// We have a candidate.
|
||||||
|
|
@ -165,7 +204,7 @@ func LoadProviderMetadataForDomain(
|
||||||
|
|
||||||
// Next load the PMDs from security.txt
|
// Next load the PMDs from security.txt
|
||||||
secURL := "https://" + domain + "/.well-known/security.txt"
|
secURL := "https://" + domain + "/.well-known/security.txt"
|
||||||
secResults := LoadProviderMetadatasFromSecurity(client, secURL)
|
secResults := LoadProviderMetadatasFromSecurity(client, secURL, already)
|
||||||
|
|
||||||
if secResults == nil {
|
if secResults == nil {
|
||||||
logging("%s failed to load.", secURL)
|
logging("%s failed to load.", secURL)
|
||||||
|
|
@ -175,9 +214,7 @@ func LoadProviderMetadataForDomain(
|
||||||
|
|
||||||
for _, result := range secResults {
|
for _, result := range secResults {
|
||||||
if len(result.Messages) > 0 {
|
if len(result.Messages) > 0 {
|
||||||
for _, msg := range result.Messages {
|
lg(result, result.URL)
|
||||||
logging(msg)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
secGoods = append(secGoods, result)
|
secGoods = append(secGoods, result)
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +259,7 @@ func LoadProviderMetadataForDomain(
|
||||||
|
|
||||||
// Last resort: fall back to DNS.
|
// Last resort: fall back to DNS.
|
||||||
dnsURL := "https://csaf.data.security." + domain
|
dnsURL := "https://csaf.data.security." + domain
|
||||||
dnsResult := LoadProviderMetadataFromURL(client, dnsURL)
|
dnsResult := LoadProviderMetadataFromURL(client, dnsURL, already)
|
||||||
lg(dnsResult, dnsURL)
|
lg(dnsResult, dnsURL)
|
||||||
return dnsResult
|
return dnsResult
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue