Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors for lookup checks #613

Merged
merged 3 commits into from
Feb 7, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 47 additions & 55 deletions cmd/csaf_checker/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1339,50 +1339,56 @@ func (p *processor) checkSecurityFolder(folder string) string {

// checkDNS checks if the "csaf.data.security.domain.tld" DNS record is available
// and serves the "provider-metadata.json".
// It returns an empty string if all checks are passed, otherwise the errormessage.
func (p *processor) checkDNS(domain string) string {
func (p *processor) checkDNS(domain string) {

p.badDNSPath.use()

client := p.httpClient()
path := "https://csaf.data.security." + domain
res, err := client.Get(path)
if err != nil {
return fmt.Sprintf("Fetching %s failed: %v", path, err)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("Fetching %s failed: %v", path, err))
return
}
if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status)

p.badDNSPath.add(ErrorType,
fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status))
}
hash := sha256.New()
defer res.Body.Close()
content, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Sprintf("Error while reading the response from %s", path)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("Error while reading the response from %s", path))
}
hash.Write(content)
if !bytes.Equal(hash.Sum(nil), p.pmd256) {
return fmt.Sprintf("%s does not serve the same provider-metadata.json as previously found", path)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("%s does not serve the same provider-metadata.json as previously found",
path))
}
return ""
}

// checkWellknownMetadataReporter checks if the provider-metadata.json file is
// available under the /.well-known/csaf/ directory. Returns the errormessage if
// an error was encountered, or an empty string otherwise
func (p *processor) checkWellknown(domain string) string {
// checkWellknown checks if the provider-metadata.json file is
// available under the /.well-known/csaf/ directory.
func (p *processor) checkWellknown(domain string) {

p.badWellknownMetadata.use()

client := p.httpClient()
path := "https://" + domain + "/.well-known/csaf/provider-metadata.json"

res, err := client.Get(path)
if err != nil {
return fmt.Sprintf("Fetching %s failed: %v", path, err)
p.badWellknownMetadata.add(ErrorType,
fmt.Sprintf("Fetching %s failed: %v", path, err))
}
if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status)
p.badWellknownMetadata.add(ErrorType, fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status))
}
return ""
}

// checkWellknownSecurityDNS
Expand All @@ -1394,57 +1400,43 @@ func (p *processor) checkWellknown(domain string) string {
// 4. Finally it checks if the "csaf.data.security.domain.tld" DNS record
// is available and serves the "provider-metadata.json".
//
// /
// If all three checks fail, errors are given,
// otherwise warnings for all failed checks.
// The function returns nil, unless errors outside the checks were found.
// In that case, errors are returned.
// For the security.txt checks, it first checks the default location.
// Should this lookup fail, a warning is will be given and a lookup
// for the legacy location will be made. If this fails as well, then an
// error is given.
func (p *processor) checkWellknownSecurityDNS(domain string) error {

warningsW := p.checkWellknown(domain)
p.checkWellknown(domain)

// Security check for well known (default) and legacy location
warningsS, sDMessage := p.checkSecurity(domain, false)
warnings, sDMessage := p.checkSecurity(domain, false)
// if the security.txt under .well-known was not okay
// check for a security.txt within its legacy location
sLMessage := ""
if warningsS == 1 {
warningsS, sLMessage = p.checkSecurity(domain, true)
if warnings == 1 {
warnings, sLMessage = p.checkSecurity(domain, true)
}
warningsD := p.checkDNS(domain)

p.badWellknownMetadata.use()
p.badSecurity.use()
p.badDNSPath.use()

var kind MessageType
if warningsS != 1 || warningsD == "" || warningsW == "" {
kind = WarnType
} else {
kind = ErrorType
// Report about Securitytxt:
// Only report about default location if it was succesful (0).
// Report default and legacy as errors if neither was succesful (1).
// Warn about missing security in the default position if not found
// but found in the legacy location, and inform about finding it there (2).
switch warnings {
case 0:
p.badSecurity.add(InfoType, sDMessage)
case 1:
p.badSecurity.add(ErrorType, sDMessage)
p.badSecurity.add(ErrorType, sLMessage)
case 2:
p.badSecurity.add(WarnType, sDMessage)
p.badSecurity.add(InfoType, sLMessage)
}

// Info, Warning or Error depending on kind and warningS
kindSD := kind
if warningsS == 0 {
kindSD = InfoType
}
kindSL := kind
if warningsS == 2 {
kindSL = InfoType
}
p.checkDNS(domain)

if warningsW != "" {
p.badWellknownMetadata.add(kind, warningsW)
}
p.badSecurity.add(kindSD, sDMessage)
// only if the well-known security.txt was not successful:
// report about the legacy location
if warningsS != 0 {
p.badSecurity.add(kindSL, sLMessage)
}
if warningsD != "" {
p.badDNSPath.add(kind, warningsD)
}
return nil
}

Expand Down
Loading